diff --git a/src/include/86box/nv/classes/vid_nv3_classes.h b/src/include/86box/nv/classes/vid_nv3_classes.h index c5c014245..96df80eb1 100644 --- a/src/include/86box/nv/classes/vid_nv3_classes.h +++ b/src/include/86box/nv/classes/vid_nv3_classes.h @@ -81,6 +81,8 @@ typedef enum nv3_pgraph_class_e #define NV3_BETA_FACTOR 0x0300 +#define NV3_CHROMA_KEY 0x0304 + #define NV3_CLIP_POSITION 0x0300 // S16:S16, 0=topleft #define NV3_CLIP_SIZE 0x0304 // U16:U16 diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h index 58ecf9df5..50e41c17e 100644 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ b/src/include/86box/nv/render/vid_nv3_render.h @@ -19,6 +19,9 @@ /* Core */ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t grobj); +uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded); +nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color); /* Primitives */ -void nv3_render_rect(nv3_position_16_t position, nv3_size_16_t size, uint32_t color, nv3_grobj_t grobj); \ No newline at end of file +void nv3_render_rect(nv3_position_16_t position, nv3_size_16_t size, uint32_t color, nv3_grobj_t grobj); +void nv3_render_chroma_test(nv3_grobj_t grobj); \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_001_beta_factor.c b/src/video/nv/nv3/classes/nv3_class_001_beta_factor.c index 784da2eb0..f56a328dd 100644 --- a/src/video/nv/nv3/classes/nv3_class_001_beta_factor.c +++ b/src/video/nv/nv3/classes/nv3_class_001_beta_factor.c @@ -32,6 +32,14 @@ void nv3_class_001_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ { switch (method_id) { + /* even if we don't do anything with this yet... */ + case NV3_BETA_FACTOR: + if (param & 0x80000000) /* bit0 */ + nv3->pgraph.beta_factor = 0; + else + nv3->pgraph.beta_factor = param & 0x7F800000; + + break; default: nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); diff --git a/src/video/nv/nv3/classes/nv3_class_003_chroma_key.c b/src/video/nv/nv3/classes/nv3_class_003_chroma_key.c index 92a3cb225..a1364bd98 100644 --- a/src/video/nv/nv3/classes/nv3_class_003_chroma_key.c +++ b/src/video/nv/nv3/classes/nv3_class_003_chroma_key.c @@ -32,6 +32,12 @@ void nv3_class_003_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ { switch (method_id) { + case NV3_CHROMA_KEY: + nv3_color_expanded_t expanded_color = nv3_render_expand_color(grobj, param); + + uint32_t color = nv3_render_to_chroma(expanded_color); + nv3->pgraph.chroma_key = *(nv3_color_x2a10g10b10_t*)&color; + break; default: nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index aebfb6466..8d7bdd189 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -29,12 +29,6 @@ #include <86box/nv/vid_nv3.h> #include <86box/utils/video_stdlib.h> -/* Render Core: Performs a ROP */ -uint32_t nv3_perform_rop(uint32_t src, uint32_t dst, uint32_t pattern, nv3_render_operation_type rop) -{ - return video_rop_gdi_ternary(rop, dst, pattern, src); -} - /* Expand a colour. NOTE: THE GPU INTERNALLY OPERATES ON RGB10!!!!!!!!!!! */ @@ -108,6 +102,8 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) color_final.r = color_final.g = color_final.b = (color & 0xFFFF) * 4; // convert to rgb10 break; default: + warning("nv3_render_expand_color unknown format %d", format); + break; } @@ -117,6 +113,39 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) return color_final; } +/* Used for chroma test */ +uint32_t nv3_render_downconvert(nv3_grobj_t grobj, nv3_color_expanded_t color) +{ + uint8_t format = (grobj.grobj_0 & 0x07); + bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_ALPHA) & 0x01; + + #ifdef ENABLE_NV_LOG + nv_log("Downconverting Colour 0x%08x using pgraph_pixel_format 0x%x alpha enabled=%d", color, format, alpha_enabled); + #endif + + uint32_t packed_color = 0x00; + + switch (format) + { + case nv3_pgraph_pixel_format_r5g5b5: + break; + case nv3_pgraph_pixel_format_r8g8b8: + break; + case nv3_pgraph_pixel_format_r10g10b10: + break; + case nv3_pgraph_pixel_format_y8: + break; + case nv3_pgraph_pixel_format_y16: + break; + default: + warning("nv3_render_downconvert_color unknown format %d", format); + break; + + } + + return packed_color; +} + /* Convert expanded colour format to chroma key format */ uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded) { @@ -162,7 +191,23 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr /* TODO: Chroma Key, Pattern, Plane Mask...*/ /* Combine the current buffer with the pitch to get the address in the framebuffer to draw from. */ - uint32_t pixel_addr_vram = position.x + (nv3->pgraph.bpitch[current_buffer]) * position.y + nv3->pgraph.boffset[current_buffer]; + + uint32_t vram_x = position.x; + + // we have to multiply the x position by the number of bytes per pixel + switch (framebuffer_bpp) + { + case 8: + break; + case 16: + vram_x = position.x * 2; + break; + case 32: + vram_x = position.x * 4; + break; + } + + uint32_t pixel_addr_vram = vram_x + (nv3->pgraph.bpitch[current_buffer] * position.y) + nv3->pgraph.boffset[current_buffer]; pixel_addr_vram &= nv3->nvbase.svga.vram_mask; @@ -180,7 +225,9 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr case 8: src = color & 0xFF; dst = nv3->nvbase.svga.vram[pixel_addr_vram]; - nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + nv3->nvbase.svga.vram[pixel_addr_vram] = (int8_t)video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + + nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount; break; case 16: @@ -189,7 +236,9 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr src = color & 0xFFFF; dst = vram_16[pixel_addr_vram]; - nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + vram_16[pixel_addr_vram] = (int16_t)video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + + nv3->nvbase.svga.changedvram[pixel_addr_vram >> 11] = changeframecount; break; case 32: @@ -198,11 +247,13 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr src = color; dst = vram_32[pixel_addr_vram]; - nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + vram_32[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + + nv3->nvbase.svga.changedvram[pixel_addr_vram >> 10] = changeframecount; break; } - nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount; -} \ No newline at end of file +} +