TITAN TWOでのマクロの作り方
本記事の執筆経緯
「ゲームの稼ぎを自動化して楽したい」
ゲーマーの多くは考えることでしょう。
世界にはそれを叶えてくれる方法がいくつかあり、輪ゴムでスティックを傾け続けるとか、連打機能付きコントローラーを使うとか、はたまた連打してくれる装置を自分で作るとか……
自分もそういうのが欲しかった者のうちの1人なので、買ってみました。
TITAN TWOです。
Amazonでの購入はコチラ
TITAN TWOは「ゲーミングコンバーター」と呼ばれるもので、プレイヤーの入力を、連打やコンボなどに変換してくれるツールです。
筆者は試していませんが、ゲームのコントローラーを別のゲーム機でも使用可能にする機能もあるとかなんとか。
というゲーミングコンバーターという名前的には、そちらがメインの使い方になるかと思います。
さて、上記のTITAN TWOのAmazonや販売代理店の説明をお読みいただくとわかると思いますが、「圧倒的なマクロ機能!」だとか「自分専用のマクロを開発することも可能!」だとか書いてあります。
マクロを組むだけならもっと安くて手軽にできるツールがたくさんあると思うのですが、説明に「ミリ秒のカスタム精度」という記載もあり、筆者が自動化したいゲームはそのミリ秒単位の調整が必要だったのです。
具体的にはパタポン3の稼ぎを自動化したかったのですが、リズムゲーなのでいかんせん判定がシビアで……
それで、ミリ秒単位でマクロが組めると書いてあったTITAN TWOをいざ買ってみて、付属のQUICK SETUP GUIDEと日本語マニュアルを読んでみたものの……
公式の解説が絶望的にわかりにくい。
公式アプリのインストールまでは解説されているものの、肝心の公式アプリの使い方がほとんど説明されておらず、マクロの組み方が全然わかりません。
レビューにも説明がわかりにくいことは書いてあったけども!
あと箱に書いてあった日本語マニュアルのリンクが全く関係ない別の会社のマイクの解説書だったんですけど!
QRコード側は日本語マニュアルに繋がってたけど!
TITAN TWOの導入方法を解説されているブログは多少あるものの、マクロの作成に関してはあまり存在しておらず、自分にはそれを読んでも理解が難しく……
なんとか動くマクロの作成までは行けたので、いっそ自分で記事を書いて後続の方に役立ててもらうことにしました。
もっと簡単にマクロを作れる方法があったらゴメンね!
注意事項
・本記事で発生した問題や損害の責任は負いません。
オンラインゲームにマクロありで突入しないようにね、最悪BANされるだろうから……
・筆者が動作を確認したのは「PlayStation Vita TV」に対してPS4コントローラーを繋いだ状況のみです。
他のゲーム機ではまだ使ったことがありません。
公式の対応デバイス一覧があるので、自分が使いたいゲーム機が対応しているか調べましょう。
・この記事で紹介するのは単純なボタン入力のマクロのみです。
高度なやり方は紹介していませんので悪しからず。
・多少プログラミングの知識が必要です。
プログラミングを全く知らない場合は厳しいかもしれませんが、単純なボタン入力なら何とかなる……かも。
・TITAN TWOの公式アプリを起動できるようになるまでの詳細な解説はしません。
購入時に付いてきたQUICK SETUP GUIDEの日本語版や、他の方の記事をご覧ください。
次の章でざっとは説明しますが、公式のQUICK SETUP GUIDEが絵もあってわかりやすかったと思います。
TITAN TWOの公式アプリを起動できるようになるまで
公式ガイドにも書いてはありますが、なんらかの事情で完全に閲覧できない状況になりうると思うので、ざっと説明を載せておきます。
まずはケーブルの繋ぎ方から。
(まぶしくてゴメン)
下のケーブル(Aポート)は操作に使うコントローラーのインプット、上の左側のケーブルはゲーム機本体、右側のケーブルはPCに繋ぎます。
下には右側にもケーブルを繋げる場所(Bポート)があり、PS5等の認証が必要なコントローラーはここに刺す必要があるみたいです。
また、上の左側にはマイクロSDカードのスロットもあります。
マイクロSDカードが必須かどうかはよくわかりませんでした。
多分SDカードなしでも動くと思うのですが、SDカードを抜いても動くのか確認しようと思ったものの、SDカードの抜き方がわからず……
TITAN TWO本体に比べたら安く買えるので、一緒に買っておくことをお勧めします。
※追記
ConsoleTuner » t2:gpc_scripting:combos
公式のリファレンスを読んでいたのですが、マクロにはSDカードが必要ですが、コンボにはSDカードが必要なようです。
今回のこの記事で紹介しているのはTITAN TWOでの区分ではコンボに該当するものなので、SDカードは必須ではなさそうです。
ここまで追記
なお、上側に付けるケーブルはどちらもマイクロUSB-B端子です。
1本はケーブルが付いていましたが、もう一本はPCと繋ぐように自分で用意しておく必要があります。
(ちなみに、写真ではタイプCをタイプBに変換する端子を使ってます:Amazonリンク)
本体に必要なケーブルを刺したら、以下のページを辿って公式アプリをダウンロードします。
ConsoleTuner » Gtuner IV
「GO TO DOWNLOAD PAGE」というリンクがあるので、その先からダウンロードしてください。
ダウンロード後、アプリを起動出来たら次に進みましょう。
コントローラー入力を確認
公式アプリをダウンロードし起動すると、細部は異なると思いますが以下のようなアプリが立ち上がると思います。
まずは右上にご注目ください。
初回起動時には、右上の「TITAN TWO [E9...」と書かれている部分が、「Disconnected - 1 ...」などと書かれていると思います。
まずはそこをクリックし、繋がっているTITAN TWOを選びましょう。
順調に進んでいれば選べるはず……
続いて、コントローラーが正常に動作しているか確認します。
中央の大きな画面の下にご注目ください。
筆者は設定で表示内容を減らしていますが、初期設定では赤枠の部分にはほかにも項目があると思います。
左上の「VIEW」から、使わないのは消しておくことをお勧めします。
さて、この中から「Device Monitor」を選びましょう。
すると、画面中央がこういう感じになると思います。
この画面はコントローラーの入力と出力を表しています。
上記画像ではPS4コントローラーの〇ボタンを押しているため、INPUTのCircleが100になっています。
コントローラーの入力通りに数値が表示されていれば、接続成功です。
ごく簡単なマクロを動かしてみる
さて、今度はマクロを作成してみましょう。
まず、GPC Script IDEを開きます。
ここでは既に何かしらのコードを用意していますが、最初は多分何も出ていないと思います。
左上のファイルアイコンをクリックし、新しいファイルを作成しましょう。
そして表示された画面に、以下のプログラムをコピー&ペーストしてみてください。
#pragma METAINFO("push_circle", 1, 0, "<author_name>") combo CIRCLE { set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(400); set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(400); } init{ set_val(BUTTON_15, 0.00); } main { if(event_active(BUTTON_15)){ combo_run(CIRCLE); } }
PS4のコントローラーでは、〇ボタンを1回押したときの挙動が、「〇ボタンを2回押す」に書き換わるプログラムです。
機種によってBUTTON_15の箇所が変わってきます。
Device Monitorで対応する番号がわかると思うので、そこは書き換えてください。
さて、作ったプログラムを、TITAN TWO本体に反映させる必要があります。
反映方法は次の3ステップです。
- 自動化プログラムを書く
- 作成したプログラムをFile Explorerから選び、Memory Slotにドラッグ&ドロップ
- ドロップしたスロット左の番号をクリック
以上により、TITAN TWOに作成したプログラムが反映されます。
ドラッグ&ドロップしたときに、画面下部のOutput Panelでエラーが出る場合、プログラムのどこかが間違っています。
その場合、そのエラーの説明文をダブルクリックすることで、間違っている箇所の近くを教えてくれます(間違っている箇所そのものを教えてくれることもある)。
エラーメッセージをヒントに修正しましょう。
とりあえずやりがちなのは、セミコロンを忘れることです。
最後に、TITAN TWO本体の番号を、メモリスロットの番号に合わせます。
中央の番号の左右に物理的なボタンがあり、これを押すことでスロット番号を変更できます。
今回筆者は2番にドロップしたので、番号は2に設定します。
あとはこの状態で、〇ボタンを押せば、「〇ボタンを2回押す」という入力が起こります!
上手くいかなければここまでの手順のどこかで間違えている可能性が高いので、先ほどの3ステップあたりからやり直してみることをお勧めします。
これでおよそのマクロ作成の手引きは終了です。
あとはもう少し詳細なプログラム方法を解説します。
プログラムの中身についての解説と若干の補足説明
TITAN TWOではGPCというスクリプトを用いてプログラミングが可能です。
しかし、おそらく独自の言語なので、解説が少ないです。
C言語ベースではある様子。
初期化があってメイン関数を実行し続けるので、筆者が知っている中ではArduinoなんかに挙動が近いです。
情報量が少ないものの、一応公式の解説ページはあるので念のため見ておいてください。
F7でコンパイルは結構役に立ちます。
ConsoleTuner » t2:gpc_scripting
あと、最初は無いと思っていたのですが、リファレンスもちゃんとありました。
ConsoleTuner » t2:gpc_language_reference
このページの左の欄に各種機能へのリンクがあります。(PC以外から見ると別の場所にリンクがあるかも)
本格的にマクロを組む場合は詳細を見ておいたほうがよさそうですね。
本章では前章のプログラムの解説をします。
#pragma METAINFO("push_circle", 1, 0, "<author_name>")
まず先頭のこれは、プログラムの作者名とかを設定できるようですが、マクロの内容自体には影響を与えないと思うので無視していいでしょう。
ファイルを作成した時点で付与されるので、弄らなくて良いと思います。
続いてcomboについて。
combo CIRCLE { set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(400); set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(400); }
これはcomboというもので、おそらくGPC独自のものです。
comboのあとにコンボ名を付けます。
関数ではないためか、コンボ名の後ろには()はつけません。
このcombo内で、キー入力を設定できます。
先述の通りBUTTON_15はPS4コントローラーでは〇ボタンです。
set_val(BUTTON_15, 100.00);では、〇ボタンの値を100(押されている状態)にし、
set_val(BUTTON_15, 0.00);では、〇ボタンの値を0(押されていない状態)にします。
wait(100);はそのまま一定秒数待つ指示で、ミリ秒単位で記入します。
この場合は100ミリ秒、つまり0.1秒待機します。
ということでcombo CIRCLEの機能は、「0.1秒〇ボタンを押し、0.4秒待機する」を2回繰り返していることになります。
続いてinitについて。
init{ set_val(BUTTON_15, 0.00); }
このinitは、プログラムの開始時に1度だけ呼ばれます。
ここでは〇ボタンを押されていない状態にしていますが、実際のところは今回は必要なかったと思います。
最後にmainについて。
main { if(event_active(BUTTON_15)){ combo_run(CIRCLE); } }
mainはマクロを実行している(TITAN TWO本体の番号を合わせている)限り、何度も実行され続けます。
まず、event_active(BUTTON_15)は、〇ボタンが押されたことを指します。
長押ししても1回分の判定になります。
長押ししている間続けたい場合は、get_val(BUTTON_15)にすればOKです。
if(event_active(BUTTON_15))で、〇ボタンが押された場合にcombo_run(CIRCLE);を実行することになります。
これで上記で定義したcomboのCIRCLEを実行できます。
以上で先ほどの〇ボタンを2回押すプログラムの解説は終わりです。
後はいくつか使えそうなものを紹介します。
#pragma METAINFO("push_circle", 1, 0, "<author_name>") combo CIRCLE { set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(400); set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(400); } combo CROSS { set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(400); set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(400); } init{ } int mode = 0; main { if(event_active(BUTTON_6)){ // press R stick mode = (mode + 1) % 3; printf("%d", mode); } switch (mode){ case 1:combo_run(CIRCLE);break; case 2:combo_run(CROSS);break; default: combo_stop(CIRCLE); combo_stop(CROSS); break; } }
こんな感じのプログラムを作ってみました。
combo CROSSは、〇ボタンの代わりに×ボタンを押すようにしたものです。
mainの上でint mode = 0;と、グローバル変数を宣言しています。
mainは繰り返し実行されますが、その外にあるmodeの値はmainが何度実行されても保持されます。
そしてmainは、modeを切り替える部分とmodeに応じて挙動を変える部分の2段構成です。
'''
if(event_active(BUTTON_6)){ // press R stick
mode = (mode + 1) % 3;
printf("%d", mode);
}
'''
これは、Rスティックの押し込みがされるたびに、modeを現在の値から1増やし、3以上になったら0に戻しています。
その後、Output Panelに現在のmodeの値を出力しています。
TITAN TWOの本体側のボタンでマクロを切り替えることも可能ですが、このように普段使わないボタンにモード切替機能を付けることで手間を省くことができます。
switch (mode){ case 1:combo_run(CIRCLE);break; case 2:combo_run(CROSS);break; default: combo_stop(CIRCLE); combo_stop(CROSS); break; }
次にこの部分は、C言語にもあるswitch文で、modeの値に応じて実行するcomboを変えています。
combo_runはそのcomboが実行されていなかったら実行し、実行されていたらそのまま実行し続けます。
つまり、mode1を保ち続けると、〇ボタンを押すプログラムが実行され続けることになります。
modeを2に切り替えると、〇ボタンを押すcomboが実行途中であればそれをそのまま続け、それと同時に×ボタンを押すcomboも実行されます。
つまり、同じcomboは同時には実行されませんが、別々のcomboは同時に実行されるようです。
combo_stopは、実行中のcomboを途中で終了させます。
と、こんな感じでC言語で使える条件分岐を使うことで、マクロを便利にしたり複雑にしたりいろいろできそうです。
おわりに
というわけで、TITAN TWOでマクロを作成する手順の説明でした。
最後のステップの数字を押し忘れることが多いので、動かないなーと思ったらそこを疑いましょう。
Amazonでの購入はコチラ
冒頭でも記載したように、マクロ使いたいだけならば他のもっと安い奴で十分でしょう。
ミリ秒単位での調整に魅力を感じたら購入してみても良いと思います!
ではでは、閲覧ありがとうございました。
おまけ:パタポン3の暗黒竜リベラ1階層自動攻略スクリプト
最後に、筆者の本来の目的であったパタポン3の自動化スクリプトをおまけで載せておきます。
とりあえず遊びで動かそうと思っていただけなので、最適な行動にはなっていません。
裏ダンジョンの暗黒竜リベラの1階層目用のスクリプトです。
カンがワンダバラッパだとその生死で最適な入力が左右されると思うので、このスクリプトではカンがワンダバラッパ以外を想定して作成しています。
LトリガーとRトリガーでモードを切り替え、モード1がリベラ攻略モードです。
モード2はパタパタし続けるモード、モード3は宝箱開封をするものです。
パタポン2でもパタパタのモードは使えるので、パタポンを持っている方はスクリプト作成の参考にしてください。
#pragma METAINFO("playmacro", 1, 0, "<author_name>") init{ set_val(BUTTON_14, 0.00); set_val(BUTTON_15, 0.00); set_val(BUTTON_16, 0.00); set_val(BUTTON_17, 0.00); } combo PATA { set_val(BUTTON_17, 100.00); wait(100); set_val(BUTTON_17, 0.00); wait(400); } combo PON { set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(400); } combo DON{ set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(400); } combo CHAKA { set_val(BUTTON_14, 100.00); wait(100); set_val(BUTTON_14, 0.00); wait(400); } combo WAIT{ wait(1995); } combo DONDODONDODON{ set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(400); set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(150); set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(400); set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(150); set_val(BUTTON_16, 100.00); wait(100); set_val(BUTTON_16, 0.00); wait(400); wait(1995); } combo OPEN_CHEST{ set_val(BUTTON_15, 100.00); wait(100); set_val(BUTTON_15, 0.00); wait(1400); set_val(BUTTON_12, 100.00); wait(100); set_val(BUTTON_12, 0.00); wait(900); } combo CHAKACHAKA{ call(CHAKA); call(CHAKA); call(PATA); call(PON); call(WAIT); } combo PATAPATA{ call(PATA); call(PATA); call(PATA); call(PON); call(WAIT); } combo PONPON{ call(PON); call(PON); call(PATA); call(PON); call(WAIT); } combo DONCHAKA{ call(PATA); call(PON); call(DON); call(CHAKA); call(WAIT); } combo PONPATA{ call(PON); call(PATA); call(PON); call(PATA); call(WAIT); } combo ONE_ROOM{ // enter room call(PONPON); call(PATAPATA); call(PATAPATA); call(PONPON); call(PATAPATA); call(PATAPATA); call(PONPON); call(DONCHAKA); call(DONCHAKA); call(PONPON); call(PATAPATA); call(PONPON); call(PATAPATA); call(PATAPATA); call(PATAPATA); call(PATAPATA); call(PATAPATA); call(PATAPATA); call(PATAPATA); call(PONPATA); } combo RIBERA{ // start call(PATAPATA); call(PATAPATA); call(PATAPATA); call(PATAPATA); call(ONE_ROOM); call(ONE_ROOM); call(ONE_ROOM); call(PONPON); call(PATAPATA); call(PATAPATA); call(DONDODONDODON); } int mode = 0; int active = 0; int lastMode = 0; int lastActive = 0; main { if(event_active(BUTTON_8)) { // Run the Macro once. mode -= 1; active = 0; } else if(event_active(BUTTON_5)){ mode += 1; active = 0; } else if(event_active(BUTTON_9)){ active = 1; } else if(event_active(BUTTON_6)){ active = 0; } mode = (mode + 4) % 4; if(mode != lastMode || active != lastActive){ printf("mode:%d, active:%d", mode, active); lastMode = mode; lastActive = active; } switch(mode * active){ case 0: combo_stop(RIBERA); combo_stop(PATAPATA); combo_stop(OPEN_CHEST); break; case 1: combo_run(RIBERA); break; case 2: combo_run(PATAPATA); break; case 3: combo_run(OPEN_CHEST); break; } }