diff --git a/doc/nvidia_notes/status.xlsx b/doc/nvidia_notes/status.xlsx index 7d58d5250..f36ba573a 100644 Binary files a/doc/nvidia_notes/status.xlsx and b/doc/nvidia_notes/status.xlsx differ diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h index 5f6d39ae2..fd76042d6 100644 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ b/src/include/86box/nv/render/vid_nv3_render.h @@ -37,4 +37,7 @@ void nv3_render_rect(nv3_position_16_t position, nv3_size_16_t size, uint32_t co bool nv3_render_chroma_test(nv3_grobj_t grobj, uint32_t color); /* Blit */ -void nv3_render_blit_screen2screen(nv3_grobj_t grobj); \ No newline at end of file +void nv3_render_blit_screen2screen(nv3_grobj_t grobj); + +/* GDI */ +void nv3_render_gdi_type_d(nv3_grobj_t grobj, uint32_t param); \ 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 d4ceb5cf4..78cc3953a 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -1228,6 +1228,7 @@ typedef struct nv3_pgraph_s struct nv3_object_class_00A lin; struct nv3_object_class_00B triangle; struct nv3_object_class_00C win95_gdi_text; + nv3_position_16_t win95_gdi_text_current_position; /* This is here so we can hold the current state of the image draw */ struct nv3_object_class_00D m2mf; struct nv3_object_class_00E scaled_image_from_memory; struct nv3_object_class_010 blit; diff --git a/src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c b/src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c index 9fbc92006..a834da989 100644 --- a/src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c +++ b/src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c @@ -38,8 +38,35 @@ void nv3_class_00c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ case NV3_W95TXT_A_COLOR: nv3->pgraph.win95_gdi_text.color_a = param; break; + /* Type B and C not implemented YET, as they are not used by NT GDI driver */ + case NV3_W95TXT_D_CLIP_TOPLEFT: + nv3->pgraph.win95_gdi_text.clip_d.left = (param & 0xFFFF); + nv3->pgraph.win95_gdi_text.clip_d.top = ((param >> 16) & 0xFFFF); + break; + case NV3_W95TXT_D_CLIP_BOTTOMRIGHT: + nv3->pgraph.win95_gdi_text.clip_d.right = (param & 0xFFFF); + nv3->pgraph.win95_gdi_text.clip_d.bottom = ((param >> 16) & 0xFFFF); + /* is it "only if we are out of the top left or the bottom right or is it "all of them"*/ + break; + case NV3_W95TXT_D_CLIP_COLOR: + nv3->pgraph.win95_gdi_text.color1_d = param; + break; + case NV3_W95TXT_D_CLIP_SIZE_IN: + nv3->pgraph.win95_gdi_text.size_in_d.w = (param & 0xFFFF); + nv3->pgraph.win95_gdi_text.size_in_d.h = ((param >> 16) & 0xFFFF); + break; + case NV3_W95TXT_D_CLIP_SIZE_OUT: + nv3->pgraph.win95_gdi_text.size_out_d.w = (param & 0xFFFF); + nv3->pgraph.win95_gdi_text.size_out_d.h = ((param >> 16) & 0xFFFF); + break; + case NV3_W95TXT_D_CLIP_POSITION: + nv3->pgraph.win95_gdi_text.point_d.x = (param & 0xFFFF); + nv3->pgraph.win95_gdi_text.point_d.y = ((param >> 16) & 0xFFFF); + + nv3->pgraph.win95_gdi_text_current_position = nv3->pgraph.win95_gdi_text.point_d; + break; default: - /* These are the same things as rectangles */ + /* Type A submission: these are the same things as rectangles */ if (method_id >= NV3_W95TXT_A_RECT_START && method_id <= NV3_W95TXT_A_RECT_END) { uint32_t index = (method_id - NV3_RECTANGLE_START) >> 3; @@ -66,6 +93,24 @@ void nv3_class_00c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ } return; } + else if (method_id >= NV3_W95TXT_D_CLIP_CLIPRECT_START && method_id <= NV3_W95TXT_D_CLIP_CLIPRECT_END) + { + /* lol */ + uint32_t index = (method_id - NV3_W95TXT_D_CLIP_CLIPRECT_START) >> 3; + + nv3->pgraph.win95_gdi_text.mono_color1_d[index] = param; + + /* Mammoth logger! */ + nv_log("Rect GDI-D%d Data=%08x SizeIn%04x,%04x SizeOut%04x,%04x Point%04x,%04x Color=%08x Clip Left=0x%04x Right=0x%04x Top=0x%04x Bottom=0x%04x", + index, param, nv3->pgraph.win95_gdi_text.size_in_d.w, nv3->pgraph.win95_gdi_text.size_in_d.h, + nv3->pgraph.win95_gdi_text.size_out_d.w, nv3->pgraph.win95_gdi_text.size_out_d.h, + nv3->pgraph.win95_gdi_text.point_d.x, nv3->pgraph.win95_gdi_text.point_d.y, + nv3->pgraph.win95_gdi_text.color1_d, + nv3->pgraph.win95_gdi_text.clip_d.left, nv3->pgraph.win95_gdi_text.clip_d.right, nv3->pgraph.win95_gdi_text.clip_d.top, nv3->pgraph.win95_gdi_text.clip_d.bottom); + + nv3_render_gdi_type_d(grobj, nv3->pgraph.win95_gdi_text.mono_color1_d[index]); + + } 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_primitives.c b/src/video/nv/nv3/render/nv3_render_primitives.c index f4bfdebf4..d8dfe7ba9 100644 --- a/src/video/nv/nv3/render/nv3_render_primitives.c +++ b/src/video/nv/nv3/render/nv3_render_primitives.c @@ -36,6 +36,7 @@ void nv3_render_rect(nv3_position_16_t position, nv3_size_16_t size, uint32_t co for (int32_t y = position.y; y < (position.y + size.h); y++) { current_pos.y = y; + for (int32_t x = position.x; x < (position.x + size.w); x++) { current_pos.x = x; @@ -43,4 +44,66 @@ void nv3_render_rect(nv3_position_16_t position, nv3_size_16_t size, uint32_t co nv3_render_write_pixel(current_pos, color, grobj); } } +} + +void nv3_render_gdi_type_d(nv3_grobj_t grobj, uint32_t param) +{ + // reset when a position is submitted + nv3_position_16_t start_position = nv3->pgraph.win95_gdi_text_current_position; + + // is this clip or point? + + uint16_t end_x = nv3->pgraph.win95_gdi_text.point_d.x + nv3->pgraph.win95_gdi_text.size_in_d.w; + uint16_t end_y = nv3->pgraph.win95_gdi_text.point_d.y + nv3->pgraph.win95_gdi_text.size_in_d.h; + + /* set up our packed pixels */ + uint32_t pixel0 = 0, pixel1 = 0, pixel2 = 0, pixel3 = 0; + + /* Go through the bitmap that was sent, bit by bit. */ + for (int32_t bit_num = 0; bit_num <= 31; bit_num++) + { + bool bit = (param >> bit_num) & 0x01; + //bool bit = true; // debug test + + nv3->pgraph.win95_gdi_text_current_position.x++; + + /* let's hope NV never overflow the y */ + if (nv3->pgraph.win95_gdi_text_current_position.x >= end_x) + { + nv3->pgraph.win95_gdi_text_current_position.x = nv3->pgraph.win95_gdi_text.point_d.x; + nv3->pgraph.win95_gdi_text_current_position.y++; + } + + /* check if we are in the clipping rectangle */ + if (nv3->pgraph.win95_gdi_text_current_position.x < nv3->pgraph.win95_gdi_text.clip_d.left + || nv3->pgraph.win95_gdi_text_current_position.x > nv3->pgraph.win95_gdi_text.clip_d.right + || nv3->pgraph.win95_gdi_text_current_position.y < nv3->pgraph.win95_gdi_text.clip_d.top + || nv3->pgraph.win95_gdi_text_current_position.y > nv3->pgraph.win95_gdi_text.clip_d.bottom) + { + return; + } + + // if it's 0 we don't need to do anything + if (!bit) + continue; + else + { + switch (nv3->nvbase.svga.bpp) + { + case 8: + uint32_t final_color8 = (nv3->pgraph.win95_gdi_text.color1_d & 0xFF); /* do we need to add anything? mul blend perhaps? */ + nv3_render_write_pixel(nv3->pgraph.win95_gdi_text_current_position, final_color8, grobj); + break; + case 16: + uint32_t final_color16 = (nv3->pgraph.win95_gdi_text.color1_d & 0xFFFF); /* do we need to add anything? mul blend perhaps? */ + nv3_render_write_pixel(nv3->pgraph.win95_gdi_text_current_position, final_color16, grobj); + break; + case 32: + uint32_t final_color32 = (nv3->pgraph.win95_gdi_text.color1_d); /* do we need to add anything? mul blend perhaps? */ + nv3_render_write_pixel(nv3->pgraph.win95_gdi_text_current_position, final_color32, grobj); + break; + } + } + + } } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c index 088ddf1ba..b782f2b56 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c @@ -939,9 +939,10 @@ void nv3_pfifo_cache1_pull() nv3_ramin_context_t context_structure = *(nv3_ramin_context_t*)¤t_context; nv3_debug_ramin_print_context_info(current_param, context_structure); + #endif nv3_pgraph_submit(current_param, current_method, current_channel, current_subchannel, class_id & 0x1F, context_structure); - #endif + //Todo: finish it } diff --git a/src/video/nv/nv3/subsystems/nv3_pramin.c b/src/video/nv/nv3/subsystems/nv3_pramin.c index 7a5ff749b..b4858acca 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin.c @@ -477,7 +477,7 @@ bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, u else { nv3->pfifo.cache1_settings.pull0 |= NV3_PFIFO_CACHE1_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_ENABLED; + nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_ENABLED; } // It's an error but it isn't lol @@ -504,7 +504,7 @@ void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t conte { #ifndef RELEASE_BUILD nv_log("Found object:\n"); - nv_log("Name: 0x%04x\n", name); + nv_log("Param: 0x%04x\n", name); nv_log("Context:\n"); nv_log("DMA Channel %d (0-7 valid)\n", context.channel);