VOGONS


First post, by emendelson

User metadata
Rank Oldbie
Rank
Oldbie

]Here is a mystery I hope someone can help me solve. I've been building DOSBox for years under both OSX/macOS and Windows (using both Visual Studio and MinGW), using a modified version of the source that owes a lot to helpful people on this forum. Recently I've tried using the same source code for both my OS X builds and Windows builds, and I came across this problem.

When I build under Windows, the startup screen shows the correct ANSI.SYS colors. When I built under OS X in the past (using older versions of my code), I also got the correct ANSI.SYS colors. But when I try to build my current code under OS X (macOS Sierra, actually), I get the wrong colors shown in the attached screen shot.

I can't see anything wrong with the code in shell.cpp, so it seems that something is going wrong somewhere else, perhaps in configure.ac, though I can't imagine what it might be. Here's the relevant shell.cpp code:

 MSG_Add("SHELL_STARTUP_BEGIN",
"\033[44;1m\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n"
"\xBA \033[32mWelcome to DOSBoxWP\033[37m - " __DATE__ " \xBA\n"
"\xBA \xBA\n"
#if defined (MACOSX)
"\xBA To toggle to and from fullscreen, use \033[31mCmd-Enter\033[37m. \xBA\n"
"\xBA To redraw the screen if the colors change, use \033[31mCmd-F3\033[37m. \xBA\n"
"\xBA To adjust the emulated CPU speed, use \033[31mCmd-F11/F12\033[37m. \xBA\n"
"\xBA See the About box on the main menu for other keyboard commands. \xBA\n"
#else
"\xBA For supported shell commands type: \033[33mHELP\033[37m \xBA\n"
"\xBA To toggle between windowed and full-screen modes, use \033[31mAlt-Enter\033[37m. \xBA\n"
"\xBA To adjust the emulated CPU speed, use \033[31mCtrl-Alt-F11/F12\033[37m. \xBA\n"
"\xBA For other keys, see Keyboard help... on the system menu. \xBA\n"
#endif

Can anyone guess what's going wrong here? I'll be very grateful for any help.

PS I use a version of my OneStopDOSBoxOSX script (all ideas by Dominus, not me) to build my code:

https://github.com/emendelson/OneStopDOSBoxOS … topDOSBoxOSX.sh

[attachment=0]Screen Shot 2017-06-04 at 5.07.41 PM.png[/attachment

Last edited by emendelson on 2017-06-05, 15:58. Edited 1 time in total.

Reply 1 of 13, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

It certainly resembles the issue seen before with hi-color modes on Macs: NBA Live 97 on Mac

Your situation seems worse, however, with text modes affected (I doubt it's specific to ANSI colors). In any case, it's presumed to be an endianness issue. As I mentioned in the linked thread, a reversal of ARGB could account for the scrambled colors, so perhaps you can investigate the cause based on that.

Reply 2 of 13, by emendelson

User metadata
Rank Oldbie
Rank
Oldbie

Your memory is amazingly exact. I followed the link and found a fix by applying the first of the two patches in this posting:

https://sourceforge.net/p/dosbox/bugs/347/#ca16

I didn't need the second patch in the message.

But what really puzzles me is this:

Stock SVN, built in macOS Sierra with my build script (where all the intelligent bits are by Dominus, not me), doesn't have this color problem. I don't need to make any changes in the straight SVN code; I don't need to apply the patch in that post. It just works.

So: there must be something else in my modified code that's ultimately causing the ARGB problem here, and I still haven't figured out what it might be. I'll go back and check through all my changes until I figure out what did it, and will report back. Meanwhile, thank you for that exact memory of what is going wrong.

Reply 3 of 13, by emendelson

User metadata
Rank Oldbie
Rank
Oldbie

OK, I think I see where the problem is, though I haven't the faintest idea of how to solve it.

In vga_draw.cpp, in order to get char9 to work, I comment out one part of the code and uncomment another part, like this:

/* // emendelson comment out
static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) {
Bits font_addr;
Bit32u * draw=(Bit32u *)TempLine;
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
Bitu chr=vidmem[cx*2];
Bitu col=vidmem[cx*2+1];
Bitu font=vga.draw.font_tables[(col >> 3)&1][chr*32+line];
Bit32u mask1=TXT_Font_Table[font>>4] & FontMask[col >> 7];
Bit32u mask2=TXT_Font_Table[font&0xf] & FontMask[col >> 7];
Bit32u fg=TXT_FG_Table[col&0xf];
Bit32u bg=TXT_BG_Table[col>>4];
*draw++=(fg&mask1) | (bg&~mask1);
*draw++=(fg&mask2) | (bg&~mask2);
}
if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor;
font_addr = (vga.draw.cursor.address-vidstart) >> 1;
if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) {
if (line<vga.draw.cursor.sline) goto skip_cursor;
if (line>vga.draw.cursor.eline) goto skip_cursor;
draw=(Bit32u *)&TempLine[font_addr*8];
Bit32u att=TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf];
*draw++=att;*draw++=att;
}
skip_cursor:
return TempLine;
}
*/ // end emendelson comment out

and:

// emendelson uncomments
// combined 8/9-dot wide text mode 8bpp line drawing function
static Bit8u* VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) {
// keep it aligned:
Bit8u* draw = ((Bit8u*)TempLine) + 16 - vga.draw.panning;
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs
Bitu blocks = vga.draw.blocks;
if (vga.draw.panning) blocks++; // if the text is panned part of an
// additional character becomes visible
while (blocks--) { // for each character in the line
Bitu chr = *vidmem++;
Bitu attr = *vidmem++;
// the font pattern
Bitu font = vga.draw.font_tables[(attr >> 3)&1][(chr<<5)+line];

Bitu background = attr >> 4;
// if blinking is enabled bit7 is not mapped to attributes
if (vga.draw.blinking) background &= ~0x8;
// choose foreground color if blinking not set for this cell or blink on
Bitu foreground = (vga.draw.blink || (!(attr&0x80)))?
(attr&0xf):background;
// underline: all foreground [freevga: 0x77, previous 0x7]
if (GCC_UNLIKELY(((attr&0x77) == 0x01) &&
(vga.crtc.underline_location&0x1f)==line))
background = foreground;
if (vga.draw.char9dot) {
font <<=1; // 9 pixels
// extend to the 9th pixel if needed
if ((font&0x2) && (vga.attr.mode_control&0x04) &&
(chr>=0xc0) && (chr<=0xdf)) font |= 1;
for (Bitu n = 0; n < 9; n++) {
*draw++ = (font&0x100)? foreground:background;
font <<= 1;
}
} else {
for (Bitu n = 0; n < 8; n++) {
*draw++ = (font&0x80)? foreground:background;
font <<= 1;
}
}
}
// draw the text mode cursor if needed
if ((vga.draw.cursor.count&0x8) && (line >= vga.draw.cursor.sline) &&
(line <= vga.draw.cursor.eline) && vga.draw.cursor.enabled) {
// the adress of the attribute that makes up the cell the cursor is in
Bits attr_addr = (vga.draw.cursor.address-vidstart) >> 1;
if (attr_addr >= 0 && attr_addr < (Bits)vga.draw.blocks) {
Bitu index = attr_addr * (vga.draw.char9dot? 9:8);
draw = (Bit8u*)(&TempLine[index]) + 16 - vga.draw.panning;

Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf;
for (Bitu i = 0; i < 8; i++) {
*draw++ = foreground;
}
}
}
return TempLine+16;
}
// end emendelson uncomments

Elsewhere in the file, I do this:

case M_TEXT:
vga.draw.blocks=width;
doublewidth=(vga.seq.clocking_mode & 0x8) > 0;
// next is replacement by ripsaw emendelson
if (IS_VGA_ARCH) {
// allow 9-pixel wide fonts
if (!render.char9 || vga.seq.clocking_mode&0x01) {
// end ripsaw emendelson
vga.draw.char9dot = false;
width*=8;
} else {
vga.draw.char9dot = true;
width*=9;
// aspect_ratio*=1.125; // removed ripsaw emendelson
}
/// if (svgaCard==SVGA_None) { // ripsaw emendelson
VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line;
bpp=16;
/// } else VGA_DrawLine=VGA_TEXT_Draw_Line; // ripsaw emendelson
/// } else {
/// // not vgaonly: force 8-pixel wide fonts
/// width*=8; // 8 bit wide text font
/// vga.draw.char9dot = false;
/// VGA_DrawLine=VGA_TEXT_Draw_Line;
}
aspect_ratio=(vga.draw.char9dot)?1.35:1.2; // ripsaw emendelson
break;

If I uncomment the commented-out block, and comment out the uncommented block, then I get the right colors, but not char9.

Is there an easy fix that would give back the colors while keeping char9? As you can see, I'm deeply indebted to you for help with this years ago, and I hope I'm not asking too much by coming back for more.

PS: The colors are correct in Win32; they're wrong only in OS X/macOS. And you're right - this has nothing to do with ANSI.SYS colors; I've changed the title of the thread to reflect this.

Reply 4 of 13, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

There were other things than 9-dot characters you wanted, like 512 characters. I forget the reason(s) for using the 16-bpp drawing instead of 8-bpp, but that would appear to be a crucial point in the color issue. However, what I don't understand is why it's only an issue *now*, all these years later...

Reply 5 of 13, by emendelson

User metadata
Rank Oldbie
Rank
Oldbie
ripsaw8080 wrote:

There were other things than 9-dot characters you wanted, like 512 characters. I forget the reason(s) for using the 16-bpp drawing instead of 8-bpp, but that would appear to be a crucial point in the color issue. However, what I don't understand is why it's only an issue *now*, all these years later...

Wait - after writing the rest of this message I seem to have fixed the problem, though I'm not at all sure how. I'll post details when I figure it out.

Meanwhile, to answer your question:

I should have been more clear: It's only an issue now because I decided to re-create my whole project from scratch, starting from current SVN instead of the ancient code that I was using when you provided patches for 512-characters, underline in mode mono, and char9. Since that time, SVN made changes that supported 512-characters, underline in mode mono, and much else, so I thought it would make life easier if I worked with current code. It was getting

The only thing missing from SVN was char9, and I was able to get that working (in Win32) but making the changes spelled out in my earlier message with the three blocks of code. So yesterday, I tried to see if my new code would work in OS X - and found the problem with the colors.

Reply 6 of 13, by emendelson

User metadata
Rank Oldbie
Rank
Oldbie

Well, I need to apologize (yet again) for wasting your time. The problem was that I had commented out too many lines. Instead of the third code block in my message above, I should have used this:

case M_TEXT:
vga.draw.blocks=width;
doublewidth=(vga.seq.clocking_mode & 0x8) > 0;
if (IS_VGA_ARCH) {
// allow 9-pixel wide fonts
if (!render.char9 || vga.seq.clocking_mode&0x01) {
vga.draw.char9dot = false;
width*=8;
} else {
vga.draw.char9dot = true;
width*=9;
}
if (svgaCard==SVGA_None) { // ripsaw emendelson
VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line;
bpp=16;
} else VGA_DrawLine=VGA_TEXT_Draw_Line; // ripsaw emendelson
} else {
/// // not vgaonly: force 8-pixel wide fonts
width*=8; // 8 bit wide text font
vga.draw.char9dot = false;
VGA_DrawLine=VGA_TEXT_Draw_Line;
}
aspect_ratio=(vga.draw.char9dot)?1.35:1.2;
break;

The problem was ignorance on my part, and the result was that you wasted time tracking down an old bug. Apologies again for that, and again a thousand thanks for all the help you've given over the years.

Reply 7 of 13, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

The machine=vgaonly setting uses 16-bpp drawing to support line-wise palette changes, so it would seem to be susceptible to the issue. Can you confirm that with a vanilla SVN build on your Mac system?

Reply 8 of 13, by emendelson

User metadata
Rank Oldbie
Rank
Oldbie
ripsaw8080 wrote:

The machine=vgaonly setting uses 16-bpp drawing to support line-wise palette changes, so it would seem to be susceptible to the issue. Can you confirm that with a vanilla SVN build on your Mac system?

Yes, as you thought, the issue occurs with pure SVN. The screen shot has the details:

The attachment Screen Shot 2017-06-05 at 7.46.10 PM.png is no longer available

I'm not sure this is relevant, but the issue seems to occur only if machine=vgaonly is set in the .conf file. If it is set in the .conf file, then a change in the setting from the command line has no effect; if it is NOT set in the .conf file, then a change to machine=vgaonly does not cause the issue to occur.

PPS: As you see from the screen shot, I use config -get cpu in my tests. This is to make sure that I don't have the problem where dynamic crashes in an OS X build.

Last edited by emendelson on 2017-06-06, 12:54. Edited 1 time in total.

Reply 9 of 13, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Thanks for checking. It makes sense that vgaonly is affected, but I don't recall that being noted about the issue before.

When changing the machine= setting at the prompt, it won't go into effect until DOSBox is restarted. In SVN you can write the changed setting and restart from the prompt with: config -writeconf -r

Reply 10 of 13, by emendelson

User metadata
Rank Oldbie
Rank
Oldbie

OK - let me know if there's anything else I can do...

Reply 11 of 13, by TheGreatCodeholio

User metadata
Rank Oldbie
Rank
Oldbie

I've come across this in DOSBox-X as well. Intel builds of Mac OS X use a strange RGBA byte order. Where PC hardware uses ARGB, Mac OS X uses BGRA.

To clarify, that puts the 8-bit alpha channel in the LOWER 8 bits and the blue channel in the HIGHEST 8 bits.

DOSBox-X deals with this by following what SDL reports as the red/green/blue bitfields and following them, and for Mac OS X, assuming the BGRA order.

The other problem is in the render scaler code, which assumes the PC ARGB format and cannot directly handle Mac OS X's BGRA format.

It's messy, but it works.

DOSBox-X project: more emulation better accuracy.
DOSLIB and DOSLIB2: Learn how to tinker and hack hardware and software from DOS.

Reply 13 of 13, by TheGreatCodeholio

User metadata
Rank Oldbie
Rank
Oldbie

Here you go:

Re: DOSBox-X branch

DOSBox-X project: more emulation better accuracy.
DOSLIB and DOSLIB2: Learn how to tinker and hack hardware and software from DOS.