• HHKBをAXキーボードレイアウトで使っているFF14プレイヤーの話

    2015年01月13日 20時28分
    この記事はタイトルに関係無い人には全く役に立たない内容と予めお知らせしておきます。

    問題

    FINAL FANTASY XIVでパッチ2.4アップデート以降、
    半角/全角キー押下でAltキーが押されたままの状態になる。

    ∧∧∧∧∧∧∧∧∧∧      ___/ ̄ ̄ ̄\
    < ┌┐  ┌───┐ >   /  / / ̄ ̄ ̄ ̄\
    < ││  └──┐│ >  /    ̄          \
    < ││  ┌──┘│ >/    □            \
    < ││  └──┐│ >// ̄~\ / ̄ ̄ ̄\      |
    < ││  ┌──┘│ >|//\ヽ ∨〃/\   \   /\
    < ││  └───┘ >//(・) \ゞ/ /(・)  〉   |  | ∩|
    < ││           >| \_/ノ  \_/ ノ し|:   | ∪|
    < ││   □   _  >l:::::::::∠~         ⌒ |   \/
    < ││   □  //  >|:::::::::r~~‐、ヽ      /   /
    < ││     //   >|:::::::::)jjjjjjjjjjjヽヽ   /   /
    <   ̄    //     >|:::::::::|,,    || /   /
    <.  ロロ┌┐ ̄ _ □□ >!:::: ヽiiiiiiiii//  /   /
    <   ┌┘│  / /     >ヽ  ヽ~~"/   /
    <     ̄ ̄  /  ̄ ̄フ  > ヽ、__,,,_∠__/
    < ┌┐┌┐ / /ニ/ /  >  _]:::::::   [_
    < ││││/┌っ /   > ̄~        ゙ ̄ ̄ ̄ ̄ヽ
    < ││││ ̄ / /    >               ,~ヽ
    < └┘└┘  / /      >             ~ ノ ̄\
    <   []  []    ̄       >           ’ノ⌒⌒⌒⌒



    原因

    HHKB Professional2をAXキーボードレイアウトで使っているためと思われる。

    AXキーボードレイアウトというのは、基本的にUSレイアウトのキーボードとして使えるが
    右Altキーを半角/全角キーとして使えるようになる設定。

    おそらくFF14のキー情報取得はスキャンコードを取っているが、
    IMEがONになったときにそのキーのUPを取りこぼすようなバグがあるんだと思う。

    Altキーは各種ショートカットで頻繁に使うので押しっぱ状態だと色々と困る。


    対応

    一応公式に不具合報告は出しているが、未だに修正されないし修正されるのかもわからないので自分で対応する。

    ちなみに私はWindowsのキーボードがどういう仕様で動いているかよく知らないし、
    こんな全国でも数人レベルしか困っていない問題に労力を割くのも馬鹿らしいので
    理論や理屈はかなり適当だと断っておく。動けば良い。
    あと文章もほぼ自分用のメモ代わりなので結構雑になるとも断っておく。


    周りに同様の現象で困っているような人は居ないので、半角/全角キーのスキャンコードのキーに半角/全角キーのレイアウトを割り当てれば良いっぽい。
    たぶんゲーム内部的には半角/全角キーのスキャンコード(0x0029)が押しっぱになっていると思うのだが、
    そのキーはIMEのON/OFFにしか使わないので表に問題として出てきてないんだと思う。

    なので、まずはキーボードのレイアウトをを日本語106キー(kbd106.dll)に戻す。
    基本的には日本語のWindowsは最初これになっていると思う。

    そうすると、HHKBの右上のキー(`キー)が半角/全角キーになるので、
    レジストリのスキャンコードの設定を変えて、右Altがこのキーになるように設定すればよい。
    ついでに同じキーが2個あっても仕方ないので、右上のキー(`キー)を日本語キーボードの|キーに変更する。

    つまりこうなる
    • 右Altキー(スキャンコード=0xe038) → 半角/全角キー(スキャンコード=0x0029)
    • 半角/全角キー(スキャンコード=0x0029) → |キー(スキャンコード=0x007d)


    ひとまずこれで右Altキーを押してIMEの切り替えが正常に行われるようになる。


    ただ、この状態だと基本的に日本語レイアウトなので、
    Shift+数字キーとか記号キーの辺りが違って非常に使いにくい。

    そこで、kbd106.dllのレイアウトを一部改造してUSレイアウトっぽくする。

    具体的にはkbd106.dllのソースがMicrosoft公式に置いてあるのでそれを取ってくる。
    (厳密には違うのかもしれないけどだいたい同じっぽいのでよしとする)

    このソースはVisual Studio 2013とWDK8.1をインストールすれば簡単にビルドできる。
    (両方とも同じくMicrosoft公式からダウンロード出来る。)


    C++/fe_kbds/jpn/106の、キーボードレイアウトを設定してるっぽいところを
    適度にエスパーしつつ書き換える。

    --- kbd106.c    2015-01-13 20:23:39.000000000 +0900
    +++ kbd106mod.c 2015-01-13 20:26:22.739691347 +0900
    @@ -237,14 +237,14 @@
     static ALLOC_SECTION_LDATA VK_TO_WCHARS4 aVkToWch4[] = {
         //                               |          |   SHIFT  |  KANA  | K+SHFT |
         //                               |          |==========|========|========|
    -    {'0'          ,          KANALOK ,'0'       ,WCH_NONE  ,WCH_WA  ,WCH_WO  },
    +    {'0'          ,          KANALOK ,'0'       ,')'       ,WCH_WA  ,WCH_WO  },
         {'1'          ,          KANALOK ,'1'       ,'!'       ,WCH_NU  ,WCH_NU  },
         {'3'          ,          KANALOK ,'3'       ,'#'       ,WCH_A   ,WCH_AA  },
         {'4'          ,          KANALOK ,'4'       ,'$'       ,WCH_U   ,WCH_UU  },
         {'5'          ,          KANALOK ,'5'       ,'%'       ,WCH_E   ,WCH_EE  },
    -    {'7'          ,          KANALOK ,'7'       ,0x27      ,WCH_YA  ,WCH_YAA },
    -    {'8'          ,          KANALOK ,'8'       ,'('       ,WCH_YU  ,WCH_YUU },
    -    {'9'          ,          KANALOK ,'9'       ,')'       ,WCH_YO  ,WCH_YOO },
    +    {'7'          ,          KANALOK ,'7'       ,'&'       ,WCH_YA  ,WCH_YAA },
    +    {'8'          ,          KANALOK ,'8'       ,'*'       ,WCH_YU  ,WCH_YUU },
    +    {'9'          ,          KANALOK ,'9'       ,'('       ,WCH_YO  ,WCH_YOO },
         {'A'          , CAPLOK | KANALOK ,'a'       ,'A'       ,WCH_TI  ,WCH_TI  },
         {'B'          , CAPLOK | KANALOK ,'b'       ,'B'       ,WCH_KO  ,WCH_KO  },
         {'C'          , CAPLOK | KANALOK ,'c'       ,'C'       ,WCH_SO  ,WCH_SO  },
    @@ -271,14 +271,14 @@
         {'X'          , CAPLOK | KANALOK ,'x'       ,'X'       ,WCH_SA  ,WCH_SA  },
         {'Y'          , CAPLOK | KANALOK ,'y'       ,'Y'       ,WCH_NN  ,WCH_NN  },
         {'Z'          , CAPLOK | KANALOK ,'z'       ,'Z'       ,WCH_TU  ,WCH_TUU },
    -    {VK_OEM_1     ,          KANALOK ,':'       ,'*'       ,WCH_KE  ,WCH_KE  },
    +    {VK_OEM_1     ,          KANALOK ,'\''      ,'"'       ,WCH_KE  ,WCH_KE  },
         {VK_OEM_2     ,          KANALOK ,'/'       ,'?'       ,WCH_ME  ,WCH_MD  },
    -    {VK_OEM_3     ,          KANALOK ,'@'       ,'`'       ,WCH_VS  ,WCH_VS  },
    -    {VK_OEM_7     ,          KANALOK ,'^'       ,'~'       ,WCH_HE  ,WCH_HE  },
    +    {VK_OEM_3     ,          KANALOK ,'['       ,'{'       ,WCH_VS  ,WCH_VS  },
    +    {VK_OEM_7     ,          KANALOK ,'='      ,'+'        ,WCH_HE  ,WCH_HE  },
         {VK_OEM_8     , 0                ,WCH_NONE  ,WCH_NONE  ,WCH_NONE,WCH_NONE},
         {VK_OEM_COMMA ,          KANALOK ,','       ,'<'       ,WCH_NE  ,WCH_IC  },
         {VK_OEM_PERIOD,          KANALOK ,'.'       ,'>'       ,WCH_RU  ,WCH_IP  },
    -    {VK_OEM_PLUS  ,          KANALOK ,';'       ,'+'       ,WCH_RE  ,WCH_RE  },
    +    {VK_OEM_PLUS  ,          KANALOK ,';'       ,':'       ,WCH_RE  ,WCH_RE  },
         {VK_TAB       , 0                ,'\t'      ,'\t'      ,'\t'    ,'\t'    },
         {VK_ADD       , 0                ,'+'       ,'+'       ,'+'     ,'+'     },
         {VK_DECIMAL   , 0                ,'.'       ,'.'       ,'.'     ,'.'     },
    @@ -294,10 +294,10 @@
         {VK_BACK      , 0       ,'\b'      ,'\b'      ,'\b'    ,'\b'    , 0x7f      , 0x7f      },
         {VK_CANCEL    , 0       ,0x03      ,0x03      ,0x03    ,0x03    , 0x03      , 0x03      },
         {VK_ESCAPE    , 0       ,0x1b      ,0x1b      ,0x1b    ,0x1b    , 0x1b      , 0x1b      },
    -    {VK_OEM_4     , KANALOK ,'['       ,'{'       ,WCH_SVS ,WCH_OB  , 0x1b      , 0x1b      },
    -    {VK_OEM_5     , KANALOK ,'\\'      ,'|'       ,WCH_PS  ,WCH_PS  , 0x1c      , 0x1c      },
    +    {VK_OEM_4     , KANALOK ,']'       ,'}'       ,WCH_SVS ,WCH_OB  , 0x1b      , 0x1b      },
    +    {VK_OEM_5     , KANALOK ,'`'       ,'~'       ,WCH_PS  ,WCH_PS  , 0x1c      , 0x1c      },
         {VK_OEM_102   , KANALOK ,'\\'      ,'_'       ,WCH_RO  ,WCH_RO  , 0x1c      , 0x1c      },
    -    {VK_OEM_6     , KANALOK ,']'       ,'}'       ,WCH_MU  ,WCH_CB  , 0x1d      , 0x1d      },
    +    {VK_OEM_6     , KANALOK ,'\\'      ,'|'       ,WCH_MU  ,WCH_CB  , 0x1d      , 0x1d      },
         {VK_RETURN    , 0       ,'\r'      ,'\r'      ,'\r'    ,'\r'    , '\n'      , '\n'      },
         {VK_SPACE     , 0       ,' '       ,' '       ,' '     ,' '     , 0x20      , 0x20      },
         {0            , 0       ,0         ,0         ,0       ,0       , 0         , 0         }
    @@ -306,9 +306,9 @@
     static ALLOC_SECTION_LDATA VK_TO_WCHARS8 aVkToWch8[] = {
         //                      |          |   SHIFT  |  KANA  | K+SHFT |  CONTROL  |  K+CTRL   | SHFT+CTRL |K+SHFT+CTRL|
         //                      |          |==========|========|========|===========|===========|===========|===========|
    -    {'2'          , KANALOK ,'2'       ,'"'       ,WCH_HU  ,WCH_HU  , WCH_NONE  , WCH_NONE  , 0x00      , 0x00      },
    -    {'6'          , KANALOK ,'6'       ,'&'       ,WCH_O   ,WCH_OO  , WCH_NONE  , WCH_NONE  , 0x1e      , 0x1e      },
    -    {VK_OEM_MINUS , KANALOK ,'-'       ,'='       ,WCH_HO  ,WCH_HO  , WCH_NONE  , WCH_NONE  , 0x1f      , 0x1f      },
    +    {'2'          , KANALOK ,'2'       ,'@'       ,WCH_HU  ,WCH_HU  , WCH_NONE  , WCH_NONE  , 0x00      , 0x00      },
    +    {'6'          , KANALOK ,'6'       ,'^'       ,WCH_O   ,WCH_OO  , WCH_NONE  , WCH_NONE  , 0x1e      , 0x1e      },
    +    {VK_OEM_MINUS , KANALOK ,'-'       ,'_'       ,WCH_HO  ,WCH_HO  , WCH_NONE  , WCH_NONE  , 0x1f      , 0x1f      },
         {0            , 0       ,0         ,0         ,0       ,0       , 0         , 0         , 0         , 0         }
     };


    書き換えたらビルドしてdllを設定すればよい。
    (上書きは怖いので別の名前で設定したほうがいいと思う。)

    コメントを書く

    名前
    本文
    編集用パスワード
    管理者のみ閲覧