I have been trying out Irrlicht for a couple of weeks now both
in Linux and Windows and I must say that I am impressed by the
easy interfaces and how fast I actually could get something up
and running on both windows and linux.
I just wanted to post a few things that I have found and couldnt find
in the various topics, I dont know where to put it so I guess here
is just as good as any place. Note, that I'm new to irrlicht and
might not have understood how some features actually are supposed
to work so I just changed them to work as I feelt was apropriate.
1) I have updated the key event handling somewhat in CIrrDeviceLinux.
It is still not complete but at least it gives a decent result for me
and works better than before
In createKeymap() I added:
// Some more keys..
KeyMap.push_back(SKeyMap(XK_braceleft,0)); //?
KeyMap.push_back(SKeyMap(XK_braceright,0)); // ?
KeyMap.push_back(SKeyMap(XK_parenright, 0)); //?
KeyMap.push_back(SKeyMap(XK_Alt_L,KEY_MENU)); //Left Alt (KEY_MENU???)
KeyMap.push_back(SKeyMap(XK_Mode_switch,KEY_HANGUL)); // (kana,arabic,greek,hebrew,hangul??) (Just setting it to Hangul)
KeyMap.push_back(SKeyMap(XK_Multi_key,KEY_RWIN)); //Right win button on my keyboard..
KeyMap.push_back(SKeyMap(XK_Super_L,KEY_LWIN)); // Left win button on my keyboard
KeyMap.push_back(SKeyMap(XK_Num_Lock,KEY_NUMLOCK)); // Num lock....
KeyMap.push_back(SKeyMap(XK_KP_Home,KEY_HOME)); // Home on my keyboard...
KeyMap.push_back(SKeyMap(XK_Caps_Lock,KEY_CAPITAL)); // Caps lock...
In run():
I changed the code somewhat after case KeyPress:
// Its a bit messy, when it comes to toggle the .Char parameter and also
// the .Control & .Shift, probably solvable by adding a third parameter
// in SKeyMap that specifies what corresponding character the found entry
// should give but I havent given it much thought.
case KeyPress:
{
SKeyMap mp;
KeySym keysym;
int charcount;
char charbuff[8];
charcount = XLookupString(&event.xkey, charbuff,sizeof(charbuff),&keysym,0);
mp.X11Key = keysym;
s32 idx = KeyMap.binary_search(mp);
//printf("KeySym = %d\n",keysym);
if (idx != -1)
{
irrevent.EventType = irr::EET_KEY_INPUT_EVENT;
irrevent.KeyInput.Key = (EKEY_CODE)KeyMap[idx].Win32Key;
irrevent.KeyInput.PressedDown = (event.type == KeyPress);
irrevent.KeyInput.Char = keysym;
irrevent.KeyInput.Control = (event.xkey.state&ControlMask)?true:false;
irrevent.KeyInput.Shift = (event.xkey.state&ShiftMask)?true:false;
// There are 6 more masks that can be used to match event.xkey.state,
// these are, LockMask (Caps lock), Mod1Mask(Left alt), Mod2Mask(Num lock),
// Mod3Mask(dont have a clue), Mod4Mask(left window button), Mod5Mask(Scroll lock)
// If Control or Shift is pressed, the control&shift mask wont be set so
// force the Control&Shift to be marked and reset the character.
if(irrevent.KeyInput.Key==KEY_CONTROL||
irrevent.KeyInput.Key==KEY_LCONTROL ||
irrevent.KeyInput.Key==KEY_RCONTROL)
{
irrevent.KeyInput.Control = true;
irrevent.KeyInput.Char = false;
}
if(irrevent.KeyInput.Key==KEY_SHIFT||
irrevent.KeyInput.Key==KEY_LSHIFT||
irrevent.KeyInput.Key==KEY_RSHIFT)
{
irrevent.KeyInput.Shift = true;
irrevent.KeyInput.Char = false;
}
/* Modify so that keyboard keys are mapped to actual ascii */
if(keysym >= XK_KP_Space && keysym <= XK_KP_9)
{
if(keysym >= XK_KP_F1 && keysym <= XK_KP_Delete)
{
irrevent.KeyInput.Char = false;
}
else
{
irrevent.KeyInput.Char = irrevent.KeyInput.Char & 0x007f;
}
}
else if(keysym==XK_Num_Lock || keysym == XK_Alt_L || keysym==XK_Mode_switch ||
keysym==XK_Multi_key || keysym == XK_Super_L || keysym == XK_Tab || keysym == XK_Caps_Lock)
{
irrevent.KeyInput.Char = false;
}
postEventFromUser(irrevent);
}
else
{
os::Printer::log("Could not find win32 key for x11 key.", ELL_WARNING);
}
}
break;
2) CGUIEditBox
I was doing some setText and noticed that the cursor always is set on the beginning
of the line which was the oposite side I wanted the cursor to be, easilly fixed by
Changing setText to take one more argument, like setText(const wchar_t* text,bool cursorAtEnd=false),
requires a few changes of IGUIElement and some other classes.
The other way to do it is to give IGUIEditBox a few more methods, like setCursorAt(...), etc..
3) CIrrDeviceLinux::createWindow(...)
I tried to fetch the list of possible resolutions by using the VideoModeList and noticed
that it is quite crippled in the linux implementation
As it is now, it seems like VideoModeList only will return the currently used
resolution.
for (; i<modeCount; ++i) {
printf("hdisplay=%d, vdisplay=%d\n",modes->hdisplay,modes->vdisplay);
if (modes->hdisplay == width &&
modes->vdisplay == height)
{
bestMode = i;
if (videoListEmpty)
VideoModeList.addMode(core::dimension2d<s32>(
modes->hdisplay, modes->vdisplay), 0);
}
}
Where width & height comes from the specified windowSize.
I also saw another thing further down in the code.
int visualAttrNoDoubleBuffer[]={...}
int visualAttrDoubleBuffer[] = {...}
int visualAttrDoubleStencilBuffer[] = {}
// get visual
XVisualInfo* visual = 0;
if (stencilbuffer)
{
visual = glXChooseVisual(display, screennr, visualAttrDoubleBuffer);
if (visual)
doublebuffer = true;
}
Shouldn't glXChooseVisual take visualAttrDoubleStencilBuffer instead?