NV_IMAGE_FROM_CPU implemented, leading to the mouse cursor being drawn, and the windows start menu

This commit is contained in:
starfrost013
2025-03-23 01:24:42 +00:00
parent 8d4096fffc
commit 493020ca51
5 changed files with 109 additions and 5 deletions

Binary file not shown.

View File

@@ -92,7 +92,15 @@ typedef enum nv3_pgraph_class_e
#define NV3_RECTANGLE_START 0x0400
#define NV3_RECTANGLE_MAX 16
#define NV3_RECTNAGLE_END 0x0480
#define NV3_RECTANGLE_END 0x0480
// image_from_cpu
#define NV3_IMAGE_START_POSITION 0x0304 // starting position of image from cpu
#define NV3_IMAGE_SIZE 0x0308
#define NV3_IMAGE_SIZE_IN 0x030C
#define NV3_IMAGE_COLOR_START 0x0400
#define NV3_IMAGE_COLOR_MAX 32
#define NV3_IMAGE_COLOR_END 0x0480
#define NV3_IMAGE_IN_MEMORY_COLOR_FORMAT 0x0300
#define NV3_IMAGE_IN_MEMORY_IN_MEMORY_DMA_CTX_TYPE 0x0304

View File

@@ -14,7 +14,7 @@
* Also check the doc folder for some more notres
*
* vid_nv3.h: NV3 Architecture Hardware Reference (open-source)
* Last updated: 20 March 2025 (STILL WORKING ON IT!!!)
* Last updated: 22 March 2025 (STILL WORKING ON IT!!!)
*
* Authors: Connor Hyde <mario64crashed@gmail.com>
*
@@ -1227,6 +1227,7 @@ typedef struct nv3_pgraph_s
struct nv3_object_class_00E scaled_image_from_memory;
struct nv3_object_class_010 blit;
struct nv3_object_class_011 image;
nv3_position_16_t image_current_position; /* This is here so we can hold the current state of the image */
struct nv3_object_class_012 bitmap;
struct nv3_object_class_014 transfer2memory;
struct nv3_object_class_015 stretched_image_from_cpu;

View File

@@ -37,7 +37,7 @@ void nv3_class_007_method(uint32_t param, uint32_t method_id, nv3_ramin_context_
break;
default:
/* Check for any rectangle point or size method. */
if (method_id >= NV3_RECTANGLE_START && method_id <= NV3_RECTNAGLE_END)
if (method_id >= NV3_RECTANGLE_START && method_id <= NV3_RECTANGLE_END)
{
uint32_t index = (method_id - NV3_RECTANGLE_START) / 8;

View File

@@ -28,13 +28,108 @@
#include <86box/nv/vid_nv.h>
#include <86box/nv/vid_nv3.h>
/* Check the line bounds */
void nv3_class_011_check_line_bounds()
{
uint32_t relative_x = nv3->pgraph.image_current_position.x - nv3->pgraph.image.point.x;
//uint32_t relative_y = nv3->pgraph.image_current_position.y - nv3->pgraph.image.point.y;
/* In theory, relative_y should never be exceeded...because it only submits enough pixels to render the image*/
if (relative_x >= nv3->pgraph.image.size_in.w)
{
nv3->pgraph.image_current_position.y++;
nv3->pgraph.image_current_position.x = nv3->pgraph.image.point.x;
}
}
void nv3_class_011_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj)
{
switch (method_id)
{
case NV3_IMAGE_START_POSITION:
nv3->pgraph.image.point.x = (param & 0xFFFF);
nv3->pgraph.image.point.y = (param >> 16);
nv_log("Image Point=%d,%d", nv3->pgraph.image.point.x, nv3->pgraph.image.point.y);
break;
/* Seems to allow scaling of the bitblt. */
case NV3_IMAGE_SIZE:
nv3->pgraph.image.size.w = (param & 0xFFFF);
nv3->pgraph.image.size.h = (param >> 16);
break;
case NV3_IMAGE_SIZE_IN:
nv3->pgraph.image.size_in.w = (param & 0xFFFF);
nv3->pgraph.image.size_in.h = (param >> 16);
nv3->pgraph.image_current_position = nv3->pgraph.image.point;
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);
if (method_id >= NV3_IMAGE_COLOR_START && method_id <= NV3_IMAGE_COLOR_END)
{
// shift left by 2 because it's 4 bits per si\e..
uint32_t pixel_slot = (method_id - NV3_IMAGE_COLOR_START) >> 2;
uint32_t current_buffer = (nv3->pgraph.context_switch >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03;
/* todo: a lot of stuff */
uint32_t pixel0 = 0, pixel1 = 0, pixel2 = 0, pixel3 = 0;
/* we need to unpack them - IF THIS IS USED SOMEWHERE ELSE, DO SOMETHING ELSE WITH IT */
/* the reverse order is due to the endianness */
switch (nv3->nvbase.svga.bpp)
{
// 4pixels packed into one
case 8:
//pixel3
pixel3 = param & 0xFF;
nv3_render_pixel(nv3->pgraph.image_current_position, pixel3, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
pixel2 = (param >> 8) & 0xFF;
nv3_render_pixel(nv3->pgraph.image_current_position, pixel2, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
pixel1 = (param >> 16) & 0xFF;
nv3_render_pixel(nv3->pgraph.image_current_position, pixel1, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
pixel0 = (param >> 24) & 0xFF;
nv3_render_pixel(nv3->pgraph.image_current_position, pixel0, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
break;
//2pixels packed into 1
case 16:
pixel1 = (param) & 0xFFFF;
nv3_render_pixel(nv3->pgraph.image_current_position, pixel1, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
pixel0 = (param >> 16) & 0xFFFF;
nv3_render_pixel(nv3->pgraph.image_current_position, pixel0, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
break;
// just one
case 32:
pixel0 = param;
nv3_render_pixel(nv3->pgraph.image_current_position, pixel0, grobj);
nv3->pgraph.image_current_position.x++;
nv3_class_011_check_line_bounds();
break;
}
}
else
{
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;
}
}