diff --git a/doc/nvidia_notes/status.xlsx b/doc/nvidia_notes/status.xlsx index a301eba64..4118b2c56 100644 Binary files a/doc/nvidia_notes/status.xlsx and b/doc/nvidia_notes/status.xlsx differ diff --git a/src/include/86box/nv/classes/vid_nv3_classes.h b/src/include/86box/nv/classes/vid_nv3_classes.h index 80e2c1437..83d378031 100644 --- a/src/include/86box/nv/classes/vid_nv3_classes.h +++ b/src/include/86box/nv/classes/vid_nv3_classes.h @@ -77,15 +77,34 @@ typedef enum nv3_pgraph_class_e #define NV3_SET_NOTIFY_CONTEXT_FOR_DMA 0x0100 // Set object ctx for dma...see nv3_dma_context_t structure #define NV3_SET_NOTIFY 0x0104 +// Render OPeration #define NV3_ROP_SET_ROP 0x0300 // Set GDI standard rop +// Beta Factor #define NV3_BETA_FACTOR 0x0300 +// Chroma Key #define NV3_CHROMA_KEY 0x0304 +// Clip #define NV3_CLIP_POSITION 0x0300 // S16:S16, 0=topleft #define NV3_CLIP_SIZE 0x0304 // U16:U16 +// Blit Pattern +#define NV3_PATTERN_FORMAT 0x0304 +#define NV3_PATTERN_SHAPE 0x0308 +#define NV3_PATTERN_SHAPE_8X8 0 +#define NV3_PATTERN_SHAPE_64X1 1 +#define NV3_PATTERN_SHAPE_1X64 2 +#define NV3_PATTERN_SHAPE_LAST_VALID NV3_PATTERN_SHAPE_1X64 + +#define NV3_PATTERN_COLOR0 0x0310 +#define NV3_PATTERN_COLOR1 0x0314 +#define NV3_PATTERN_BITMAP_HIGH 0x0318 +#define NV3_PATTERN_BITMAP_LOW 0x031C + +// Rect + #define NV3_RECTANGLE_COLOR 0x0304 // 16 possible rectangles. 8 byte structure, first 4 bytes = position, second 2 = size. @@ -173,44 +192,6 @@ typedef struct nv3_color_argb_s uint8_t b; } nv3_color_argb_t; -/* 30-bit colour format for internal PGRAPH use */ -typedef struct nv3_color_x2a10g10b10_s -{ - uint8_t reserved : 1; - bool a : 1; // 1-bit ALPHA if chroma key, OTHERWISE USELESS and IGNORE - uint16_t r : 10; - uint16_t g : 10; - uint16_t b : 10; -} nv3_color_x2a10g10b10_t; - -/* 16-bit A4R4G4B4 colour format */ -typedef struct nv3_color_16_a4r4g4b4_s -{ - uint8_t a : 4; - uint8_t r : 4; - uint8_t g : 4; - uint8_t b : 4; -} nv3_color_16_a4r4g4b4_t; - -/* A1R5G5B5 format - Can also be used for R5G5B5 -*/ -typedef struct nv3_color_16_a1r5g5b5_s -{ - uint8_t a : 1; - uint8_t r : 5; - uint8_t g : 5; - uint8_t b : 5; -} nv3_color_16_a1r5g5b5_t; - -/* 565 format - NV3Tweak */ -typedef struct nv3_color_16_r5g6b5_s -{ - uint8_t r : 5; - uint8_t g : 6; - uint8_t b : 5; -} nv3_color_16_r5g6b5_t; - /* Generic 16-bit position*/ typedef struct nv3_position_16_s { @@ -384,8 +365,8 @@ typedef struct nv3_object_class_006 uint8_t reserved2[0x200]; uint32_t shape; // 0 = 8x8, 1 = 64x1, 2 = 1x64 uint32_t color0; // Some 32-bit format (argb?) - uint32_t color1; // argb? - uint32_t pattern[2]; // argb? + uint32_t color1; // bit0=color0, bit1=color1 + uint32_t pattern[2]; // bit0=color0, bit1=color1 uint8_t reserved3[0x1CDF]; // needs to be 0x2000 bytes } nv3_pattern_t; diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h index 8481213ac..c5741f30c 100644 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ b/src/include/86box/nv/render/vid_nv3_render.h @@ -20,7 +20,11 @@ /* 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); +nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color); // Convert a colour to full RGB10 format from the current working format. +uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t color); // Convert a colour from the current working format to RGB10 format. + +/* Pattern */ +uint32_t nv3_render_set_pattern_color(nv3_color_expanded_t pattern_colour, bool use_color1); /* Primitives */ void nv3_render_rect(nv3_position_16_t position, nv3_size_16_t size, uint32_t color, nv3_grobj_t grobj); diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 29b2f70b9..ed8d9c4fc 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -569,10 +569,10 @@ extern const device_config_t nv3_config[]; #define NV3_PGRAPH_SRC_CANVAS_MAX 0x400554 // Maximum Source Canvas for Blit, Y=30:16, X=10:0 #define NV3_PGRAPH_DST_CANVAS_MIN 0x400558 // Minimum Destination Canvas for Blit, Y=30:16, X=10:0 #define NV3_PGRAPH_DST_CANVAS_MAX 0x40055C // Maximum Destination Canvas for Blit, Y=30:16, X=10:0 -#define NV3_PGRAPH_PATTERN_COLOR_0_0 0x400600 -#define NV3_PGRAPH_PATTERN_COLOR_0_1 0x400604 -#define NV3_PGRAPH_PATTERN_COLOR_1_0 0x400608 -#define NV3_PGRAPH_PATTERN_COLOR_1_1 0x40060C // pattern color +#define NV3_PGRAPH_pattern_color_0_rgb 0x400600 +#define NV3_PGRAPH_pattern_color_0_alpha 0x400604 +#define NV3_PGRAPH_pattern_color_1_rgb 0x400608 +#define NV3_PGRAPH_pattern_color_1_alpha 0x40060C // pattern color #define NV3_PGRAPH_PATTERN_BITMAP_HIGH 0x400610 // pattern bitmap [31:0] #define NV3_PGRAPH_PATTERN_BITMAP_LOW 0x400614 // pattern bitmap [63:32] #define NV3_PGRAPH_PATTERN_SHAPE 0x400618 @@ -1176,15 +1176,14 @@ typedef struct nv3_pgraph_s nv3_position_16_bigy_t dst_canvas_min; nv3_position_16_bigy_t dst_canvas_max; // Pattern stuff - nv3_color_x2a10g10b10_t pattern_color_0_0; - uint32_t pattern_color_0_1; // only 7:0 relevant - nv3_color_x2a10g10b10_t pattern_color_1_0; - uint32_t pattern_color_1_1; // only 7:0 relevant - uint32_t pattern_bitmap_high; // high part of pattern bitmap for blit - uint32_t pattern_bitmap_low; + nv3_color_expanded_t pattern_color_0_rgb; // ignore alpha + uint32_t pattern_color_0_alpha; // only 7:0 relevant + nv3_color_expanded_t pattern_color_1_rgb; // ignore alpha + uint32_t pattern_color_1_alpha; // only 7:0 relevant + uint64_t pattern_bitmap; // pattern bitmap for blit. it's alwaus 64 bits to simplify pixel rendering code uint32_t pattern_shape; // may need to be an enum - 0=8x8, 1=64x1, 2=1x64 uint32_t plane_mask; // only 7:0 relevant - nv3_color_x2a10g10b10_t chroma_key; // color key + uint32_t chroma_key; // color key uint32_t beta_factor; nv3_pgraph_dma_settings_t dma_settings; uint8_t rop; // Current GDI Ternary Render Operation diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 094b64440..43e7cf2a0 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -128,8 +128,7 @@ add_library(vid OBJECT nv/nv3/classes/nv3_class_01c_image_in_memory.c nv/nv3/render/nv3_render_core.c - nv/nv3/render/nv3_render_primitives.c - + nv/nv3/render/nv3_render_primitives.c ) if(G100) 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 f56a328dd..1450acbeb 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 @@ -43,6 +43,6 @@ void nv3_class_001_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ 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); - return; + break; } } \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_002_rop.c b/src/video/nv/nv3/classes/nv3_class_002_rop.c index 38fe29d78..1052da80d 100644 --- a/src/video/nv/nv3/classes/nv3_class_002_rop.c +++ b/src/video/nv/nv3/classes/nv3_class_002_rop.c @@ -38,6 +38,6 @@ void nv3_class_002_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ 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); - return; + break; } } \ No newline at end of file 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 a1364bd98..bf24f420f 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 @@ -34,13 +34,12 @@ void nv3_class_003_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ { 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; + + nv3->pgraph.chroma_key = nv3_render_to_chroma(expanded_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); - return; + break; } } \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_006_pattern.c b/src/video/nv/nv3/classes/nv3_class_006_pattern.c index 2c2174447..36ce70e19 100644 --- a/src/video/nv/nv3/classes/nv3_class_006_pattern.c +++ b/src/video/nv/nv3/classes/nv3_class_006_pattern.c @@ -32,9 +32,48 @@ void nv3_class_006_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ { switch (method_id) { + /* Valid software method, suppress logging */ + case NV3_PATTERN_FORMAT: + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); + break; + case NV3_PATTERN_SHAPE: + /* If the shape is not valid, tell the software that it's invalid */ + + /* + Technically you are meant to do this: + + But in practice, I don't know, because it always submits 0x20 or 0x40, which are valid when param & 0x03, + and appear to be deliberate behaviour in the drivers rather than bugs. What + if (param > NV3_PATTERN_SHAPE_LAST_VALID) + { + warning("NV3 class 0x06 (Pattern) invalid shape %d (This is a bug)", param); + nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_INVALID_DATA); + return; + } + + */ + nv3->pgraph.pattern_shape = param & 0x03; + + break; + case NV3_PATTERN_COLOR0: + nv3_color_expanded_t expanded_colour0 = nv3_render_expand_color(grobj, param); + nv3_render_set_pattern_color(expanded_colour0, false); + break; + case NV3_PATTERN_COLOR1: + nv3_color_expanded_t expanded_colour1 = nv3_render_expand_color(grobj, param); + nv3_render_set_pattern_color(expanded_colour1, true); + break; + case NV3_PATTERN_BITMAP_HIGH: + nv3->pgraph.pattern_bitmap = 0; //reset + nv3->pgraph.pattern_bitmap |= ((uint64_t)param << 32); + break; + case NV3_PATTERN_BITMAP_LOW: + nv3->pgraph.pattern_bitmap |= param; + + 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); - return; + break; } } \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c b/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c index 9ba86c0eb..a6cb52fbf 100644 --- a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c +++ b/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c @@ -85,6 +85,6 @@ void nv3_class_01c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ 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); - return; + break; } } \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_shared_methods.c b/src/video/nv/nv3/classes/nv3_class_shared_methods.c index 0bb12a2eb..9985845cf 100644 --- a/src/video/nv/nv3/classes/nv3_class_shared_methods.c +++ b/src/video/nv/nv3/classes/nv3_class_shared_methods.c @@ -35,7 +35,7 @@ void nv3_generic_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t { /* mthdCreate in software(?)*/ case NV3_ROOT_HI_IM_OBJECT_MCOBJECTYFACE: - nv_log("mthdCreate\n"); + nv_log("mthdCreate obj_name=0x%08x\n", param); nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); break; // set up the current notification request/object diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index 8ccca2e6f..741f8e422 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -57,14 +57,12 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) // 555 case nv3_pgraph_pixel_format_r5g5b5: - nv3_color_16_a1r5g5b5_t new_color = *(nv3_color_16_a1r5g5b5_t*)&color; // "stretch out" the colour - color_final.r = new_color.r * 0x20; - color_final.g = new_color.g * 0x20; - color_final.b = new_color.b * 0x20; - if (alpha_enabled) - color_final.a = new_color.a; + color_final.a = (color >> 15) & 0x01; // will be ignored if alpha_enabled isn't used + color_final.r = ((color >> 10) & 0x1F) << 5; + color_final.g = ((color >> 5) & 0x1F) << 5; + color_final.b = (color & 0x1F) << 5; break; // 888 (standard colour + 8-bit alpha) @@ -76,18 +74,12 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) color_final.g = ((color >> 8) & 0xFF) * 4; color_final.b = (color & 0xFF) * 4; - if (alpha_enabled) - color_final.a = new_color.a; break; case nv3_pgraph_pixel_format_r10g10b10: - nv3_color_x2a10g10b10_t new_color_rgb10 = *(nv3_color_x2a10g10b10_t*)&color; - - color_final.r = new_color_rgb10.r; - color_final.g = new_color_rgb10.g; - color_final.b = new_color_rgb10.b; - - if (alpha_enabled) - color_final.a = new_color.a; + color_final.a = (color << 31) & 0x01; + color_final.r = (color << 30) & 0x3FF; + color_final.g = (color << 20) & 0x1FF; + color_final.b = (color << 10); break; case nv3_pgraph_pixel_format_y8: @@ -115,7 +107,7 @@ nv3_color_expanded_t nv3_render_expand_color(nv3_grobj_t grobj, uint32_t color) } /* Used for chroma test */ -uint32_t nv3_render_downconvert(nv3_grobj_t grobj, nv3_color_expanded_t color) +uint32_t nv3_render_downconvert_color(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; @@ -129,18 +121,30 @@ uint32_t nv3_render_downconvert(nv3_grobj_t grobj, nv3_color_expanded_t color) switch (format) { case nv3_pgraph_pixel_format_r5g5b5: - packed_color = (color.r / 0x20) << 10 | - (color.g / 0x20) << 5 | - (color.b / 0x20); + packed_color = (color.r >> 5) << 10 | + (color.g >> 5) << 5 | + (color.b >> 5); break; case nv3_pgraph_pixel_format_r8g8b8: + packed_color = (color.a) << 24 | // is this a thing? + (color.r >> 2) << 16 | + (color.g >> 2) << 8 | + color.b; break; case nv3_pgraph_pixel_format_r10g10b10: + /* sometimes alpha isn't used but we should incorporate it anyway */ + if (color.a > 0x00) packed_color | (1 << 31); + + packed_color |= (color.r << 30); + packed_color |= (color.g << 20); + packed_color |= (color.b << 10); break; case nv3_pgraph_pixel_format_y8: + nv_log("nv3_render_downconvert: Y8 not implemented"); break; case nv3_pgraph_pixel_format_y16: + nv_log("nv3_render_downconvert: Y16 not implemented"); break; default: warning("nv3_render_downconvert_color unknown format %d", format); @@ -164,6 +168,37 @@ uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded) return !!expanded.a | (expanded.r << 30) | (expanded.b << 20) | (expanded.a << 10); } +/* Convert a rgb10 colour to a pattern colour */ +uint32_t nv3_render_set_pattern_color(nv3_color_expanded_t pattern_colour, bool use_color1) +{ + /* reset the colour */ + if (!use_color1) + nv3->pgraph.pattern_color_0_rgb.r = nv3->pgraph.pattern_color_0_rgb.g = nv3->pgraph.pattern_color_0_rgb.b = 0x00; + else + nv3->pgraph.pattern_color_1_rgb.r = nv3->pgraph.pattern_color_1_rgb.g = nv3->pgraph.pattern_color_1_rgb.b = 0x00; + + /* select the right pattern colour, _rgb is already in RGB10 format, so we don't need to do any conversion */ + + if (!use_color1) + { + nv3->pgraph.pattern_color_0_alpha = (pattern_colour.a) & 0xFF; + nv3->pgraph.pattern_color_0_rgb.r = pattern_colour.r; + nv3->pgraph.pattern_color_0_rgb.g = pattern_colour.g; + nv3->pgraph.pattern_color_0_rgb.b = pattern_colour.b; + + } + else + { + nv3->pgraph.pattern_color_1_alpha = (pattern_colour.a) & 0xFF; + nv3->pgraph.pattern_color_1_rgb.r = pattern_colour.r; + nv3->pgraph.pattern_color_1_rgb.g = pattern_colour.g; + nv3->pgraph.pattern_color_1_rgb.b = pattern_colour.b; + } + + + +} + /* Plots a pixel. */ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t grobj) { @@ -224,6 +259,46 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr pixel_addr_vram &= nv3->nvbase.svga.vram_mask; + uint32_t rop_src = 0, rop_dst = 0, rop_pattern = 0; + uint8_t bit = 0x00; + + /* Get our pattern data, may move to another function */ + switch (nv3->pgraph.pattern.shape) + { + + /* This logic is from NV1 envytoos docs, but seems to be same on NV3*/ + case NV3_PATTERN_SHAPE_8X8: + bit = (position.x & 7) | (position.y & 7) << 3; + break; + case NV3_PATTERN_SHAPE_1X64: + bit = (position.x & 0x3f); + break; + case NV3_PATTERN_SHAPE_64X1: + bit = (position.y & 0x3f); + break; + } + + // pull out the actual bit and see which colour we need to use + + bool use_color1 = (nv3->pgraph.pattern_bitmap >> bit) & 0x01; + + if (!use_color1) + { + if (!nv3->pgraph.pattern_color_0_alpha) + return; + + /* This is stupid */ + rop_pattern = nv3_render_downconvert_color(grobj, nv3->pgraph.pattern_color_0_rgb); + } + else + { + if (!nv3->pgraph.pattern_color_1_alpha) + return; + + rop_pattern = nv3_render_downconvert_color(grobj, nv3->pgraph.pattern_color_1_rgb); + } + + /* Go to vram and do the final ROP for a basic bitblit. It seems we can skip the downconversion step *for now*, since (framebuffer bits per pixel) == (object bits per pixel) I'm not sure how games will react. But it depends on how the D3D drivers operate, we may need ro convert texture formats to the current bpp internally. @@ -231,14 +306,12 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr TODO: MOVE TO BPIXEL DEPTH or GROBJ0 to determine this, once we figure out how to get the bpixel depth. */ - uint32_t src = 0, dst = 0; - switch (framebuffer_bpp) { 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) & 0xFF; + rop_src = color & 0xFF; + rop_dst = nv3->nvbase.svga.vram[pixel_addr_vram]; + nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern) & 0xFF; nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount; @@ -246,19 +319,28 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr case 16: uint16_t* vram_16 = (uint16_t*)(nv3->nvbase.svga.vram); pixel_addr_vram >>= 1; + + // mask to 16bit - // mask off the alpha bit. Even though the drivers should send this. What! - if (!alpha_enabled) - src = ((color & (~0x8000)) & 0xFFFF); - else - src = color & 0xFFFF; + rop_src = color & 0xFFFF; + + /* if alpha is turned on and we aren't in 565 mode, reject transparent pixels */ + bool is_16bpp = (nv3->pramdac.general_control >> NV3_PRAMDAC_GENERAL_CONTROL_565_MODE) & 0x01; + + // a1r5g5b5 + if (!is_16bpp) + { + if (alpha_enabled && + !(color & 0x8000)) + return; + } // convert to 16bpp // forcing it to render in 15bpp fixes it, - - dst = vram_16[pixel_addr_vram]; - vram_16[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00) & 0xFFFF; + rop_dst = vram_16[pixel_addr_vram]; + + vram_16[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern) & 0xFFFF; nv3->nvbase.svga.changedvram[pixel_addr_vram >> 11] = changeframecount; @@ -267,9 +349,9 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr uint32_t* vram_32 = (uint32_t*)(nv3->nvbase.svga.vram); pixel_addr_vram >>= 2; - src = color; - dst = vram_32[pixel_addr_vram]; - vram_32[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + rop_src = color; + rop_dst = vram_32[pixel_addr_vram]; + vram_32[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern); nv3->nvbase.svga.changedvram[pixel_addr_vram >> 10] = changeframecount; diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c index 993232c9d..70aef4270 100644 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ b/src/video/nv/nv3/subsystems/nv3_pgraph.c @@ -63,10 +63,10 @@ nv_register_t pgraph_registers[] = { { NV3_PGRAPH_SRC_CANVAS_MAX, "PGRAPH Source Canvas Maximum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, { NV3_PGRAPH_DST_CANVAS_MIN, "PGRAPH Destination Canvas Minimum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, { NV3_PGRAPH_DST_CANVAS_MAX, "PGRAPH Destination Canvas Maximum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, - { NV3_PGRAPH_PATTERN_COLOR_0_0, "PGRAPH Pattern Color 0_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_0_1, "PGRAPH Pattern Color 0_1 (Bits 7:0 = Alpha)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_1_0, "PGRAPH Pattern Color 1_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_1_1, "PGRAPH Pattern Color 1_1 (Bits 7:0 = Alpha)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_0_rgb, "PGRAPH Pattern Color 0_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_0_alpha, "PGRAPH Pattern Color 0_1 (Bits 7:0 = Alpha)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_1_rgb, "PGRAPH Pattern Color 1_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, + { NV3_PGRAPH_pattern_color_1_alpha, "PGRAPH Pattern Color 1_1 (Bits 7:0 = Alpha)", NULL, NULL, }, { NV3_PGRAPH_PATTERN_BITMAP_HIGH, "PGRAPH Pattern Bitmap (High 32bits)", NULL, NULL}, { NV3_PGRAPH_PATTERN_BITMAP_LOW, "PGRAPH Pattern Bitmap (Low 32bits)", NULL, NULL}, { NV3_PGRAPH_PATTERN_SHAPE, "PGRAPH Pattern Shape (1:0 - 0=8x8, 1=64x1, 2=1x64)", NULL, NULL}, @@ -185,23 +185,23 @@ uint32_t nv3_pgraph_read(uint32_t address) ret = *(uint32_t*)&nv3->pgraph.src_canvas_max; break; // Pattern - case NV3_PGRAPH_PATTERN_COLOR_0_0: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_0; + case NV3_PGRAPH_pattern_color_0_rgb: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_rgb; break; - case NV3_PGRAPH_PATTERN_COLOR_0_1: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_1; + case NV3_PGRAPH_pattern_color_0_alpha: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_alpha; break; - case NV3_PGRAPH_PATTERN_COLOR_1_0: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_0; + case NV3_PGRAPH_pattern_color_1_rgb: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_rgb; break; - case NV3_PGRAPH_PATTERN_COLOR_1_1: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_1; + case NV3_PGRAPH_pattern_color_1_alpha: + ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_alpha; break; case NV3_PGRAPH_PATTERN_BITMAP_HIGH: - ret = nv3->pgraph.pattern_bitmap_high; + ret = (nv3->pgraph.pattern_bitmap >> 32) & 0xFFFFFFFF; break; case NV3_PGRAPH_PATTERN_BITMAP_LOW: - ret = nv3->pgraph.pattern_bitmap_low; + ret = (nv3->pgraph.pattern_bitmap & 0xFFFFFFFF); break; // Beta factor case NV3_PGRAPH_BETA: @@ -388,23 +388,23 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) *(uint32_t*)&nv3->pgraph.src_canvas_max = value; break; // Pattern - case NV3_PGRAPH_PATTERN_COLOR_0_0: - *(uint32_t*)&nv3->pgraph.pattern_color_0_0 = value; + case NV3_PGRAPH_pattern_color_0_rgb: + *(uint32_t*)&nv3->pgraph.pattern_color_0_rgb = value; break; - case NV3_PGRAPH_PATTERN_COLOR_0_1: - *(uint32_t*)&nv3->pgraph.pattern_color_0_1 = value; + case NV3_PGRAPH_pattern_color_0_alpha: + *(uint32_t*)&nv3->pgraph.pattern_color_0_alpha = value; break; - case NV3_PGRAPH_PATTERN_COLOR_1_0: - *(uint32_t*)&nv3->pgraph.pattern_color_1_0 = value; + case NV3_PGRAPH_pattern_color_1_rgb: + *(uint32_t*)&nv3->pgraph.pattern_color_1_rgb = value; break; - case NV3_PGRAPH_PATTERN_COLOR_1_1: - *(uint32_t*)&nv3->pgraph.pattern_color_1_1 = value; + case NV3_PGRAPH_pattern_color_1_alpha: + *(uint32_t*)&nv3->pgraph.pattern_color_1_alpha = value; break; case NV3_PGRAPH_PATTERN_BITMAP_HIGH: - nv3->pgraph.pattern_bitmap_high = value; + nv3->pgraph.pattern_bitmap |= ((uint64_t)value << 32); break; case NV3_PGRAPH_PATTERN_BITMAP_LOW: - nv3->pgraph.pattern_bitmap_low = value; + nv3->pgraph.pattern_bitmap |= value; break; // Beta factor case NV3_PGRAPH_BETA: @@ -415,7 +415,7 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) nv3->pgraph.rop = value & 0xFF; break; case NV3_PGRAPH_CHROMA_KEY: - nv3->pgraph.chroma_key = *(nv3_color_x2a10g10b10_t*)value; + nv3->pgraph.chroma_key = value; break; case NV3_PGRAPH_PLANE_MASK: nv3->pgraph.plane_mask = value;