1
0
Fork 0

- Use temporary storage for linear scanline, fixes corruption in Fractint SVGA modes

- Implement wrapping on lower-order bit, fixes black line in Titan

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3648
This commit is contained in:
Ralf Grillenberger 2010-10-04 21:46:23 +00:00
parent c2622359f9
commit eff418eaee

View file

@ -175,12 +175,28 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) {
#endif
static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu /*line*/) {
// There is guaranteed extra memory past the wrap boundary. So, instead of using temporary
// storage just copy appropriate chunk from the beginning to the wrap boundary when needed.
Bitu offset = vidstart & vga.draw.linear_mask;
if (vga.draw.linear_mask-offset < vga.draw.line_length)
memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length);
Bit8u *ret = &vga.draw.linear_base[ offset ];
Bit8u* ret = &vga.draw.linear_base[offset];
// in case (vga.draw.line_length + offset) has bits set that
// are not set in the mask: ((x|y)!=y) equals (x&~y)
if (GCC_UNLIKELY((vga.draw.line_length + offset)& ~vga.draw.linear_mask)) {
// this happens, if at all, only once per frame (1 of 480 lines)
// in some obscure games
Bitu end = (offset + vga.draw.line_length) & vga.draw.linear_mask;
// assuming lines not longer than 4096 pixels
Bitu wrapped_len = end & 0xFFF;
Bitu unwrapped_len = vga.draw.line_length-wrapped_len;
// unwrapped chunk: to top of memory block
memcpy(TempLine, &vga.draw.linear_base[offset], unwrapped_len);
// wrapped chunk: from base of memory block
memcpy(&TempLine[unwrapped_len], vga.draw.linear_base, wrapped_len);
ret = TempLine;
}
#if !defined(C_UNALIGNED_MEMORY)
if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) {
memcpy( TempLine, ret, vga.draw.line_length );