Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH] Fix for bug W343-3, part 1: Details of the console API bug

14 views
Skip to first unread message

Ray Chason

unread,
Nov 5, 2005, 6:33:12 AM11/5/05
to
Bug W343-3 really consists of two distinct and unrelated bugs. This post is
the first of a four part series, and describes the first of these two bugs.
It is not in fact a bug in NetHack, but a bug in certain versions of
Windows; it appears when certain character sets are configured.

The bug requires four conditions before it will appear:

* an NT-based version of Windows
* the console box running in a window, as opposed to full screen
* a bitmap font selected, as opposed to Lucida Console
* the language for non-Unicode programs set to one that does _not_ use code
page 437 or 850

Character sets known to trigger the console box bug are:

* code page 737 - Greek
* code page 775 - Baltic languages
* code page 852 - Central European languages in the Latin alphabet
* code page 857 - Turkish
* code page 866 - Cyrillic

Character sets known _not_ to trigger the console box bug are:

* code page 437 - English
* code page 850 - Most other West European languages

Here's how to duplicate the console box bug on an English-language version
of Windows XP:

* Go to Control Panel and select Regional and Language Settings.

* From the dialog, select the third tab, "Advanced".

* At the top of this page is a box labeled "Language for non-Unicode
programs". From the combo box, select "Polish". Russian, Czech, Greek,
Turkish, and Lithuanian are also known to trigger the bug. (This setting
does not change the language of the Windows UI; it only seems to affect
the character set used by the non-Unicode APIs.)

* Click Ok.

* You may get a dialog saying that the required files are already on disk.
Click Yes to skip copying them again. Or you may get a dialog prompting
for the Windows disk. Insert it and click Ok.

* Windows now needs to reboot.

* When Windows has finished rebooting, open a command shell, set it to
windowed mode (full screen does not trigger the bug), set the font to
bitmap (choose Properties from the menu at the upper left), and run the
console version of NetHack. Make sure IBMgraphics is enabled. You will
see the dungeon drawn incorrectly.

Here's a test program that demonstrates both the bug and a proposed fix:

--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void
print_glyph_8(unsigned glyph, int X, int Y)
{
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
WORD attr = 0x07;
char ch = (char)glyph;
DWORD count;
COORD cursor;

cursor.X = X;
cursor.Y = Y;
WriteConsoleOutputAttribute(hcon, &attr, 1, cursor, &count);
WriteConsoleOutputCharacterA(hcon, &ch, 1, cursor, &count);
}

void
print_glyph_16(unsigned glyph, int X, int Y)
{
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
WORD attr = 0x07;
WCHAR ch = (WCHAR)glyph;
DWORD count;
COORD cursor;

cursor.X = X;
cursor.Y = Y;
WriteConsoleOutputAttribute(hcon, &attr, 1, cursor, &count);
WriteConsoleOutputCharacterW(hcon, &ch, 1, cursor, &count);
}

int
main(void)
{
int X, Y;
CONSOLE_SCREEN_BUFFER_INFO info;
COORD c;
CHAR ch;
WCHAR wch;

GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);

for (Y=0; Y<16; Y++)
for (X=0; X<16; X++)
print_glyph_8(Y*16+X, X*2, Y+info.dwCursorPosition.Y+1);

for (Y=0; Y<16; Y++)
{
for (X=0; X<16; X++)
{
ch = Y*16+X;
MultiByteToWideChar(CP_OEMCP, 0, &ch, 1, &wch, 1);
print_glyph_16(wch, X*2+40, Y+info.dwCursorPosition.Y+1);
}
}

c.X = 0;
c.Y = info.dwCursorPosition.Y+17;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
return 0;
}
--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--CUT HERE--

When run on an NT-based version of Windows, the program prints two character
tables. (95-based versions of Windows do not have the Unicode APIs; I
haven't tried this program, but I expect that only one table will appear.)

The table on the left is generated by the function print_glyph_8. If the
four conditions named above are all met, the table will come up damaged;
depending on the size of the font, the incorrect glyphs may appear as
spaces, apostrophes, or inverted triangles.

The table on the right is generated by the function print_glyph_16. This
function is similar to print_glyph_8, but uses the Unicode version of
WriteConsoleOutputCharacter. When combined with the character set
translation from MultiByteToWideChar, it generates a correct table for all
8-bit character sets.

This is the proposed fix. Check the version of Windows in use, and if it's
NT-based, transform the IBMgraphics and use the Unicode API. Spanish
NetHack already does this, and it displays a correct map.

--
--------------===============<[ Ray Chason ]>===============--------------
The War on Terra is not meant to be won.
Delendae sunt RIAA, MPAA et Windoze

0 new messages