操作系统和实现独立访问键盘?

时间:2021-08-29 12:09:36

I made an FPS game with MSVC++ which is running very well on Windows. But now I am trying to make it portable (at least I want to create a linux and a Windows version), so I decided to change the IDE to Code::Blocks and the framework to wxWidgets. But it seems the virtual key codes and scan codes are different on different systems.

我用MSVC ++做了一个FPS游戏,它在Windows上运行得很好。但现在我试图让它变得可移植(至少我想创建一个Linux和Windows版本),所以我决定将IDE更改为Code :: Blocks,将框架更改为wxWidgets。但似乎虚拟键码和扫描码在不同系统上是不同的。

Earlier I experienced that the virtual keycodes may be different even on the same operating system but different computer (I got bug reports about they unable to control the character (depending on the numlock state, lol, not joke), which is fixed when change the code to use scancodes instead of virtkey codes) (edit: with wxWidgets both virtkey and scan codes on the numpad has different values depending on numlock state, bang!)

之前我曾经历过,即使在同一个操作系统上,虚拟键码也可能不同,但是计算机不同(我得到了关于他们无法控制角色的bug报告(取决于numlock状态,lol,而不是笑话),这在修改时是固定的代码使用扫描码而不是virtkey代码)(编辑:使用wxWidgets,numpad上的virtkey和扫描码都有不同的值,具体取决于numlock状态,砰!)

Now with wxWidgets it seems the wxKeyEvent::GetRawKeyCode and the code obtained earlier from WM_KEYDOWN's lParam are different. And I also get a completely different scan code on linux (ubuntu) from GetRawKeyCode.

现在使用wxWidgets,似乎wxKeyEvent :: GetRawKeyCode和之前从WM_KEYDOWN的lParam获得的代码是不同的。我还从GetRawKeyCode获得了一个完全不同的linux(ubuntu)扫描代码。

Well I can make my own scan code table by pressing all the keys and seeing what code it gives, but the only problem that ubuntu runs on my laptop, and the laptop does not have a full keyboard... But I need all of them to make Control Settings work.

好吧,我可以通过按下所有键并查看它给出的代码来制作我自己的扫描码表,但是ubuntu在我的笔记本电脑上运行的唯一问题是,笔记本电脑没有全键盘...但我需要所有这些使控制设置工作。

So the question: Is there a standard and cross-platform way to get the same code for the same key (the key at the same position to be more precise)? (at least on windows and linux)

所以问题是:是否有一种标准的跨平台方式来获得相同密钥的相同代码(相同位置的密钥更精确)? (至少在Windows和Linux上)

5 个解决方案

#1


In case you haven't considered it already, you might be able to use SDL.

如果您尚未考虑它,您可能可以使用SDL。

#2


This being an FPS, the lower-level graphics toolkit you are using makes a huge difference (I'm assuming that you're not writing 3d graphics in wxWidgets). If you're using OpenGL, have you looked at what GLUT can do?

这是一个FPS,你正在使用的低级图形工具包产生了巨大的差异(我假设你没有在wxWidgets中编写3d图形)。如果您正在使用OpenGL,您是否看过GLUT可以做什么?

The glutKeyboardFunc and glutSpecialFunc combined with glutGetModifiers could be sufficient for cross-platform keyboard code, and GLUT can even be used for other input devices.

glutKeyboardFunc和glutSpecialFunc与glutGetModifiers相结合可能足以用于跨平台键盘代码,而GLUT甚至可以用于其他输入设备。

To be honest though, I still don't see how this could possibly have anything to do with wxWidgets.

说实话,我仍然没有看到这可能与wxWidgets有什么关系。

#3


My opinion is that it's completely wrong to use wxWidgets to code fast-paced 3D games. In "hardcore" game development,you should use it to develop supporting tools, such as editors and converters.

我的观点是,使用wxWidgets编写快节奏的3D游戏是完全错误的。在“硬核”游戏开发中,您应该使用它来开发支持工具,例如编辑器和转换器。

SDL is the way to go. It may seem quite basic, but once you start sacrificing small children to the unholy gods of SDL, stuff like SDL_image (perfect for reading numerous image file formats - to the extent I sometimes use SDL solely to read e.g. JPEG) or SDL_mixer (sole solution you need for reading and playing basic audio - OGG, WAV, ...).

SDL是要走的路。这看起来很基本,但是一旦你开始牺牲小孩到SDL的邪恶之神,像SDL_image(非常适合阅读大量图像文件格式 - 我有时只使用SDL阅读例如JPEG)或SDL_mixer(唯一的解决方案)你需要阅读和播放基本音频 - OGG,WAV,...)。

So look no further than SDL. Even the 2D graphics support is good once you start using SDL_gfx. SDL may at first seem basic, but once you count in all the extra libraries built around it, and once you code a few wrappers around it, you'll see SDL is the perfect balance between bare necessities and ease of advanced use.

所以请看SDL。一旦开始使用SDL_gfx,即使是2D图形支持也是如此。 SDL可能起初看起来很基本,但是一旦你计算了围绕它构建的所有额外的库,并且一旦你编写了几个包装器,你就会发现SDL是在必需品和易于高级使用之间的完美平衡。

I'll be happy to assist you in any way with SDL since I find it so awesome.

我很乐意以任何方式帮助您使用SDL,因为我发现它非常棒。

#4


I might be misunderestimating what your seeing here, but looking at the raw keycode returned is going to result in hardware, os, configuration and platform differences, so you should be looking at the virtual keycode returned by a key event.

我可能会误解你在这里看到的内容,但是查看返回的原始密钥代码会导致硬件,操作系统,配置和平台差异,因此您应该查看关键事件返回的虚拟键代码。

EDIT: Maybe wxWidgets just doesn't handle it right (doubtful) . The issue of the numlock key is "forcing" you to work around this (poorly) by using the raw scan code.

编辑:也许wxWidgets只是没有正确处理(可疑)。 numlock键的问题是“强迫”你使用原始扫描代码来解决这个问题(糟糕)。

If that's the case you don't need to throw away what you've done, but if you add SDL just for the input stuff, you'll find calls which return the SDL_keysym don't just return the hardware scancode (which you can do nothing about "fixing") but also map it to a unicode character and a virtual symbol, which is I think what you're looking for. Hopefully their calls don't have this numlock modifier problem.

如果是这种情况你不需要丢弃你所做的事情,但是如果你只为输入内容添加SDL,你会发现返回SDL_keysym的调用不只是返回硬件扫描码(你可以什么都不做“修复”),但也把它映射到一个unicode字符和一个虚拟符号,这就是我想你要找的东西。希望他们的调用没有这个numlock修饰符问题。

#5


If you don't wan't to use SDL, I recommend SFML - Simple and Fast Multimedia Library. It is multiplatform and really simple to use. For example, from tutorials section:

如果您不想使用SDL,我推荐使用SFML - 简单快速多媒体库。它是多平台的,使用起来非常简单。例如,从教程部分:

bool         LeftKeyDown     = Input.IsKeyDown(sf::Key::Left);
bool         RightButtonDown = Input.IsMouseButtonDown(sf::Mouse::Right);
bool         Joy0Button1Down = Input.IsJoystickButtonDown(0, 1);
unsigned int MouseX          = Input.GetMouseX();
unsigned int MouseY          = Input.GetMouseY();
float        Joystick1X      = Input.GetJoystickAxis(1, sf::Joy::AxisX);
float        Joystick1Y      = Input.GetJoystickAxis(1, sf::Joy::AxisY);
float        Joystick1POV    = Input.GetJoystickAxis(1, sf::Joy::AxisPOV);

where Input is

输入在哪里

const sf::Input& Input = App.GetInput();

There are some indications that SFML is faster than SDL, however I tend to use it to whip out fast and portable code since I like its usage more than SDL.

有一些迹象表明SFML比SDL更快,但是我倾向于使用它来甩掉快速和可移植的代码,因为我喜欢它的用法而不是SDL。

#1


In case you haven't considered it already, you might be able to use SDL.

如果您尚未考虑它,您可能可以使用SDL。

#2


This being an FPS, the lower-level graphics toolkit you are using makes a huge difference (I'm assuming that you're not writing 3d graphics in wxWidgets). If you're using OpenGL, have you looked at what GLUT can do?

这是一个FPS,你正在使用的低级图形工具包产生了巨大的差异(我假设你没有在wxWidgets中编写3d图形)。如果您正在使用OpenGL,您是否看过GLUT可以做什么?

The glutKeyboardFunc and glutSpecialFunc combined with glutGetModifiers could be sufficient for cross-platform keyboard code, and GLUT can even be used for other input devices.

glutKeyboardFunc和glutSpecialFunc与glutGetModifiers相结合可能足以用于跨平台键盘代码,而GLUT甚至可以用于其他输入设备。

To be honest though, I still don't see how this could possibly have anything to do with wxWidgets.

说实话,我仍然没有看到这可能与wxWidgets有什么关系。

#3


My opinion is that it's completely wrong to use wxWidgets to code fast-paced 3D games. In "hardcore" game development,you should use it to develop supporting tools, such as editors and converters.

我的观点是,使用wxWidgets编写快节奏的3D游戏是完全错误的。在“硬核”游戏开发中,您应该使用它来开发支持工具,例如编辑器和转换器。

SDL is the way to go. It may seem quite basic, but once you start sacrificing small children to the unholy gods of SDL, stuff like SDL_image (perfect for reading numerous image file formats - to the extent I sometimes use SDL solely to read e.g. JPEG) or SDL_mixer (sole solution you need for reading and playing basic audio - OGG, WAV, ...).

SDL是要走的路。这看起来很基本,但是一旦你开始牺牲小孩到SDL的邪恶之神,像SDL_image(非常适合阅读大量图像文件格式 - 我有时只使用SDL阅读例如JPEG)或SDL_mixer(唯一的解决方案)你需要阅读和播放基本音频 - OGG,WAV,...)。

So look no further than SDL. Even the 2D graphics support is good once you start using SDL_gfx. SDL may at first seem basic, but once you count in all the extra libraries built around it, and once you code a few wrappers around it, you'll see SDL is the perfect balance between bare necessities and ease of advanced use.

所以请看SDL。一旦开始使用SDL_gfx,即使是2D图形支持也是如此。 SDL可能起初看起来很基本,但是一旦你计算了围绕它构建的所有额外的库,并且一旦你编写了几个包装器,你就会发现SDL是在必需品和易于高级使用之间的完美平衡。

I'll be happy to assist you in any way with SDL since I find it so awesome.

我很乐意以任何方式帮助您使用SDL,因为我发现它非常棒。

#4


I might be misunderestimating what your seeing here, but looking at the raw keycode returned is going to result in hardware, os, configuration and platform differences, so you should be looking at the virtual keycode returned by a key event.

我可能会误解你在这里看到的内容,但是查看返回的原始密钥代码会导致硬件,操作系统,配置和平台差异,因此您应该查看关键事件返回的虚拟键代码。

EDIT: Maybe wxWidgets just doesn't handle it right (doubtful) . The issue of the numlock key is "forcing" you to work around this (poorly) by using the raw scan code.

编辑:也许wxWidgets只是没有正确处理(可疑)。 numlock键的问题是“强迫”你使用原始扫描代码来解决这个问题(糟糕)。

If that's the case you don't need to throw away what you've done, but if you add SDL just for the input stuff, you'll find calls which return the SDL_keysym don't just return the hardware scancode (which you can do nothing about "fixing") but also map it to a unicode character and a virtual symbol, which is I think what you're looking for. Hopefully their calls don't have this numlock modifier problem.

如果是这种情况你不需要丢弃你所做的事情,但是如果你只为输入内容添加SDL,你会发现返回SDL_keysym的调用不只是返回硬件扫描码(你可以什么都不做“修复”),但也把它映射到一个unicode字符和一个虚拟符号,这就是我想你要找的东西。希望他们的调用没有这个numlock修饰符问题。

#5


If you don't wan't to use SDL, I recommend SFML - Simple and Fast Multimedia Library. It is multiplatform and really simple to use. For example, from tutorials section:

如果您不想使用SDL,我推荐使用SFML - 简单快速多媒体库。它是多平台的,使用起来非常简单。例如,从教程部分:

bool         LeftKeyDown     = Input.IsKeyDown(sf::Key::Left);
bool         RightButtonDown = Input.IsMouseButtonDown(sf::Mouse::Right);
bool         Joy0Button1Down = Input.IsJoystickButtonDown(0, 1);
unsigned int MouseX          = Input.GetMouseX();
unsigned int MouseY          = Input.GetMouseY();
float        Joystick1X      = Input.GetJoystickAxis(1, sf::Joy::AxisX);
float        Joystick1Y      = Input.GetJoystickAxis(1, sf::Joy::AxisY);
float        Joystick1POV    = Input.GetJoystickAxis(1, sf::Joy::AxisPOV);

where Input is

输入在哪里

const sf::Input& Input = App.GetInput();

There are some indications that SFML is faster than SDL, however I tend to use it to whip out fast and portable code since I like its usage more than SDL.

有一些迹象表明SFML比SDL更快,但是我倾向于使用它来甩掉快速和可移植的代码,因为我喜欢它的用法而不是SDL。