tmytのらくがき

個人の日記レベルです

CsPscのフォローアップ記事です

久しぶりにアドベントカレンダーというものを書いたのですが、その時にC#をRoslynで解析し、ASTをPostScriptに落としてC#のようなプログラムをプリンタで実行できて楽しいね!!というジョークコンパイラを実装しました。

CSharp-PostScript Comiler 縮めてcspsc は、RoslynでASTをなめて、ツリーをPostScriptに変換するだけのもはやコンパイラか?といわれると怪しいやつです。かっこよく言うと、「C#向けのPostScriptバックエンド」です。かっこつけすぎました。 これは1200行ほどの1ファイルで実装されています。

github.com

アドベントカレンダーではプリンタでプログラムが実行できて楽しいね!!Roslyn便利だね!!ぐらいのところまでにとどめておいたのですが、そこそこちゃんと作ってあるコンパイラで、紹介していない機能がたくさんあったのでせっかくなのでフォローアップという形でこっちに放流します。

文中のコードはコンパイルが通ることを確認しているのでPostScriptにコンパイルしてあほだな~って眺めるのがいいかも1

組み込み属性

PostScriptをC#から生成するにあたって、PostScriptの全命令をC#マッピングするのがめちゃくちゃだるかったので属性でさぼったりしました。そのため、変な属性が2個だけ定義されています。

DllImportAttribute

DllImportAttribute自体は普通のC#にも存在しているんですが、このコンパイラはDllImportAttributeの解釈を大幅にさぼっているので本物より実装が雑です。具体的には、引数を全く解釈していません。

さらに、この属性はRoslynをごまかしてDiagnosisを正しく通過したうえでコンパイル時に関数名をPostScriptの命令に置換するためのマーカーでしかなく、関数名は常に ToLowerCase されます。

// たとえば
[DllImport("何を書いてもいい")]
extern static void ShowPage();

// 空はRoslynがエラーにするのでなんか書いてね
// [DllImport("")]
// extern static void sub();

[DllImport("🔢")]
extern static double Sqrt(double x);

[DllImport("関数名の大文字小文字がめちゃくちゃでもいい")]
extern static void MoVeTo(double x, double y);

PSFontAttribute

せっかくなのでフォントを設定したいと思います。ただ、こんなジョークコンパイラにおいてフォントなんて最初の1回だけ設定できれば十分すぎます。そのため、Assembly属性として設定することでなんかC#っぽい見た目になるな!ということで、Assembly属性を通してページのフォントを設定できます。

// PostScriptフォント名、フォントサイズで渡す
[assembly:PSFont("Courier", 12)]

組み込み関数

組み込み関数がいくつかあります。紹介するまでもないものとしてConsole.WriteLine, Console.Write のシノニムをイメージした WriteLine, Write がありますが本物と違いFormatを受け付けないかつ、string しか受け付けないので比較的さぼった実装になっています。

これらは WriteLine, Write のシノニムです。実はシノニムですらなくて、コンパイル時には __print, __println という関数呼び出しに置換されます。Cのコンパイラだとよくある関数だと思ってたら実はマクロで、libcに置き換わってた!みたいなそういうタイプの呼び出しです。

// これが
println("Hello, World");
// こう
// (Hello, World) __println

__sym

フォントを設定するにはPSFontAttributeを使うと書いてあるのですが、やっぱりPostScriptの全機能をフル活用したいかなあと思いまして、C#からPostScriptで言うところのNameを生成する関数です。PostScriptのNameに該当する機能がC#にはないのですが、RubyJavaScriptでは言えばSymbolが近い概念です。

こんなのいつ使うんだといわれるとかなり微妙なんですが、findfontをDllImportしたときとかに使えます。

[DllImport("x")]
extern static object FindFont(PsSym sym);

FindFont(__sym("Courier"));

__asm

これはもはやC#なのかわからなくなってきましたが、任意の位置に任意のPostScript命令を直接Emitできます。 いわば、PostScript界のインラインアセンブラです。

/*
// 普通に関数定義もできる
int Fib(int n){
  if(n < 2) return n;
  return Fib(n - 1) + Fib(n - 2);
}
*/
// けどインラインアセンブラで書いたほうがオーバーヘッドが少なくて高速
[DllImport("x")]
extern static int Fib(int n);
__asm("/fib { dup 1 gt { dup 1 sub fib exch 2 sub fib add } if } def");

println(Fib(10)); // 55

参考例にもあるように、__asm で関数定義した場合C#側にはシンボル情報がやってこないのでマッピングのためにDllImportを書きます。この時順番はなんでもいいです。

ref/in/out引数、Tuple引数、Tuple戻り値

アドカレではそんなに言及してないんですが、真面目にコンパイラが実装されているのでref/in/out 引数に無駄に対応しています。 さらに、Tuple構造体がない代わりに、Tuple記法に対応しているのでNamedTupleの定義、分解ができます。

ref/in/out

ref/in/out は引数を渡すときに辞書に包んで関数を呼び、関数は引数がref/in/outの時に辞書から取り出してローカル変数を定義し、関数から抜けるとき辞書に書き戻す。そして呼び出し元は辞書から取り出してローカル変数に書き戻す。という手順を踏んでいます。

つまりこれ、Boxing/Unboxingですね!PostScriptの辞書を使ってref/in/out 指定された変数をBoxing/Unboxingすることで参照渡しをなんだかうまいこと実現できているのです。

% void X(out int n) { n = 10; }
% X(out var k);
/X {
  2 dict begin
    /n_ref exch def
    /n n_ref /value get def
    mark {
      /n 10  dup 3 1 roll store
      pop
    } stopped { pop } if
    cleartomark n_ref /value n put
    end
  }
def
/k 0 def
/k_ref << /value k >> def
k_ref X /k k_ref /value get store

この参照渡し駆使すると地獄のようだけどValidな構文が出来上がって地獄だった。例えば

int n(ref int a, out int b, int c){
  return (b = a += c) * 2;
}
int x = 1;
x = n(ref x, out var y, 3); // 8 

refのaにcを足したものをoutのbに代入したものを2倍したものがnの戻り値でそれをもとのxに代入するというレビューで見たら発狂しそうな実装なんですが、なんかこれたまたま動きます。びっくりですね。

さらにここにTupleを融合させます。

(int a, int b) m(ref int k, out (int y, int z) t){
    t = (k += 2, k *= 3);
    return (t.y, t.z * k);
}

int x = 10;
var t1 = m(ref x, out var t2);
println($"{x}, {t1.a}, {t1.b}, {t2.y}, {t2.z}"); // 36, 12 1296, 12, 36

書いてて何かいてんのかわからないぐらい狂気なので詳細は避けますが、検算したところおそらく出力は正しく、C#の評価順序とも一致した正しい挙動になっていそうです。正直ここまでちゃんと動くとは思ってなかった。

Roslynのごまかしかた

Roslynもこんな使い方をされるとは思ってなかった気がします。ただPostScriptを出力するためにいい感じにASTを吐いてほしいし、なんならC#の構文としておかしいものは事前に全部エラーにしてほしい、ただそうすると組み込み関数とかもエラーにされると困る。ので適当なクラスをでっちあげてRoslynをごまかします。

using System.Runtime.InteropServices;

namespace CsPsc.Preamble
{
    public static class Intrinsics
    {
        [DllImport("cspsc_intrinsics", EntryPoint = "println")]
        public static extern void println(string s);

        [DllImport("cspsc_intrinsics", EntryPoint = "print")]
        public static extern void print(string s);

        [DllImport("cspsc_intrinsics", EntryPoint = "__asm")]
        public static extern void __asm(string s);

        [DllImport("cspsc_intrinsics", EntryPoint = "__sym")]
        public static extern PsSym __sym(string name);
    }

    [System.AttributeUsage(System.AttributeTargets.Assembly)]
    public class PSFontAttribute : System.Attribute
    {
        public string FontFace { get; }
        public int FontSize { get; }

        public PSFontAttribute(string fontFace, int fontSize)
        {
            FontFace = fontFace;
            FontSize = fontSize;
        }
    }

    public class PsSym { }
}

この名前空間をツリーのパース時にだけusing static Preamble.Intrinsics するようにしてあります。その結果Roslynは正当なC#の呼び出しだと思っているのにその先ではILを1文字もEmitせずに、全部PostScriptしか吐かない。というジョークコンパイラとして成り立つ仕組みになっていました。

正直まさかここまでうまくPostScriptにコンパイルできるとも思ってなかったのにRoslynすごいなーPostScriptすごいなーとかおもって適当に作ってたらそこそこにC#が動く、可動式ジョークとしていいポイントに収まったんじゃないかなと思っています。

Roslynで嘘コンパイラ作るの楽しいからみんなもやってみるといいよ

github.com


  1. 実行はWebエディタを用意してあるのでそこで試してみるのが手っ取り早いです。CsPsc Playground

VRChatアバターのモーションを非破壊に差し替えるやつを作りました

VRChat楽しんでますか?僕はぼっちなのでBoothで衣装を買って、Unityで着せ替えを楽しんで、時々散歩に出かけるのと、ラジオ体操をするぐらいです。

2年ぶりの投稿がこれでいいのか一瞬悩まなかったわけでもないんですが、気にしたら負けな気がするので気にしないことにしました。

tl;dr

  • アバターのPlayable Layerに設定されているAnimatorに含まれるMotionを差し替えるNDMFプラグインを作ったよ
  • VCCから導入できるよ、URLはここ https://tmyt.github.io/vpm/
  • GameObjectを置いて、Avatar Motion Changer というComponentを設定してつかってね

前置き

さて、アバターのモーション*1を差し替えたいことが時たまあります。 具体的には、AFKを別なものに変えたり、ジャンプモーションを変えたり、ハンドサインに割当たっているモーションを変えたりでしょうか。

これらの変更をするにはアバターに付属しているAnimatorを複製して編集してアバターに設定という手順を踏まないといけないです*2。 ただ、Animatorを複製して編集みたいなのはできればやりたくないのでNDMFの力でPlayable LayerのAnimatorに設定されているMotionを差し替えるやつを作ってみました。

導入方法と使い方

VCCから簡単導入できるようにしてみました、手元のVCCと友人にやってもらった限りインストールできているので多分あってると思います。 次のページからAdd to VCC してVCCから、Avatar Motion Changer というのをインストールしてください。Non-Destructive Modular Framework が必要ですが、Modula Avatarがインストール済みであればすでに入っています。

tmyt.github.io

VCCからパッケージがインストールできたら、実際にアバターに組み込んでいきます。 今回は、ぽんでろさんのしなのちゃんに、フカさんのしなのちゃんの手でしょりしょりするやつを設定してみます。 アバターなどのUnity Packageはすでにインポートされている状態とします。

booth.pm

booth.pm

まずGameObjectをアバターの配下に追加し、そのGameObjectにAvatar Motion Changerというコンポーネントを追加します。*3

List is Empty と出ている近くの+ボタンを2回押します。すると項目が2個増えるので、ドロップダウンからいい感じに設定します。Animationのところは、設定したいMotion、ここではFUKA_Fist_Triggerをドロップします。

あとはプレイボタンを押すとか、アバターをアップロードするときなどのビルド時に自動でモーションが差し変わります。 もとのAnimatorも変更されないのでアバターのプレハブが更新されたときも基本的に気にしなくていいはず…です。

制約事項

  • Playable Layerに対するAnimatorが未設定の状態のものはこのコンポーネントから設定することはできません。将来的にできるようになるかもしれないですが、そもそも使うことがなさそうなので対応は未定です。
  • StateのMotion以外のパラメータの設定には現時点では対応していません。どうしても必要になったら対応するかもしれないですがこちらも使わなさそうなので対応は未定です。

その他

  • ひとつのGameObjectに複数つけても正しく動くように作っているはずですがテストしてないので本当に動くかはわかりません。
  • オリジナルのデータが変更されていないこと・Play時の一時ファイルでのみ変更されていること・アップロードしたアバターでは変更が反映されていることは十分に確認していますが、100%オリジナルデータが安全という保障はできないので各自バックアップは撮ってください。

おわりに

モーション入れ替えがとても簡単になるのでみんな使ってみてね!*4

それと、こういうの設定できたよ!これが設定うまくできないよ!みたいなのがあったらこそっと教えてください

*1:ここで指すモーションは、Playable Layerに設定されているAnimatorのStateMachine内に設定されているAnimation Clipを指します

*2:たぶんそう。本当にそうなのかはわからないけどみんなAnimator編集するって書いてるからたぶんそう

*3:アバター配下のどこかにComponentが設定されていれば動くので追加しなくても大丈夫ですが、後から見た時にわかりやすいのでとりあえず追加します

*4:そもそもこれを使うシーンが多分ほとんどない

Keychron Q65が届いた

Keychron Q65というキーボードがDHLで届いたのです。

5月ごろにGroupBuyやっていてそれがついに届いたという感じです。ちなみに昨日までは売り切れ表示だったんですが、今(2022年11月23日)みたところ在庫あり表示になっているので今すぐ買えますね!!!!

Keychron Q65 QMK Custom Mechanical Keyboardwww.keychron.com

組み立てるのも楽しいんですがキーキャップ選び出すと沼にはまるのでFully Assembled Knobにしました。

第一印象はめっちゃ重い(物理)なんか2.4kgあるらしいです。2リットルペットボトルより重たい…安定感抜群ですね…

そんでもってめっちゃ光る。USBケーブル接続した瞬間めっちゃ光る。虹色に波打っててゲーミングみたいでした。

このキーボードの気に入っているポイントは左側にノブとM2~M5キーがあることです。Knob Versionっていうぐらいなんだからそりゃそうかという感じですがノブがあります。

しかも、VIAでカスタムできるのも楽しいポイントでした。VIAってすごいんですね、リアルタイムで反映されるし自動で永続化されるし…

VIAで1個だけわからなかったのが、Altを押してESCを押したときはESCじゃなくてGrave*1を出力するようにしたいけどこれをどうしていいかわからなかった。

QMKにはGrave Escapeという機能があってこれを使うと似たようなことができる…けどこれはShiftかGUI*2とESCを押したときにESCじゃなくてGraveになる機能…らしい…*3

このためにレイヤ1枚使うのももったいないしなぁ…とおもってしばらく使ってたらふとQMK改造すればいい!!オープンソース最高!!となってGrave Escapeの機能を改造することにしました。

Grave Escape改造

Grave EscapeがShift or GUIでGraveになるESCから、AltでGraveになるESCに改造したメモ。

DockerでDebianを起動してやります。

# 環境設定
docker run -it --rm debian
apt update
apt install -y sudo zlibg1-dev libjpeg-dev git python3-pip vim
python3 -m pip install qmk
qmk setup Keychron/qmk_firmware

お好きなエディタでここを編集する

diff --git a/quantum/process_keycode/process_grave_esc.c b/quantum/process_keycode/process_grave_esc.c
index ddf02739..17c12a1a 100644
--- a/quantum/process_keycode/process_grave_esc.c
+++ b/quantum/process_keycode/process_grave_esc.c
@@ -23,7 +23,7 @@ static bool grave_esc_was_shifted = false;
 bool process_grave_esc(uint16_t keycode, keyrecord_t *record) {
     if (keycode == QK_GRAVE_ESCAPE) {
         const uint8_t mods    = get_mods();
-        uint8_t       shifted = mods & MOD_MASK_SG;
+        uint8_t       shifted = mods & MOD_MASK_ALT;
 
 #ifdef GRAVE_ESC_ALT_OVERRIDE
         // if ALT is pressed, ESC is always sent
# いい感じにビルドする
make keychron/q65/q65_ansi_stm32l432_ec11:via

ここまでやって、出来上がったbinを焼いたらOKでした。

焼き方はスペースバーを外すとスイッチの左側にDFUに入るスイッチがあるので、それをUSBケーブルを指すとDFUモードになってQMK Toolboxでファームが焼けるようになります。

焼き終わった後、Fn+J+Zを4秒くらい押してEEPROMをファクトリリセットしておくといいそうです。

*1:つまりバッククオート

*2:WindowsでいうところのWindowsキーMacでいうところのCommandキー

*3:ドキュメントを読むともちろんそう書いてある

Windows 開発キット 2023っていうの買いました

Windows 開発キット 2023 っていうやつを買いました。DevKit 2023のほうが呼びやすくていいですね。

BUILDでProject Volterraとして発表されたやつがようやく販売開始した感じなんですが、日本も対象でびっくりしました。*1 販売開始当初、Microsoft Storeで99万とか99円とかで一瞬話題になりましたね。

www.microsoft.com

10月26日に在庫が復活したので注文したところ、価格設定ミスってたこともあって発送がぐちゃぐちゃになっていたらしく配達予定は28日でしたが実際届いたのは11月1日でした。

スペックを引用しておくとこんな感じだそうです。

- 32GB LPDDR4x RAM and 512GB fast NVMe storage
- Snapdragon® 8cx Gen 3 compute platform
- Ports: 3x USB-A, 2x USB-C, Mini-Display (HBR2 support), Ethernet (RJ45)

あとから知ったんですが、実装RAMが32GBなことにびっくりしました。

感想

Arm64で動くWindowsなだけでなんも変わらないですね…  Snapdragon 8c以降はCPUが仮想化対応になったのでHyper-Vも動きます。Hyper-Vが動けばWSL2も動きます。

ソフトウェア面では、最近はVSCodeもArm64で動くし、Visual StudioもまだPreviewですがArm64で動作します。 2019年頃はまだx86エミュレーションで実行されていたOfficeやOneDriveも今ではArm64で動くようになりました。3年前よりArm64でコンパイルされたバイナリもかなり増えてきた印象です。

SlackやDiscordのようなサードパーティーのアプリケーションはArm64版Windowsバイナリを提供してくれないことが多くエミュレーションで実行されます。ただ、Arm64上のバイナリエミュレーションはそれなりにはがんばるので心配するほどは遅くないです。*2とはいえ、エミュレーションのChromiumとv8で動作するElectronよりはブラウザでアクセスしたほうが速いかもしれません…*3

x86エミュレーションでADBも使えるのでAndroidデバッグできます。*4

Seeeduino Xiaoを接続したところ、ちゃんとシリアルデバイスとして認識され、Arduino IDEコンパイルから書込みまで成功しました。

最近はデバイスドライバ周りもUniversal対応になっているものが増えてきたので、C630を買ったころよりはるかに環境が整備されました。

おもしろポイント1

おもしろポイント1は、Arm64でWindows動作しているのでWSAももちろんArm64で動作します。

[ro.product.cpu.abi]: [arm64-v8a]
[ro.product.cpu.abilist]: [arm64-v8a,armeabi-v7a,armeabi]
[ro.product.cpu.abilist32]: [armeabi-v7a,armeabi]
[ro.product.cpu.abilist64]: [arm64-v8a]

Arm64でWSAが動くメリットは、Unityのil2cppでコンパイルされたバイナリがx86_64版のWindowsより安定して動いている感がありました。あと心なしか動作が早い気もする、ただ計ったわけではないです。

ただ考えてみるとArm64で動いてるWSAって、それHyper-Vで仮想化されてるただのAndroidやん……という話なのでそりゃはやいじゃんという話ではあります。

おもしろポイント2

おもしろポイント2は、中身はほとんどSurfaceだそうです。たぶんSQ3のSurface Proから画面とモデムと電池をとっぱらった結果なんじゃないでしょうか。

UEFISurfaceのものが動いているようなのですが、USB-Cで接続するとUEFI画面が表示されないのでどんなのが出ているのでしょうか… miniDP to HDMIなアダプタが手に入ったら確認してみます。

そのほか

セットアップはさすがにリモートではできない…のだけど余っているディスプレイはないので数年前に流行ったHDMIをUVCで接続できる2000円ぐらいのアレ*5で画面をみてたんですがやっぱしまぁまぁ便利ですね。1個持っとくといい。

キーボードとかの接続もめんどくさかったのですが、LenovoThinkPad トラックポイント キーボード IIが2.4GHz無線とBluetoothのデュアルスタックなのでこういう時に1枚持っていると便利でした。*6

OOBEはネットワークが必須になったバージョンでした。ローカルアカウントを1回作りたい派なので、Shift+F10で OOBE\BYPASSNRO してI get kotonakiです。

このあとMSAログインに切り替えたのですが、その時にパスワードログインが無効になってしまうので有効にしたあと一度パスワードでログインしてあげないとリモートからログインできませんでした。地味にはまりポイントです。

あと結構謎な動きをしたのが、Final Fantasy XIV 暁月のフィナーレベンチマーク(x64バイナリ)を実行したところ、ベンチマークシーンの開始5秒付近でなぜかマシンがリセットしてしまいます。イベントログを見ると、予期しないシャットダウンでした。ということなので予期しないシャットダウンらしいのですがなんのこっちゃわかりません。エミュレーションの過程で変な命令とか叩いてうっかり死んでしまったのでしょうか。そもそも動作対象外の環境なのでこれ以上は詳しく調べることはしませんでした。

このPCはここまでの設定をしたのちに、電源ケーブルだけ接続された状態で部屋の隅に押し込まれたのでした…

*1:前のSnapdragon DevKitって言ってたやつは北米だけだったはず

*2:Ryzen 9 4950XみたいなハイエンドCPUと比較するともちろん遅いです。

*3:ちなみに、2022年11月現在ChromeもArm64版が提供されていません。EdgeはArm64ネイティブなのでChromeを使うよりはEdgeを使ったほうが速いですね

*4:もちろん、WSAで動作している自分自身にもadb接続できます。

*5:https://www.amazon.co.jp/dp/B0936Q2G5G/

*6:今思えば何も考えずに接続したけど普通に使えてました。ドライバ大丈夫かな…とか何も考えてなかった

スマホ同期 あらため、電話リンク

WindowsAndroidを接続して通知とかが見られるようになる、スマホ同期(英語だとYour Phone)がWindows 11になってもうちょっと便利になったよ。というのは見ていたけど一回も使ったことなかったので使ってみたら結構おもしろいし便利だったし、実装も面白い感じだったのでまとめておきます。

そもそも何

WindowsからAndroidに接続して通知がみれる、SMSの送受信ができる。一部の機種では画面の転送とか電話の発着信もできる。

一部の機種というのは、ここに書いてあって、 Surface Duoシリーズと、Galaxyシリーズだけ。GalaxyなのはSamsungとがんばって作ってますよ、ということだから。

さらに、最新の機能を使うにはGalaxyの最近の機種か、Surface Duo 2じゃないとだめ。そうSurface Duo 2を買ったから試そうと思ったのでした。

画面転送

画面転送がアプリ単位でできます。これがわりと便利でおもしろい。

例えば、Panasonicのシーリングを操作してみたり f:id:tmyt:20220406221535p:plain

プリコネグランドマスターズをプレイしたり f:id:tmyt:20220406221723p:plain

ToDoを書き込んでおいたり

f:id:tmyt:20220406221801p:plain

というのが、Windows上から同時に起動できます

f:id:tmyt:20220406222127p:plain

Google Chat入れてないなってPlayストアからインストール中の図 f:id:tmyt:20220406222344p:plain

アプリはWindows側から起動できて、電話リンクにアプリ一覧が出てきます。

f:id:tmyt:20220406222722p:plain

ここから選ぶと、アプリが立ち上がって専用のウィンドウとして表示される。さらにこのアプリはスタートメニューとタスクバーに登録ができる(!!)

f:id:tmyt:20220406222824p:plain

タスクバーにもちゃんとAndroid側のアイコンで表示される(!!)めっちゃすごい…すごいがんばって実装されている…

f:id:tmyt:20220406222851p:plain

使ってみた感想

たくさん開くとだめらしいです。Surface Duo 2では7個?が上限らしい。

f:id:tmyt:20220406223400p:plain

ゲームが快適に遊べるほどのフレームレートでは転送されてこないです。プリグラぐらいなら遊べた。

気になるのがどうやって実装されているのかな。というところ。わかる範囲で挙動をみてみたところ、アプリごとのセカンダリディスプレイが起動しているようです。

display?.displayId?.toString() // とかすると、20以上の値がGetできる

なので、サポートされてる機種じゃないとアプリ単位での転送ができないってことらしいです。

アプリごとのディスプレイを作ってるので、Windows側から比較的柔軟に制御できるのかーかしこいなー、なんて。

メールがみれたりしてちょっと便利なのと、Androidでしか動かないアプリを起動できてちょっと便利なぐらいでたいていはWindowsでもできるので劇的にこれが便利!!!ってことはないかもしれない。ただ知っておくとたぶんすごく便利。

あと、接続中はすごい速度で電池が減っていくのでいらないときは通知パネルからOffにしておくとなおよし。

f:id:tmyt:20220406232551p:plain

スマホ同期 あらため、電話リンク

WindowsAndroidを接続して通知とかが見られるようになる、スマホ同期(英語だとYour Phone)がWindows 11になってもうちょっと便利になったよ。というのは見ていたけど一回も使ったことなかったので使ってみたら結構おもしろいし便利だったし、実装も面白い感じだったのでまとめておきます。

そもそも何

WindowsからAndroidに接続して通知がみれる、SMSの送受信ができる。一部の機種では画面の転送とか電話の発着信もできる。

一部の機種というのは、ここに書いてあって、 Surface Duoシリーズと、Galaxyシリーズだけ。GalaxyなのはSamsungとがんばって作ってますよ、ということだから。

さらに、最新の機能を使うにはGalaxyの最近の機種か、Surface Duo 2じゃないとだめ。そうSurface Duo 2を買ったから試そうと思ったのでした。

画面転送

画面転送がアプリ単位でできます。これがわりと便利でおもしろい。

例えば、Panasonicのシーリングを操作してみたり f:id:tmyt:20220406221535p:plain

プリコネグランドマスターズをプレイしたり f:id:tmyt:20220406221723p:plain

ToDoを書き込んでおいたり

f:id:tmyt:20220406221801p:plain

というのが、Windows上から同時に起動できます

f:id:tmyt:20220406222127p:plain

Google Chat入れてないなってPlayストアからインストール中の図 f:id:tmyt:20220406222344p:plain

アプリはWindows側から起動できて、電話リンクにアプリ一覧が出てきます。

f:id:tmyt:20220406222722p:plain

ここから選ぶと、アプリが立ち上がって専用のウィンドウとして表示される。さらにこのアプリはスタートメニューとタスクバーに登録ができる(!!)

f:id:tmyt:20220406222824p:plain

タスクバーにもちゃんとAndroid側のアイコンで表示される(!!)めっちゃすごい…すごいがんばって実装されている…

f:id:tmyt:20220406222851p:plain

使ってみた感想

たくさん開くとだめらしいです。Surface Duo 2では7個?が上限らしい。

f:id:tmyt:20220406223400p:plain

ゲームが快適に遊べるほどのフレームレートでは転送されてこないです。プリグラぐらいなら遊べた。

気になるのがどうやって実装されているのかな。というところ。わかる範囲で挙動をみてみたところ、アプリごとのセカンダリディスプレイが起動しているようです。

display?.displayId?.toString() // とかすると、20以上の値がGetできる

なので、サポートされてる機種じゃないとアプリ単位での転送ができないってことらしいです。

アプリごとのディスプレイを作ってるので、Windows側から比較的柔軟に制御できるのかーかしこいなー、なんて。

Surface Duo 2を買いました

Surface Duo 2が日本国内で発売が始まって2か月半ぐらいが経ちました。突然思い立ってSurface Duo 2を買ったのでした。

初代Surface Duoと比べるとこんな感じ。左が2、右が1。

上下ベゼルが少し狭くなって画面の縦幅が少し大きくなりました。ヒンジ側のベゼルも少し小さくなってますね。全体的によくなったと思います。

f:id:tmyt:20220330141722p:plain

初代と比べて

よくなったところ

  • ディスプレイが90Hzになった
  • 指紋センサが電源ボタンと統合された
  • フラッシュライトが背面に移設された
  • NFCがついた
  • 背面にカメラがついた
  • 工作精度があがった
  • SD888速い
  • 開け閉めのフィーリングがよくなった
  • 閉じたときに若干楔形になるようになって保護シート貼ってもちゃんと閉まるようになった(気がする)
  • 5Gは…まぁあればうれしいかな…

いまいちなところ

  • カメラがダサい…
  • ちょっと高い

まとめ

よくなったところは書いてある通りで、とてもよくなりました。ディスプレイは滑らかだし、電源と指紋センサの位置がバラバラでいまいちとか思わなくなったし*1

NFC搭載はVISAタッチがGoogle Payで使えるようになったので*2、ついにSurface Duoだけでも決済できるようになったか!というインパクトがありとてもいいです。実際に何回かコンビニで使ってますが、画面を開かなくても電源ボタンを押して指紋認証だけ通してしまえば決済できるのでとても便利でした。

フラッシュライトが外側についたので、誤ってフラッシュライトをONにして目つぶしを食らわなくなったのも大きいです。

一方で、外側にカメラが付いたのはまぁいい感じなんですが、3眼のそこそこなカメラが付いたので見た目がやばいですね…開いて裏返すとこんな感じに…

f:id:tmyt:20220330142718p:plain

Surface Duo 2って結構薄い*3のでディスプレイモジュールの裏にさらにカメラモジュール載せるとこの厚さ*4にしかならなかったんだよ。と言われればそうかもしれない。けどおさめてほしかったなぁという気持ち。

カメラ部分が上部だけなので、完全に開いたときに下側に空間があるのでちょっと力をかけると曲がってしまう、もしかしたら割れるんじゃないかみたいな怖さがあります。

Duo 1のころは、画面を外に折り返したままポケットに突っ込むみたいなこともしばしばあったのですが、さすがにこの状態だと不意に力がかかって画面われそう…となるのでちゃんと閉めるようになりました。もしSurface Duo 3が出るのであればぜひカメラは収まるようにしていただきたいですね。

*1:最初指紋センサだった場所に触って動かんな。みたいなのをよくやりました

*2:https://www.smbc-card.com/brand/googlepay_visa/index.html

*3:5.5mm

*4:カメラが楔形になってるので最薄部で約8mm