diff --git a/src/video/nv/nv3/classes/nv3_class_010_blit.c b/src/video/nv/nv3/classes/nv3_class_010_blit.c index 57184054d..7b752243f 100644 --- a/src/video/nv/nv3/classes/nv3_class_010_blit.c +++ b/src/video/nv/nv3/classes/nv3_class_010_blit.c @@ -47,7 +47,7 @@ void nv3_class_010_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ /* This is the last one*/ nv3->pgraph.blit.size.w = (param & 0xFFFF); nv3->pgraph.blit.size.h = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: S2SB Size %04x,%04x\n", nv3->pgraph.blit.point_in.x, nv3->pgraph.blit.point_in.y); + nv_log("Method Execution: S2SB Size %04x,%04x grobj_0=0x%08x\n", nv3->pgraph.blit.point_in.x, nv3->pgraph.blit.point_in.y, grobj.grobj_0); /* Some blits have (point_in == point_out) ???? */ if (nv3->pgraph.blit.point_in.x == nv3->pgraph.blit.point_out.x diff --git a/src/video/nv/nv3/classes/nv3_class_011_image.c b/src/video/nv/nv3/classes/nv3_class_011_image.c index c1d1200b9..bd5dfa6d3 100644 --- a/src/video/nv/nv3/classes/nv3_class_011_image.c +++ b/src/video/nv/nv3/classes/nv3_class_011_image.c @@ -28,8 +28,6 @@ #include <86box/nv/vid_nv.h> #include <86box/nv/vid_nv3.h> - - void nv3_class_011_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) { switch (method_id) @@ -55,7 +53,7 @@ void nv3_class_011_method(uint32_t param, uint32_t method_id, nv3_ramin_context_ if (method_id >= NV3_IMAGE_COLOR_START && method_id <= NV3_IMAGE_COLOR_END) { uint32_t pixel_slot = (method_id - NV3_IMAGE_COLOR_START) >> 2; - nv_log("Method Execution: Pixel%d Colour%08x Format%x\n", pixel_slot, param, (grobj.grobj_0) & 0x07); + nv_log("Method Execution: Image Pixel%d Colour%08x Format%x\n", pixel_slot, param, (grobj.grobj_0) & 0x07); nv3_render_blit_image(param, grobj); } else diff --git a/src/video/nv/nv3/render/nv3_render_blit.c b/src/video/nv/nv3/render/nv3_render_blit.c index 3059aeccd..46556f928 100644 --- a/src/video/nv/nv3/render/nv3_render_blit.c +++ b/src/video/nv/nv3/render/nv3_render_blit.c @@ -108,27 +108,47 @@ void nv3_render_blit_image(uint32_t color, nv3_grobj_t grobj) break; } - } + +#define NV3_MAX_HORIZONTAL_SIZE 1920 +#define NV3_MAX_VERTICAL_SIZE 1200 + +/* 1920 for margin. Holds a buffer of the old screen we want to hold so we don't overwrite things we already overwtote +We only need to clear it once per blit, because the blits are always the same size, and then only for the size of our new blit + +Extremely not crazy about this...Surely a better way to do it without buffering the ENTIRE SCREEN. I only update the parts that are needed, but still... + +This is LUDICROUSLY INEFFICIENT (2*O(n^2)) and COMPLETELY TERRIBLE code, but it's currently 2:48am so I can't think of a better approach... +*/ +uint32_t nv3_s2sb_line_buffer[NV3_MAX_HORIZONTAL_SIZE*NV3_MAX_VERTICAL_SIZE] = {0}; + void nv3_render_blit_screen2screen(nv3_grobj_t grobj) { + if (nv3->pgraph.blit.size.w < NV3_MAX_HORIZONTAL_SIZE + && nv3->pgraph.blit.size.h < NV3_MAX_VERTICAL_SIZE) + memset(&nv3_s2sb_line_buffer, 0x00, (sizeof(uint32_t) * nv3->pgraph.blit.size.h) * (sizeof(uint32_t) * nv3->pgraph.blit.size.w)); + nv3_position_16_t old_position = nv3->pgraph.blit.point_in; nv3_position_16_t new_position = nv3->pgraph.blit.point_out; - uint16_t end_x = (nv3->pgraph.blit.point_out.x + nv3->pgraph.blit.size.w); + uint16_t end_x_in = (nv3->pgraph.blit.point_in.x + nv3->pgraph.blit.size.w); /* needed for bounds checking */ + uint16_t end_x_out = (nv3->pgraph.blit.point_out.x + nv3->pgraph.blit.size.w); uint16_t end_y = (nv3->pgraph.blit.point_out.y + nv3->pgraph.blit.size.h); uint32_t pixel_to_copy = 0x00; - /* Read the old pixel and rewrite it to the new position */ - for (int32_t y = nv3->pgraph.blit.point_out.y; y <= end_y; y++) - { - old_position.y = new_position.y = y; + /* Prevents overwriting pixels we've already modified*/ + uint32_t xdiff = 0, ydiff = 0; - for (int32_t x = nv3->pgraph.blit.point_out.x; x <= end_x; x++) + /* Read the old pixel into the line buffer */ + for (int32_t y = 0; y < nv3->pgraph.blit.size.h; y++) + { + old_position.y = nv3->pgraph.blit.point_in.y + y; + + for (int32_t x = 0; x < nv3->pgraph.blit.size.w; x++) { - old_position.x = new_position.x = x; + old_position.x = nv3->pgraph.blit.point_in.x + x; switch (nv3->nvbase.svga.bpp) { @@ -143,7 +163,26 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj) break; } - nv3_render_write_pixel(new_position, pixel_to_copy, grobj); + uint32_t buf_position = (y * nv3->pgraph.blit.size.w) + x; + nv3_s2sb_line_buffer[buf_position] = pixel_to_copy; } - } + + + } + /* simply write it all back to vram */ + for (int32_t y = 0; y < nv3->pgraph.blit.size.h; y++) + { + new_position.y = nv3->pgraph.blit.point_out.y + y; + + for (int32_t x = 0; x < nv3->pgraph.blit.size.w; x++) + { + new_position.x = nv3->pgraph.blit.point_out.x + x; + + uint32_t buf_position = (y * nv3->pgraph.blit.size.w) + x; + + nv3_render_write_pixel(new_position, nv3_s2sb_line_buffer[buf_position], grobj); + } + } + + } \ No newline at end of file diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index 9781259ad..e9ebeb013 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -289,7 +289,7 @@ uint32_t nv3_render_read_pixel_32(nv3_position_16_t position, nv3_grobj_t grobj, uint32_t vram_address = nv3_render_get_vram_address(position, grobj, use_destination); uint32_t* vram_32 = (uint32_t*)(nv3->nvbase.svga.vram); - vram_address >>= 1; //convert to 16bit pointer + vram_address >>= 2; //convert to 32bit pointer return vram_32[vram_address]; }