views:

242

answers:

3

Over the past week I've been working on a roguelike game in C++ along with a friend. Mostly too learn the language.

I'm using:

To output wchar_t's wherever I want to in the console. I have succeeded in otuputting some unicode characters such as \u263B (☻), but others such as \u2638 (☸) will just end up as question marks(?).

Here's the relevant code I use for output.

// Container of room information

struct RoomInfo
{
    wchar_t * layout;
    int width;
    int height;
};

// The following function builds RoomInfo 

RoomInfo Room::examine(IActor * examinor)
{
    RoomInfo ri;
    ri.width = this->width;
    ri.height = this->height;
    ri.layout = new wchar_t[height * width];
    for(unsigned int y = 0; y < height; y++)
    {
        for(unsigned int x = 0; x < width; x++)
        {
         ri.layout[y*width + x] = L'\u263B'; // works
         //ri.layout[y*width + x] = L'\u2638'; // will not work
        }
    }
}

// The following function outputs RoomInfo

void CursesConsole::printRoom(RoomInfo room)
{
    int w = room.width;
    int h = room.height;

    WINDOW * mapw = newwin(h, w, 1, 0);
    for(int y = 0; y < h; y++)
    {
        wmove(mapw, y, 0);
        for(int x = 0; x < w; x++)
        {
         int c = y*w + x;
         waddch(mapw, room.layout[c]);
        }
    }

    wrefresh(mapw);
    delwin(mapw);
}

I could of course fall back on boring ANSI-characters. But it would be really awesome to have the complete unicode-set of characters to play with.

To sum it up: How do you make sure that unicode characters are outputted correctly?


Edit:

Ok, so I figured out my encoding is working correctly. The problem is that I need to force the terminal to switch to a more unicode-rich font face. Is there a cross-platform way to do this? is there even a windows specific way to do this?

+1  A: 

In principle, all unicode characters are supported on the console. The fact that you're seeing question marks probably has to do with font support for those characters. Try switching the console font to something with very good unicode support.

JSBangs
Would I have to rely on the user to do this? Or can I force-change the font inside the application?
Morningcoffee
+1, this was indeed the scenario, although the solution only works on the dev-machine :/
Morningcoffee
+2  A: 

You need to set the code page properly. There's a pretty good article about that here: link

Aaron
I don't like using platform specific methods, but I tried using `SetConsoleCP(65001);` to get UTF-8... didn't work.
Morningcoffee
+1  A: 

The problem is that I need to force the terminal to switch to a more unicode-rich font face. Is there a cross-platform way to do this? is there even a windows specific way to do this?

I had a look for this, but couldn't find a Windows API call to do it (which may just mean I didn't find it, of course). I would not expect to find a cross-platform way to do it.

The best solution I can think of is to launch the console using a specially constructed Shell Link (.LNK) file. If you read the file format documentation, you'll see that it allows you to specify a font.

But your problems don't end there. A Western locale install of Windows provides Lucida Console, but that font only provides a limited subset of graphemes. I assume that you can output/input Japanese text in the console on a Japanese Windows PC. You'd need to check what is available on a Japanese Windows if you wanted to be sure it would work there.

Linux (Ubuntu, at least) seems to have much better support here, using UTF-8 and providing a font with broad grapheme support. I haven't checked other distros to see what the story is there, nor have I checked how fonts are resolved in the terminal (whether it's an X thing, a Gnome thing or whatever).

McDowell
I haven't tried creating a Shell link yet, since we had to fight off some bugs. But this reply answers my questions well. Thanks :)
Morningcoffee