From c537e614536a7104e426b6068bf4ed4c31db6033 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 30 Jun 2025 23:09:29 +0600 Subject: [PATCH] Copper demo wobbling effects now show up correctly --- src/include/86box/vid_svga.h | 3 +++ src/video/vid_et4000.c | 3 +++ src/video/vid_svga.c | 10 ++++++++ src/video/vid_svga_render.c | 45 ++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 78e025746..14f3c933a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -30,6 +30,7 @@ # define FLAG_S3_911_16BIT 256 # define FLAG_512K_MASK 512 # define FLAG_NO_SHIFT3 1024 /* Needed for Bochs VBE. */ +# define FLAG_PRECISETIME 2048 /* Needed for Copper demo if on dynarec. */ struct monitor_t; typedef struct hwcursor_t { @@ -138,6 +139,8 @@ typedef struct svga_t { int ati_4color; int vblankend; int panning_blank; + int render_line_offset; + int start_retrace_latch; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index d7de0706e..7dccd9747 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -892,6 +892,9 @@ et4000_init(const device_t *info) if (dev->type >= ET4000_TYPE_ISA) dev->svga.ramdac = device_add(&sc1502x_ramdac_device); + if (dev->type == ET4000_TYPE_TC6058AF) + dev->svga.adv_flags |= FLAG_PRECISETIME; + dev->vram_mask = dev->vram_size - 1; rom_init(&dev->bios_rom, fn, diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index e4a6d9efc..5f2d2d89c 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -703,6 +703,13 @@ svga_recalctimings(svga_t *svga) int old_monitor_overscan_x = svga->monitor->mon_overscan_x; int old_monitor_overscan_y = svga->monitor->mon_overscan_y; + if (svga->adv_flags & FLAG_PRECISETIME) { +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; svga->vsyncstart = svga->crtc[0x10]; @@ -1253,6 +1260,7 @@ svga_do_render(svga_t *svga) } if (!svga->override) { + svga->render_line_offset = svga->start_retrace_latch - svga->crtc[0x4]; svga->render(svga); svga->x_add = svga->left_overscan; @@ -1514,6 +1522,8 @@ svga_poll(void *priv) if (svga->vsync_callback) svga->vsync_callback(svga); + + svga->start_retrace_latch = svga->crtc[0x4]; } #if 0 if (svga->vc == lines_num) { diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index bd471e72e..5905a25dd 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -744,6 +744,13 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) return; p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->render_line_offset) { + if (svga->render_line_offset > 0) { + memset(p, svga->overscan_color, charwidth * svga->render_line_offset * sizeof(uint32_t)); + p += charwidth * svga->render_line_offset; + } + } + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; @@ -900,6 +907,12 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) else p += charwidth; } + + if (svga->render_line_offset < 0) { + uint32_t *orig_line = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + memmove(orig_line, orig_line + (charwidth * -svga->render_line_offset), (svga->hdisp) * 4); + memset((orig_line + svga->hdisp) - (charwidth * -svga->render_line_offset), svga->overscan_color, charwidth * -svga->render_line_offset * 4); + } } /* @@ -1279,17 +1292,26 @@ svga_render_8bpp_tseng_lowres(svga_t *svga) { uint32_t *p; uint32_t dat; + int x = 0; if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange || svga->render_line_offset) { + int end = svga->hdisp + svga->scrollcache; p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; + if (svga->render_line_offset) { + if (svga->render_line_offset > 0) { + memset(p, svga->overscan_color, 8 * svga->render_line_offset * sizeof(uint32_t)); + p += 8 * svga->render_line_offset; + } + } + for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) @@ -1311,6 +1333,11 @@ svga_render_8bpp_tseng_lowres(svga_t *svga) svga->memaddr += 4; p += 8; } + if (svga->render_line_offset < 0) { + uint32_t *orig_line = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + memmove(orig_line, orig_line + (8 * -svga->render_line_offset), (svga->hdisp) * 4); + memset((orig_line + svga->hdisp) - (8 * -svga->render_line_offset), svga->overscan_color, 8 * -svga->render_line_offset * 4); + } svga->memaddr &= svga->vram_display_mask; } } @@ -1324,13 +1351,20 @@ svga_render_8bpp_tseng_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange || svga->render_line_offset) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; + if (svga->render_line_offset) { + if (svga->render_line_offset > 0) { + memset(p, svga->overscan_color, 8 * svga->render_line_offset * sizeof(uint32_t)); + p += 8 * svga->render_line_offset; + } + } + for (int x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) @@ -1369,6 +1403,13 @@ svga_render_8bpp_tseng_highres(svga_t *svga) svga->memaddr += 8; p += 8; } + + if (svga->render_line_offset < 0) { + uint32_t *orig_line = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + memmove(orig_line, orig_line + (8 * -svga->render_line_offset), (svga->hdisp) * 4); + memset((orig_line + svga->hdisp) - (8 * -svga->render_line_offset), svga->overscan_color, 8 * -svga->render_line_offset * 4); + } + svga->memaddr &= svga->vram_display_mask; } }