VOGONS


First post, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

All of the Event Horizon RPG games (DarkSpyre, Dusk of the Gods, The Summoning, and Veil of Darkness) have a similar game engine mechanism where a status/inventory screen can be dragged up over the main view using the mouse. This sliding screen works fine until you reach the top, meaning the very topmost pixel of the screen, where the screen becomes corrupted in various ways depending on where you are in the game. If you drag the window back down, the problem goes away; but if you've moved the mouse from the grab/drag region, it can be hard to recover because you can't see the mouse cursor when the screen is glitched up. It's easy enough to work around, just don't drag all the way to the top; but the status screen also automatically snaps to the top when starting a new game, or loading a saved position, so the glitch is unavoidable at those times.

I tested older versions of DOSBox and found that the problem isn't present in 0.60, so it seems that the problem started in 0.61 and has carried through to later versions.

Reply 1 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I thought I would try figure out if changes in the VGA code might have caused this issue, but I guess I would need an older version of the g++ complier for 0.60 or 0.61, because the current one doesn't seem to be compatible (compilation errors). Using the process of elimination might not have worked, but I had a better shot with that than truly comprehending the code. 😒

Reply 2 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Perhaps some images will better demonstrate the glitched graphics. These come from Veil of Darkness, the best and most evolved of the games, and probably the one people will even care about.

The status area at it lowest point with maximum main view area:

veil1zn9.png

The status display dragged up just one tic below the highest point:

veil2yx8.png

Dragged all the way to the top, it should show the full status area, but instead you get:

veil3fd2.png

How the display gets corrupted varies a bit, but it's usually pieces of the main view and status area jumbled around in various ways. Running under DOS, even in the WinXP DOS shell, this doesn't happen.

Reply 3 of 20, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Well looks funny 😀
Maybe try compiling 0.60/0.61 with msvc or something, dunno if that
would work better.
Be sure to try different cores, and vasyl's svga patch (treats some vga
oddities as well iirc.)

Reply 4 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I've tried different cores and different cycles, disabled sound, and turned off memory management stuff like EMS/XMS; none of it makes a difference. I tested ykhwong's and gulikoza's builds (which I believe do have vasyl's patch in them) with different chipset configurations, also no effect.

It's purely a guess, but it seems like a video buffer pointer is getting miscalculated in this case.

Reply 5 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I've been experimenting with this glitch in my 0.72 test build and I think I've narrowed down the focus of what to look at more closely. It seems this "split screen" thing used in the games is a feature of VGA hardware, and not just implemented in software. I've been fiddling with the code around the vga.draw.split_line variable in vga_draw.cpp, and I think I'm getting warmer, but I haven't found the real cause of the problem. Unfortunately, comparing the code for 0.60 (which doesn't exhibit the glitch) and 0.61 (first version with the glitch) doesn't give me much to go on because there were some significant changes in rendering between those versions.

Reply 6 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I believe I have found the cause of the glitch for the Event Horizon games. It appears to be result of having the variable vga.draw.split_line equal to 0 when the VGA split screen feature is active.

The following are the two sequential lines of code from vga_draw.cpp that I think are significant:

vga.draw.lines_done++;
if (vga.draw.split_line==vga.draw.lines_done) {

If vga.draw.split_line is 0, it will never be equal to vga.draw.lines_done after it is incremented. Moving the increment after the condition fixes the glitch with the Event Horizon games, and possibly any other games that have similar conditions.

A consequence of this change is that the bottom "window" appears to be drawn one pixel lower than before in DOSBox, however this is exactly how it appears when the game is running in the WinXP DOS Shell. Unfortunately, I don't have a living DOS machine to compare to.

Reply 7 of 20, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Hm i thought splitline being zero means that it isn't used, so the behaviour
is correct. Maybe you can check how the splitline value is programmed by
the game (should be some crtc register).
Was this part changed from 0.60 to 0.61 (for bad as you describe)?

Reply 8 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Well, you would know far better than I. However the change does not appear to "break" any other games that I've tested. Also, the bottom window position in 0.60 is the same as subsequent versions, it's just that it doesn't get glitched up in 0.60. Using the example of how the game looks in the DOS Shell, it suggests that bottom window really should be rendered one pixel lower. I tried adding 1 to the calc for the split line, and that works too... but that's also not consistent with your thinking that a value of 0 is used to disable the split screen feature.

Reply 9 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Well, now that I think about it. Maybe the problem is that the splitline becomes 0 when the bottom window is slid all the way up... it shouldn't BE allowed to be zero when you have a split screen in effect... there probably is some crtc trigger for the split screen feature, but I'm probably out of my depth with that.

Reply 10 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Looking at vga_crtc.cpp, the vga.config.line_compare is set there through various register writes, and that variably is used in calculating vga.draw.split_line. Perhaps adding 1 to line_compare there would do the trick?

Reply 12 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I did a bit of debug logging of the split_line variable in my test build of DOSBox. I would have tried that before, but I was having some trouble getting pdcurses to compile into the project. Anyway, in text modes and graphics modes it does not appear to be zero when there is no split screen in use; rather it is a value well beyond the last line of the display. Only when there IS a split screen in use (at least in these Event Horizon games I'm looking at, dunno what other games might use this split screen feature) is the split_line within the range of drawn lines, and zero is apparently a valid value. So, I'm tending to think that my original suggestion of moving the increment after the condition is a reasonable and simple fix for this issue based on my observations. A) it eliminates the glitch, and B) it moves the bottom window down one pixel, exactly how it is in the DOS shell. Please ask Harekiet for his opinion on this.

Reply 13 of 20, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Yes, i think using a postdecrement fixes it for good. It seems to have gone
broken when the logic was reversed, that is the split lines was total-split
before and now is split only, just off by one.
Don't know if this is/was intentional, doesn't look like though.

Reply 15 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Taking a closer look at the games running in the WinXP DOS shell, the bottom window isn't shifted down by a full pixel, more like a fraction of a pixel... it's kind of strange. I really should know better than to use the NTVDM as a reference for proper operation of a DOS VGA game. 😒

I think DOSBox already has it right with regard to the bottom window position, so I went back to the drawing board. It occured to me that the window gets shifted down because the check for the split occurs after a line has been rendered. I looked at 0.60, and sure enough, it checks the split before rendering lines. I modified 0.72 to move the split check before the line render, which keeps the increment of lines_done after the check so a split at line 0 is handled, and now it really seems to be right. No glitch, no window shift, and when the bottom window is dragged all the way up it completely obscures the top window and displays the last pixel row of the bottow window (which it didn't do when shifted down). Sorry for going around and around on this issue, but I've tested this pretty thoroughly, and it appears to be a complete solution.

I only have Winmerge for making diff files, which is probably not like the CVS diff utilities you're used to using, so I'll just show the code here to clarify how I moved the chunk.

static void VGA_DrawPart(Bitu lines) {
while (lines--) {
if (vga.draw.split_line==vga.draw.lines_done) {
#ifdef VGA_KEEP_CHANGES
VGA_ChangesEnd( );
#endif
vga.draw.address=0;
if(!(vga.attr.mode_control&0x20))
vga.draw.address += vga.config.pel_panning;
vga.draw.address_line=0;
#ifdef VGA_KEEP_CHANGES
vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT;
#endif
}
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
RENDER_DrawLine(data);
vga.draw.address_line++;
if (vga.draw.address_line>=vga.draw.address_line_total) {
vga.draw.address_line=0;
vga.draw.address+=vga.draw.address_add;
}
vga.draw.lines_done++;
}
if (--vga.draw.parts_left) {
PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,
(vga.draw.parts_left!=1) ? vga.draw.parts_lines : (vga.draw.lines_total - vga.draw.lines_done));
} else {
#ifdef VGA_KEEP_CHANGES
VGA_ChangesEnd();
#endif
RENDER_EndUpdate();
}
}

Reply 16 of 20, by h-a-l-9000

User metadata
Rank DOSBox Author
Rank
DOSBox Author

The change in CVS seems to break Secret Agent (I'm not 100% sure as my build is not clean).

Attachments

  • linecompbug.png
    Filename
    linecompbug.png
    File size
    3.85 KiB
    Views
    4117 views
    File license
    Fair use/fair dealing exception

1+1=10

Reply 17 of 20, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Hmm, split windows are found in more games than I thought. It's strange that some games work better with the bottom window shifted down a pixel (Pinball Fantasies for example), while others do not... this being another example. It makes me wonder how these splits look on real VGA hardware. Maybe there was a slight discrepancy between different VGA card manufacturers, and game developers tweaked their games to the hardware they were using... just a thought.

Anyway, the last code example I posted was my attempt to return things to how they were in 0.60 where there was no glitch with a split at row 0. By moving the split check before lines are rendered, the bottom window is not moved down and the glitched graphics don't occur with a splitline of 0. Neither wd or Harekiet commented on my last post, so I think they'd made up their minds to go with shifting the window down.

Reply 18 of 20, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I'm not 100% sure as my build is not clean

Same here. On a real pc the top line above the items (the black pixels)
is only a half 320x200-mode pixel high, and the bottom line as well.
Would have to double the resolution for that.

Neither wd or Harekiet commented on my last post

Too bad, guess you have to live with that.