mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Implement Voodoo alpha planes and alpha mask support
Fallback to interpreter if alpha planes are used for now
This commit is contained in:
@@ -656,6 +656,7 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
|
||||
int block_pos = 0;
|
||||
int z_skip_pos = 0;
|
||||
int a_skip_pos = 0;
|
||||
int amask_skip_pos = 0;
|
||||
int chroma_skip_pos = 0;
|
||||
int depth_jump_pos = 0;
|
||||
int depth_jump_pos2 = 0;
|
||||
@@ -1732,6 +1733,15 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
|
||||
addbyte(0xdb);
|
||||
break;
|
||||
}
|
||||
if (params->fbzMode & FBZ_ALPHA_MASK) {
|
||||
addbyte(0xf7); /*TEST EBX, 1*/
|
||||
addbyte(0xc3);
|
||||
addlong(1);
|
||||
addbyte(0x0f); /* JZ amask_skip_pos */
|
||||
addbyte(0x84);
|
||||
amask_skip_pos = block_pos;
|
||||
addlong(0);
|
||||
}
|
||||
/*ECX = a_local*/
|
||||
switch (cca_localselect) {
|
||||
case CCA_LOCALSELECT_ITER_A:
|
||||
@@ -2986,6 +2996,8 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
|
||||
*(uint32_t *) &code_block[a_skip_pos] = (block_pos - a_skip_pos) - 4;
|
||||
if (chroma_skip_pos)
|
||||
*(uint32_t *) &code_block[chroma_skip_pos] = (block_pos - chroma_skip_pos) - 4;
|
||||
if (amask_skip_pos)
|
||||
*(uint32_t *) &code_block[amask_skip_pos] = (block_pos - amask_skip_pos) - 4;
|
||||
|
||||
addbyte(0x4c); /*MOV RSI, R15*/
|
||||
addbyte(0x89);
|
||||
@@ -3225,6 +3237,12 @@ voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *stat
|
||||
voodoo_x86_data_t *voodoo_x86_data = voodoo->codegen_data;
|
||||
voodoo_x86_data_t *data;
|
||||
|
||||
if (params->fbzMode & FBZ_ALPHA_ENABLE) {
|
||||
// Lands of Lore III relies on the alpha buffer functionality to create its transparent textures.
|
||||
// Fallback to interpreter.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
data = &voodoo_x86_data[odd_even + c * 4]; //&voodoo_x86_data[odd_even][b];
|
||||
|
||||
|
||||
@@ -366,11 +366,14 @@ enum {
|
||||
FBZ_DEPTH_WMASK = (1 << 10),
|
||||
FBZ_DITHER_2x2 = (1 << 11),
|
||||
|
||||
FBZ_ALPHA_MASK = (1 << 13),
|
||||
|
||||
FBZ_DRAW_FRONT = 0x0000,
|
||||
FBZ_DRAW_BACK = 0x4000,
|
||||
FBZ_DRAW_MASK = 0xc000,
|
||||
|
||||
FBZ_DEPTH_BIAS = (1 << 16),
|
||||
FBZ_ALPHA_ENABLE = (1 << 18),
|
||||
FBZ_DITHER_SUB = (1 << 19),
|
||||
|
||||
FBZ_DEPTH_SOURCE = (1 << 20),
|
||||
@@ -655,6 +658,8 @@ enum {
|
||||
|
||||
#define src_afunc ((params->alphaMode >> 8) & 0xf)
|
||||
#define dest_afunc ((params->alphaMode >> 12) & 0xf)
|
||||
#define src_aafunc ((params->alphaMode >> 16) & 0xf)
|
||||
#define dest_aafunc ((params->alphaMode >> 20) & 0xf)
|
||||
#define alpha_func ((params->alphaMode >> 1) & 7)
|
||||
#define a_ref (params->alphaMode >> 24)
|
||||
#define depth_op ((params->fbzMode >> 5) & 7)
|
||||
|
||||
@@ -932,7 +932,7 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
|
||||
state->x = x;
|
||||
state->x2 = x2;
|
||||
#ifndef NO_CODEGEN
|
||||
if (voodoo->use_recompiler) {
|
||||
if (voodoo->use_recompiler && voodoo_draw) {
|
||||
voodoo_draw(state, params, x, real_y);
|
||||
} else
|
||||
#endif
|
||||
@@ -1017,6 +1017,13 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
|
||||
dest_b |= (dest_b >> 5);
|
||||
dest_a = 0xff;
|
||||
|
||||
if (params->fbzMode & FBZ_ALPHA_ENABLE) {
|
||||
if (voodoo->params.aux_tiled)
|
||||
dest_a = aux_mem[x_tiled];
|
||||
else
|
||||
dest_a = aux_mem[x];
|
||||
}
|
||||
|
||||
if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) {
|
||||
if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) {
|
||||
/*TMU0 only sampling local colour or only one TMU, only sample TMU0*/
|
||||
@@ -1032,11 +1039,6 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
|
||||
} else {
|
||||
voodoo_tmu_fetch_and_blend(voodoo, params, state, x);
|
||||
}
|
||||
|
||||
if ((params->fbzMode & FBZ_CHROMAKEY) && state->tex_r[0] == params->chromaKey_r && state->tex_g[0] == params->chromaKey_g && state->tex_b[0] == params->chromaKey_b) {
|
||||
voodoo->fbiChromaFail++;
|
||||
goto skip_pixel;
|
||||
}
|
||||
}
|
||||
|
||||
if (voodoo->trexInit1[0] & (1 << 18)) {
|
||||
@@ -1088,6 +1090,11 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
|
||||
break;
|
||||
}
|
||||
|
||||
if ((params->fbzMode & FBZ_CHROMAKEY) && cother_r == params->chromaKey_r && cother_g == params->chromaKey_g && cother_b == params->chromaKey_b) {
|
||||
voodoo->fbiChromaFail++;
|
||||
goto skip_pixel;
|
||||
}
|
||||
|
||||
switch (cca_localselect) {
|
||||
case CCA_LOCALSELECT_ITER_A:
|
||||
alocal = CLAMP(state->ia >> 12);
|
||||
@@ -1123,6 +1130,10 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
|
||||
break;
|
||||
}
|
||||
|
||||
if ((params->fbzMode & FBZ_ALPHA_MASK) && !(aother & 1)) {
|
||||
goto skip_pixel;
|
||||
}
|
||||
|
||||
if (cc_zero_other) {
|
||||
src_r = 0;
|
||||
src_g = 0;
|
||||
@@ -1283,6 +1294,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
|
||||
dest_b = dithersub_rb2x2[dest_b][real_y & 1][x & 1];
|
||||
}
|
||||
ALPHA_BLEND(src_r, src_g, src_b, src_a);
|
||||
|
||||
// TODO: Implement proper alpha blending support here for alpha values.
|
||||
src_a = (((dest_aafunc == 4) ? dest_a * 256 : 0) + ((src_aafunc == 4) ? src_a * 256 : 0)) >> 8;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
@@ -1308,7 +1322,13 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
|
||||
else
|
||||
fb_mem[x] = src_b | (src_g << 5) | (src_r << 11);
|
||||
}
|
||||
if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) {
|
||||
if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_ALPHA_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_ALPHA_ENABLE)) {
|
||||
if (voodoo->params.aux_tiled)
|
||||
aux_mem[x_tiled] = src_a;
|
||||
else
|
||||
aux_mem[x] = src_a;
|
||||
}
|
||||
else if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) {
|
||||
if (voodoo->params.aux_tiled)
|
||||
aux_mem[x_tiled] = new_depth;
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user