Closed Ancurio closed 9 years ago
Ait, just committed it, seems to work fine: 4a8b0f30c8dfc59deb3a4b30ae6a845121e3f701
(Small change: raw_key_states
is in MKXP
module instead of System
)
I built mkxp from git and got your wrapper script from here: http://pastebin.com/zXW1hdrx
Then tried to start Sin Unsullied (http://legacyblade.com/downloads/SinUnsullied/SinUnsullied_B002.zip), which uses the Blizzard ABS script, and after fixing the usual syntax issues, I got this error:
[user32:GetKeyboardLayout] [0]
win32_wrap.rb:228:in `call': undefined method `WIN32' for Scancodes:Module (NoMethodError)
from win32_wrap.rb:321:in `call'
from 107:Blizz-ABS Part 2:7532:in `update'
from 101:Tons of Addons Part 2:695:in `block in main'
from 101:Tons of Addons Part 2:693:in `loop'
from 101:Tons of Addons Part 2:693:in `main'
from 108:Blizz-ABS Part 3:6715:in `main'
from 131:Main:15:in `<main>'
Is it supposed to work out of the box or it still needs some changes to the used scripts?
Thanks a lot for adding this Win32API emulation, by the way :)
@openmac I have fixed all syntax errors I saw, please try again.
Thanks, I download the updated win32_wrap.rb from pastebin and here is the new error:
[user32:GetKeyboardLayout] [0]
win32_wrap.rb:230:in `block in call': undefined method `contains' for #<Hash:0x0000010211d6d8> (NoMethodError)
from win32_wrap.rb:228:in `each'
from win32_wrap.rb:228:in `call'
from win32_wrap.rb:321:in `call'
from 107:Blizz-ABS Part 2:7532:in `update'
from 101:Tons of Addons Part 2:695:in `block in main'
from 101:Tons of Addons Part 2:693:in `loop'
from 101:Tons of Addons Part 2:693:in `main'
from 108:Blizz-ABS Part 3:6715:in `main'
from 131:Main:15:in `<main>'
@openmac: Try replacing contains
in line 230 with key?
.
Thanks, here is the new error:
[user32:GetKeyboardLayout] [0]
win32_wrap.rb:236:in `block in call': undefined method `setbyte' for #<Array:0x0000010217e870> (NoMethodError)
from win32_wrap.rb:228:in `each'
from win32_wrap.rb:228:in `call'
from win32_wrap.rb:321:in `call'
from 107:Blizz-ABS Part 2:7532:in `update'
from 101:Tons of Addons Part 2:695:in `block in main'
from 101:Tons of Addons Part 2:693:in `loop'
from 101:Tons of Addons Part 2:693:in `main'
from 108:Blizz-ABS Part 3:6715:in `main'
from 131:Main:15:in `<main>'
Welp, blind fixing bug really wasn't a good idea. I have put up a new revision that works (tested).
Thanks, it now starts without any error but in the game's initial screen that asks whether to choose Full Screen or not, no matter what key I press, it does not seem to be registered, so it is stuck there.
New version up.
It works now :) There are other problems that I think they do not have anything to do with the keyboard and are issues with the game scripts Ruby 1.8.x syntax. Thanks again.
Edit: I fixed the game scripts syntax issues and it seems to work perfectly, you are awesome!
here's my current win32api wrapper script that makes use of it.
Any reason this wrapper isn't part of the Git repo? (And independently of that, what's the license for that wrapper? Same as mkxp itself?)
@JeremyRand the reason is that I didn't consider it good quality code, just barely enough to make certain projects work. As for license, feel free to use it under CC0.
The following user32.dll functions are commonly used in scripts to query keyboard keys:
GetKeyState: Queries the current state of a key, and also whether keys such as caps lock are toggled on
GetAsyncKeyState Queries the current state, but also reports whether the key was pressed inbetween calls (so key presses are never missed due to timing)
GetKeyboardState: Like
GetKeyState
, but copies the state of all virtual key codes into a 256 byte arrayThe first two functions take Virtual Key Codes as parameters, which from what I understand, act similarly to SDL scancodes (ie. raw identifiers of physical keys, unaffected by keyboard layouts). The first few codes represent the mouse buttons, which are already available via mkxp's Input module extensions.
The way to enable implementing these that I currently have in mind is this: A single new function (let's call it
raw_key_states
, either under theSystem
orInput
module) returns a 512 byte string into which all SDL scancode states are memcpied into. We already keep such a state array anyway, so the new code literally amounts to a few lines.For
GetKeyState
, we just translate the windows key code to the corresponding SDL one and return the byte in the array. I'm not sure if it's worth to do extra work for the specialGetAsyncKeyState
behavior of not missing events; in practice, the RGSS Input functions act likeGetKeyState
too. As for the state of toggled keys (capslock, numlock etc.), I don't think anyone makes use of this so it's not worth considering either. One thing I'm not sure of yet is how often to retrieve the raw SDL keystate array. In my current code I hook into Graphics.update and refresh one shared array there once per frame. I assume that a game that doesn't callGraphics.update
very often or not at all cannot do anything useful anyway, so that shouldn't lead to complications where script code expects completely fresh key states.For
GetKeyboardState
one would just iterate through all available Windows Key Codes and write the result ofGetKeyState
into the provided string buffer.Here's the tentative patch for mkxp to implement
raw_key_states
, and here's my current win32api wrapper script that makes use of it.If you have any comments / ideas / suggestions, please post them!