mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
Implement hardware cursor support (9x now displays mouse cursor)
This commit is contained in:
@@ -463,13 +463,6 @@ extern const device_config_t nv3t_config[]; // Confi
|
||||
#define NV3_PME_INTR_EN 0x200140 // Mediaport: Interrupt Enable
|
||||
#define NV3_PME_END 0x200FFF
|
||||
|
||||
// THIS IS NOT A REAL REGISTER.
|
||||
// This is so my software e.g. nvplayground can determine if the software is being run in an emulator on a real RIVA 128.
|
||||
// This register should have some sort of open bus, garbage or 00/FF on a real NV3/NV3T but have a string.
|
||||
#define NV3_EMULATED_MARKER_START 0x269420
|
||||
|
||||
#define NV3_EMULATED_MARKER 0x0D15EA5E
|
||||
|
||||
#define NV3_PGRAPH_START 0x400000 // Scene graph for 2d/3d rendering...the most important part
|
||||
// PGRAPH Core
|
||||
|
||||
@@ -800,6 +793,10 @@ extern const device_config_t nv3t_config[]; // Confi
|
||||
#define NV3_RAMIN_RAMRM_START 0x1C02000
|
||||
#define NV3_RAMIN_RAMRM_END 0x1C02FFF
|
||||
|
||||
// I'm not sure if this can be moved.
|
||||
// 4K of "PRAM" is listed at 0x6000.
|
||||
#define NV3_RAMIN_OFFSET_CURSOR 0x6000
|
||||
|
||||
#define NV3_RAMIN_END 0x1FFFFFF
|
||||
|
||||
// not done
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<width>620</width>
|
||||
<height>350</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -18,13 +18,13 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<width>620</width>
|
||||
<height>350</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<width>620</width>
|
||||
<height>350</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -88,7 +88,7 @@
|
||||
<x>10</x>
|
||||
<y>30</y>
|
||||
<width>151</width>
|
||||
<height>16</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
@@ -98,7 +98,7 @@
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>420</x>
|
||||
<x>390</x>
|
||||
<y>30</y>
|
||||
<width>91</width>
|
||||
<height>16</height>
|
||||
@@ -111,14 +111,14 @@
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>510</x>
|
||||
<x>480</x>
|
||||
<y>30</y>
|
||||
<width>49</width>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-weight:700;">PLACEHOLDER 9000</span></p></body></html></string>
|
||||
<string><html><head/><body><p><span style=" font-weight:700;">PLACEHOLDER</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit_2">
|
||||
@@ -137,13 +137,26 @@
|
||||
<x>10</x>
|
||||
<y>60</y>
|
||||
<width>151</width>
|
||||
<height>16</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Pixel Depth</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="loadSavestateBtn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>110</y>
|
||||
<width>231</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load nvplay savestate from real hardware</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -866,9 +866,14 @@ void nv3_draw_cursor(svga_t* svga, int32_t drawline)
|
||||
if ((nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_CURSOR_START] >> NV3_CRTC_REGISTER_CURSOR_START_DISABLED) & 0x01)
|
||||
return;
|
||||
|
||||
// On windows, this shows up using NV_IMAGE_IN_MEMORY.
|
||||
// NT GDI drivers: Load cursor using NV_IMAGE_FROM_MEMORY ("NV3LCD")
|
||||
// 9x GDI drivers: Use H/W cursor in RAMIN
|
||||
|
||||
// Do we need to emulate it?
|
||||
uint32_t vram_cursor_base = nv3->pramdac.cursor_address;
|
||||
|
||||
// THIS IS CORRECT. BUT HOW DO WE FIND IT?
|
||||
uint32_t ramin_cursor_position = NV3_RAMIN_OFFSET_CURSOR;
|
||||
|
||||
/* let's just assume buffer 0 here...that code needs to be totally rewritten*/
|
||||
nv3_coord_16_t start_position = nv3->pramdac.cursor_start;
|
||||
|
||||
@@ -890,49 +895,64 @@ void nv3_draw_cursor(svga_t* svga, int32_t drawline)
|
||||
We have to get a 32x32, "A"1R5G5B5-format cursor
|
||||
out of video memory. The alpha bit actually means - XOR with display pixel if 0, replace if 1
|
||||
|
||||
Technically these are expanded to RGB10, but I don't see why this needs to happen. And our pipeline isn't set up for it anyway.
|
||||
These are expanded to RGB10 only if they are XORed. We don't do this (we don't really need to + there is no grobj specified here so special casing
|
||||
would be needed) so we just xor it with the current pixel format
|
||||
*/
|
||||
for (int32_t y = 0; y < NV3_PRAMDAC_CURSOR_SIZE_Y; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < NV3_PRAMDAC_CURSOR_SIZE_X; x++)
|
||||
{
|
||||
uint16_t current_pixel = vram_16[vram_cursor_base << 1];
|
||||
bool replace_bit = (current_pixel & 0x8000);
|
||||
|
||||
switch (nv3->nvbase.svga.bpp)
|
||||
uint16_t current_pixel = nv3_ramin_read16(ramin_cursor_position, nv3);
|
||||
|
||||
// 0000 = transparent, so skip drawing
|
||||
if (current_pixel)
|
||||
{
|
||||
/* this is indexed colour but... lol */
|
||||
case 8:
|
||||
if (replace_bit)
|
||||
{
|
||||
uint8_t final = current_pixel ^ nv3->nvbase.svga.vram[final_position];
|
||||
nv3->nvbase.svga.vram[final_position] = final;
|
||||
}
|
||||
else // just override
|
||||
nv3->nvbase.svga.vram[final_position] = current_pixel;
|
||||
case 15 ... 16: // easy case (our cursor is 15bpp format)
|
||||
uint32_t index_16 = final_position >> 1;
|
||||
if (replace_bit)
|
||||
{
|
||||
uint16_t final = current_pixel ^ vram_16[index_16];
|
||||
vram_16[index_16] = final;
|
||||
}
|
||||
else // just override
|
||||
vram_16[index_16] = current_pixel;
|
||||
case 32:
|
||||
uint32_t index_32 = final_position >> 2;
|
||||
if (replace_bit)
|
||||
{
|
||||
uint16_t final = current_pixel ^ vram_32[index_32];
|
||||
vram_32[index_32] = final;
|
||||
}
|
||||
else // just override
|
||||
vram_32[index_32] = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here
|
||||
break;
|
||||
bool replace_bit = (current_pixel & 0x8000);
|
||||
|
||||
// use buffer 0 BPIXEL
|
||||
uint32_t bpixel_format = (nv3->pgraph.bpixel[0]) & 0x03;
|
||||
|
||||
switch (bpixel_format)
|
||||
{
|
||||
case bpixel_fmt_8bit:
|
||||
if (replace_bit)
|
||||
nv3->nvbase.svga.vram[final_position] = current_pixel;
|
||||
else //xor
|
||||
{
|
||||
// not sure what to do here. we'd have to search through the palette to find the closest possible colour.
|
||||
uint8_t final = current_pixel ^ nv3->nvbase.svga.vram[final_position];
|
||||
nv3->nvbase.svga.vram[final_position] = final;
|
||||
}
|
||||
case bpixel_fmt_16bit: // easy case (our cursor is 15bpp format)
|
||||
uint32_t index_16 = final_position >> 1;
|
||||
|
||||
if (replace_bit) // just replace
|
||||
vram_16[index_16] = current_pixel;
|
||||
else // xor
|
||||
{
|
||||
current_pixel &= ~0x8000; // mask off the xor bit
|
||||
uint16_t final = current_pixel ^ vram_16[index_16];
|
||||
vram_16[index_16] = final;
|
||||
}
|
||||
case bpixel_fmt_32bit:
|
||||
uint32_t index_32 = final_position >> 2;
|
||||
|
||||
if (replace_bit) // just replace
|
||||
vram_32[index_32] = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here
|
||||
else //xor
|
||||
{
|
||||
current_pixel &= ~0x8000; // mask off the xor bit
|
||||
uint32_t current_pixel_32 = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here
|
||||
|
||||
uint32_t final = current_pixel_32 ^ vram_32[index_32];
|
||||
vram_32[index_32] = final;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// increment vram position
|
||||
vram_cursor_base += 2;
|
||||
ramin_cursor_position += 2;
|
||||
|
||||
// go
|
||||
switch (nv3->nvbase.svga.bpp)
|
||||
|
||||
@@ -739,7 +739,7 @@ void nv3_pfifo_cache0_pull(void)
|
||||
uint32_t current_context = nv3->pfifo.cache0_settings.context[0]; // only 1 entry for CACHE0 so basically ignore the other context entries?
|
||||
uint8_t class_id = ((nv3_ramin_context_t*)¤t_context)->class_id;
|
||||
|
||||
// Tell the CPU if we found a software method
|
||||
// Tell the CPU if we found a software method and turn off cache pulling
|
||||
if (!(current_context & 0x800000))
|
||||
{
|
||||
nv_log("The object in CACHE0 is a software object\n");
|
||||
|
||||
Reference in New Issue
Block a user