From 8d4096fffc34e971f249b38011cd4ef6b14ce6c5 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sat, 22 Mar 2025 15:37:14 +0000 Subject: [PATCH] Fix the colours. Wtf is wrong with NVidia? --- src/include/86box/nv/render/vid_nv3_render.h | 1 + src/include/86box/nv/vid_nv3.h | 1 + src/video/nv/nv3/nv3_core.c | 22 ++++++++++++++----- src/video/nv/nv3/render/nv3_render_core.c | 21 +++++++++++++----- src/video/nv/nv3/subsystems/nv3_pramdac.c | 1 + .../nv/nv3/subsystems/nv3_pramin_ramro.c | 4 ++-- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h index 50e41c17e..8481213ac 100644 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ b/src/include/86box/nv/render/vid_nv3_render.h @@ -24,4 +24,5 @@ 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); + void nv3_render_chroma_test(nv3_grobj_t grobj); \ No newline at end of file diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index e966f79b6..640a0c951 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -699,6 +699,7 @@ extern const device_config_t nv3_config[]; #define NV3_PRAMDAC_COEFF_SELECT 0x68050C #define NV3_PRAMDAC_GENERAL_CONTROL 0x680600 +#define NV3_PRAMDAC_GENERAL_CONTROL_565_MODE 12 // These are all 10-bit values, but aligned to 32bits // so treating them as 32bit should be fine diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c index 3f9fb0274..b1d96f8d9 100644 --- a/src/video/nv/nv3/nv3_core.c +++ b/src/video/nv/nv3/nv3_core.c @@ -481,8 +481,10 @@ void nv3_recalc_timings(svga_t* svga) nv3_t* nv3 = (nv3_t*)svga->priv; + svga->ma_latch += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0x1F) << 16; - svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 3; + + svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 2; // should these actually use separate values? // i don't we should force the top 2 bits to 1... @@ -495,7 +497,6 @@ void nv3_recalc_timings(svga_t* svga) if (svga->crtc[NV3_CRTC_REGISTER_PIXELMODE] & 1 << (NV3_CRTC_REGISTER_FORMAT_VBS10)) svga->vsyncstart += 0x400; if (svga->crtc[NV3_CRTC_REGISTER_PIXELMODE] & 1 << (NV3_CRTC_REGISTER_FORMAT_HBE6)) svga->hdisp += 0x400; - if (svga->crtc[NV3_CRTC_REGISTER_HEB] & 0x01) svga->hdisp += 0x100; // large screen bit @@ -509,9 +510,20 @@ void nv3_recalc_timings(svga_t* svga) svga->render = svga_render_8bpp_highres; break; case NV3_CRTC_REGISTER_PIXELMODE_16BPP: - svga->bpp = 16; - svga->lowres = 0; - svga->render = svga_render_16bpp_highres; + /* sometimes it really renders in 15bpp, so you need to do this */ + if ((nv3->pramdac.general_control >> NV3_PRAMDAC_GENERAL_CONTROL_565_MODE) & 0x01) + { + svga->bpp = 16; + svga->lowres = 0; + svga->render = svga_render_16bpp_highres; + } + else + { + svga->bpp = 16; // HACK: DO NOT change this + svga->lowres = 0; + svga->render = svga_render_15bpp_highres; + } + break; case NV3_CRTC_REGISTER_PIXELMODE_32BPP: svga->bpp = 32; diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index 7b9b3e303..8ccca2e6f 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -23,6 +23,7 @@ #include <86box/device.h> #include <86box/mem.h> #include <86box/pci.h> +#include <86box/plat.h> #include <86box/rom.h> #include <86box/video.h> #include <86box/nv/vid_nv.h> @@ -175,6 +176,8 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr #ifdef DEBUG uint8_t color_format_object = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_COLOR_FORMAT) & 0x07; #endif + bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_ALPHA) & 0x01; + uint32_t framebuffer_bpp = nv3->nvbase.svga.bpp; // maybe y16 too? uint32_t current_buffer = (nv3->pgraph.context_switch >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03; @@ -235,7 +238,7 @@ 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] = (int8_t)video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00) & 0xFF; nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount; @@ -244,9 +247,18 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr uint16_t* vram_16 = (uint16_t*)(nv3->nvbase.svga.vram); pixel_addr_vram >>= 1; - src = color & 0xFFFF; + // mask off the alpha bit. Even though the drivers should send this. What! + if (!alpha_enabled) + src = ((color & (~0x8000)) & 0xFFFF); + else + src = color & 0xFFFF; + + // convert to 16bpp + // forcing it to render in 15bpp fixes it, + + dst = vram_16[pixel_addr_vram]; - vram_16[pixel_addr_vram] = (int16_t)video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00); + vram_16[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, src, dst, 0x00) & 0xFFFF; nv3->nvbase.svga.changedvram[pixel_addr_vram >> 11] = changeframecount; @@ -263,7 +275,4 @@ void nv3_render_pixel(nv3_position_16_t position, uint32_t color, nv3_grobj_t gr break; } - - } - diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c index b887b83f9..c640d5f10 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ b/src/video/nv/nv3/subsystems/nv3_pramdac.c @@ -328,6 +328,7 @@ void nv3_pramdac_write(uint32_t address, uint32_t value) break; case NV3_PRAMDAC_GENERAL_CONTROL: nv3->pramdac.general_control = value; + nv3_recalc_timings(&nv3->nvbase.svga); break; case NV3_PRAMDAC_VSERR_WIDTH: //vslines? diff --git a/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c b/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c index d421b28dd..1209faa2f 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c @@ -30,12 +30,12 @@ uint32_t nv3_ramro_read(uint32_t address) { - nv_log("RAM Runout (invalid dma object submission) Read (0x%04x), I DON'T BELIEVE THIS SHOULD EVER HAPPEN\n", address); + nv_log("RAM Runout (invalid dma object submission) Read (0x%04x), Probably shouldn't happenn\n", address); } void nv3_ramro_write(uint32_t address, uint32_t value) { - nv_log("RAM Runout WRITE, OH CRAP!!!! (0x%04x -> 0x%04x), I DON'T BELIEVE THIS SHOULD EVER HAPPEN\n", value, address); + nv_log("RAM Runout WRITE, OH CRAP!!!! (0x%04x -> 0x%04x), Probably shouldn't happenn", value, address); } void nv3_ramro_send()