AZO234 / NP2kai

Neko Project II kai
http://domisan.sakura.ne.jp/article/np2kai/np2kai.html
MIT License
260 stars 61 forks source link

Fixed the key repeat problem on MS-DOS and N88-BASIC(86) with SDL port. #115

Closed miyamoto999 closed 3 years ago

miyamoto999 commented 4 years ago

SDLポートでMS-DOS、N88-BASIC(86)でキーリピートしないのをなおしてみました。 Windowsやゲームに影響ないかが心配。

I fixed the key repeat problem on MS-DOS and N88-BASIC(86) with SDL port. I'm worried about the problems with Windows and games.

AZO234 commented 4 years ago

Thank you! But this code couldn't fix key on Linux(Ubuntu 20.04's) SDL.

About 'key-repeat' on NP2, it seems realized by OS event. For example in Windows implementation, keystat_senddata() called by WM_KEYDOWN or UP event. I think 'key-repeat' must be implemented in keystat.c without depend on OSs/platforms.

Then, I implemented for SDL/libretro with keystat.c's keystat_keydown() and keystat_keyup(). Keyboard is one kind of HID. Down or up of keys states are gotten simply, and 'key-repeat' is realized by NP2 core. (And adjustable.)

miyamoto999 commented 4 years ago

おっしゃる通り、Windows(VS2019ビルド)、Xポートがそのように実装されていたのでSDL2のイベントを見てみるとWindowsと同じように発生していたのでプルリクエストしたような改修をしました。SDL2(Win/macOS/Linux)、Libretro(Win/macOS/Linux)は確認したのですが、SDL1での動作確認をしていませんでした。試してみたらSDL1(Linux)では動かなかったです。失礼しました。

さて、キーリピートを実装する上で挙動を整理してみた。1つのキー入力は想像通りシンプルで次のようになります。キーダウンで500ms間キーアップがなければキーリピート開始(リピート間隔は不明)、キーアップでリピート終了。

複数キー入力については、例えばaを押してリピート、bを押してリピート、bを離すと次のように入力されます(記憶が確かならば)

aaaaabbbbbbbbbaaaaa

これらから実装方法を考えると、キーダウンした順にバッファに積んでキーアップでバッファから削除する。500ms間キーアップがなければバッファに最後に積んだキーコードをリピートする。

イベントの処理はio/serial.cのkeyboard_send()関数に組み込むか、keyboard_send()関数を呼んでるところに入れるかのどちらか。 定期処理はメインループから呼んでやる。

こんな感じでどうでしょうか?


You are right.Windows (VS2019 build), the X-port was implemented that to do so, so I looked at the SDL2 events and found that they were occurring the same way as on Windows, so I modified them as I did the pull request.I checked SDL2 (Win/macOS/Linux) and Libretro (Win/macOS/Linux), but I didn't test it on SDL1. I tried it and it did not succeed with SDL1 (Linux).I'm sorry.

Well, I've tried to tidy up the behavior in implementing key repeats. One key input is as simple as imagined and goes like this. If there is no key-up for 500ms on key-down, start key repeat (repeat interval time unknown), and The repeat ends with a key up.

For multiple keystrokes, for example, press "a" and repeat, press "b" and repeat, and then release "b" to input the following. (if my memory serves)

aaaaabbbbbbbbbaaaaa

I think about how to implement it from these.Push them to the buffer in the order they are keyed down, and remove them from the buffer on key-up.If there is no key-up for 500ms, the last keycode in the buffer is repeated.

Event processing is implemented in the keyboard_send() function in io/serial.c,or Implement it in the place where the keyboard_send() function is called.

The interval process will be called from the main loop.

How about this?

AZO234 commented 4 years ago

ご意見をありがとうございます!

シリアル部分に何が流れているか、は具体的にはわかりませんが、 キーリピートをすべき/すべきでないものを判別するために、 keystat.c 内に実装すると判別がしやすいかと思います。

リピート用バッファはリスト構造になる必要があるかもしれませんね。 リストに積んだ最後尾をリピートするような・・・。 A長押し(aaa)→B長押し(bbb)→C長押し(ccc)→ 1.A解放(ccc)→B解放(ccc)→C解放(終わり) 2.C解放(bbb)→B解放(aaa)→A解放(終わり)

「キーリピート有効/無効」を選択するオプションとその分岐も、 pccore.c + ini.c に加えたいですね。 (オプション機能部分は、私の方に投げてOKです。)

いかがでしょうか? すべて日本語にて失礼しました。

miyamoto999 commented 4 years ago

配列でもいいかな?と思っていたんですが、リンクリストみたいにした方がいいですかね?

キーリピート用のバッファは指は10本なので10個程度で、途中の要素を削除で詰める処理を行っても数バイトなのでいいかと。(key.txtのことを考えるとバッファサイズは少し増やさないといけないですが、どれくらいがいいでしょうかね?)

I was thinking "Am I allowed to use an array?",but Should I implement it like a link-list?

The buffer for key repeats is about 10 because there are 10 fingers, I think it's good because it's only a few bytes even if you remove the elements in the middle and pack them in.(I need to increase the buffer size a bit, considering the key.txt thing, but how much is better?)

AZO234 commented 4 years ago

(「攻殻機動隊」のあの入力補助ギミック・・・とか思い浮かべました。 やる人はシリアルに直にズドンと入れると思いますw) 指10本、転じて16要素もあればいいでしょうかね。 16番目のキーはもうバッファに乗せないカンジですね。

いかがでしょうか? 宜しくお願い致します。

miyamoto999 commented 4 years ago

「数バイトなので」は「数バイトのコピーなので」の間違いです。

(あの指を考えるとたくさん・・・ 同時押しはほとんどしてないはずなので問題ないでしょう😀)

AZO234 commented 4 years ago

ご返答ありがとうございます。 他力本願で申し訳ございませんが、ご検討をお願い致します。😅 何か御座いましたら、お気軽にお尋ねくださいね。

miyamoto999 commented 4 years ago

直してみました。どうでしょう?

以下、macOS上での話です。 動作確認していてわかったんですが、キーボード自体の同時入力限界があります。 Appleのキーボードが6つ同時入力可能で、 うちにAppple以外のキーボードがいくつかあるのですが、それらのキーボードでは4つ同時入力、キーの組み合わせによっては2つしか入力できない。 また、うちにある一部キーボードで同時入力限界を超えたあとのキーをリリースするとそれ以外の押し続けてるキーが一度upとdownが発生するしたり、場合によっては押し続けてる複数キーのup、downが繰り返し発生したりします。

このあたりはどうすることもできなさそうなので何も策を講じていません。

あっ、macOS以外はそこまで細かく確認していません。💦

AZO234 commented 3 years ago

I could test on Linux with SDL1,2 and libretro. Great work! 😂 I'll add interface of this feature.

完璧な仕事です!お疲れ様です! マージさせて頂きます。