The worst ever s2sb implementation in human history but at least it works. Why are the buffers set to the same place

This commit is contained in:
starfrost013
2025-04-06 02:53:02 +01:00
parent 0bf5b5ea74
commit c05098e9ea
4 changed files with 52 additions and 15 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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];
}