2017年1月6日金曜日

pixel bufferのOpenGL/ESのロジックをC++化

昨日書いた記事で、Android版LaiNESの描画ロジックをOpenGL/ES2.0に書き換えることに成功しましたが、OpenGL/ESの実装をJavaで書くというしょっぱい作りになっていました。

AndroidのOpenGL/ESはNDK(C/C++)で書くことができるので、Javaで書くのはナンセンスです。

という訳で、サクッと Java → C++化。
https://github.com/suzukiplan/nes-view-android/pull/6

これで描画周りのパフォーマンスは大分良い感じになったと思います。

ただし、実機で動かした時の最大のボトルネック要因は描画周りではなくAPUエミュレータ(音関連)なので、その部分を何とかしたいところ。(これはLaiNESの問題で、VGSでは問題ないことだからあまり深追いするつもりはありませんが)

2017年1月5日木曜日

OpenGLで pixel buffer を60fps描画する方法

たまには技術的なことを書こう。

かなり以前、Android版VGSの描画をSurfaceViewからOpenGLに変更する試みをしたものの、60fpsのパフォーマンスが確保できず断念したことがあります。

VGSの描画処理は、

  1. 描画API(vgs_putSP等)を発行するとメモリ(システムメモリ)上に確保された8bit仮想VRAMに出力(OS非依存)
  2. VSYNC(垂直同期)の間隔で8bit仮想VRAMの内容を画面に出力(OS依存)
という流れで映像を画面に出力してます。

Android版VGSの上記2(OS依存部分)の実装は、RGB565のBitmapに8bit仮想VRAMの内容を(パレット変換をしながら)書き込み、それをSurfaceViewへCanvas#drawBitmapで描画する形になっています。

当時、これをOpenGL化するに当たって、毎フレームテクスチャを生成して描画するという方法を試しました。

しかし、テクスチャ画像の生成には結構時間がかかります。
また、システムメモリからGPUのメモリへの転送速度は物凄く遅い。
色々工夫して、50fps台ぐらいまで出せるようになったものの、それでは実用上問題がある(フレームレートだけでなく発熱量や消費電力も凄いことになる)ので、当時は結局OpenGL化を断念しました。

今回また、映像処理をOpenGL化することに再挑戦してみようと思います。

今回は、映像をテクスチャで表示するのではなく、1pixelを2ポリゴン(1つの四角形)で表現し、ポリゴンの色を変更することで映像を表示する仕組みを試してみることにします。

また、今回はVGSではなく、先日作ったLaiNESベースのファミコンエミュレータを使います。VGSのアーキテクチャはゲーム機エミュレータと同じ仕組みで作っているので、やっていることはファミコンと大差はありません。

以下、実際にOpenGL対応したAndroid版LaiNESを作成時の Pull Request です。
https://github.com/suzukiplan/nes-view-android/pull/4

ファミコンの場合、画素は256x240なので、pixel数=61,440 になります。
ポリゴン数 = pixel数 x 2 なので, 1フレーム辺り122,880ポリゴン。
60frame で描画するポリゴン数は, 7,372,800(737万2,800ポリゴン/秒)。

初代PlayStationの最大ポリゴン数のSCE公表値は、

  • 演算能力 = 150万ポリゴン/秒
  • 表示能力 = 36万ポリゴン/秒

とのことなので、この方式だと少々キツイ。
まぁ、初代PlayStationで動かす訳ではないですが。
ただ、もう少しポリゴン数を抑えた方が良い感じかなと。

そこで、上記のPull Requestでは、色情報の変化があったpixelのポリゴンのみ色を変更するようにしています。

これで適当なゲーム(某横スクロールアクションゲーム)を動かしてみて、1フレームあたりに更新されたピクセル数を測定した結果が下図です。
画面切り替わり直後などに最大更新が走りますが、ゲームプレイ中は多くても1万pixel未満の更新(これはスクロール時)で、スクロールしていない状態であれば100pixel未満の更新しか走らないようです。

常にスクロールしている状態(1万pixel更新)であれば、120万ポリゴン/秒ということになるので、これなら演算能力的には初代PlayStationでも耐えられそうです。(表示能力は追いつかなそうですが)

ナッツ&ミルクやドンキーコングみたいな固定画面アクションゲームなら余裕です。
まぁ、最近のスマホならフル更新(737万ポリゴン)であっても60fps保てそうな感じかと思います。(Android実機が手元に無くてエミュレータでしか動作確認してません)

2017年1月4日水曜日

デレステの上達方法

最近デレステのことしか書いていませんが、そういえばデレステは音ゲーなのに、音ゲーっぽいネタを書いてないな。という訳で、音ゲー部分の上達方法みたいなものを書いてみます。

参考までに私の腕前は、プレイ開始3日目でおねがいシンデレラのMasterをギリギリクリアできた程度で、プレイ開始から約4ヶ月経過した現在は、Master95曲中69曲フルコンしている感じです。(下手の横好きレベル)

音ゲーをじっくりプレイしたのは今回(デレステ)が初めてなのですが、一応ピアノをやっていたことがあるため、私のデレステ練習方法は基本的にピアノの練習方法の応用(ピアノで「こうやったら上手く出来るようになった」というネタが幾つかあるので、それをデレステ向けにカスタマイズしたもの)です。ちなみに、ピアノの腕前は平均律が弾ける程度でした(※今はもう弾けない)。

以下、我流の上達方法を項目毎に書いてみます。

①適正レベルより高めの曲のプレイを繰り返す
プレイ開始当初は、初回キャンペーンで獲得した無料石(2500個)を全て消費し尽くすつもりで、お願いシンデレラを繰り返しプレイしました。
自分の適正レベルより少し高めのレベルの曲(ギリギリクリアできるぐらいの曲)を繰り返しプレイすると上達スピードが早くて良い感じです。
やり込みの目安としては、ClearランクS(100回クリア)を取れるあたりを目標にすると良いでしょう。ちなみに、おねシンの次は(曜日限定だけど)咲いてJewel(Lv25)でそれをやりました。
しかし、一番難しい曲でも平常時はLv28までしか無いので、この方式で成長できるのは適正レベル(フルコンが狙えるレベル)26〜27辺りが限界になります。
イベントでLv30のMaster+曲が来れば、適正Lv28辺りにまで成長できるチャンスですが、Lv29のMaster+だとLv28のMasterとの差が少なすぎてあまり練習にならなかったりします。

②タップする指の接地面積を可能な限り小さくする
例えば、指の腹でタップするとミスし易くなります。
AppStoreでレビューを見てみると、「ロングノートが途中で切れる」「タッチしていないのにタッチ音が鳴る」といった不具合報告みたいなものをチラホラ見ますが、iPhone/iPadの場合、指の接地面積が大きすぎることが原因でそういった現象が起きている筈です。
タップするのは、置きプレイの場合は指先の肉の部分(爪を短めに切った状態で画面につかない程度の位置)にすれば、こういった問題は改善できます。(親指勢の場合は左手親指は右側面、右手親指は左側面の先端付近の肉の部分)

③椅子の高さを調整する
置きプレイ限定の事ですが、タッチしている時、腕が地面と並行になる程度の高さに椅子の高さを調整しましょう。
かなり重要なことです。
この高さでないと、②で書いている指先でのタップがやり難くなったりします。
また、脱力もし難くなるのでプレイしていて疲れやすくなります。
ピアノを習った経験がある人なら分かると思いますが、この腕が地面と並行になる程度の高さというのは、ピアノを演奏する時の椅子の高さのことです。
例えば、TOKIMEKIエスカレートやOrange Sapphireなどのフルコンが取れそうで取れないというレベルの人は、椅子の高さ調整をするだけでアッサリとフルコンが取れるかもしれません。

④単発ノートをスタッカート奏法で処理する
単発ノートは、タップした瞬間にポンと弾ませるようにする(スタッカート奏法でプレイする)ことで、次のノートの処理が迅速にできるようになり、その結果、Master+クラスの曲などで出てくる高速パッセージのようなノートでも簡単に処理できるようになります。

ただし、下手にスタッカート奏法でやろうとすると、ヘンな力みが入ってしまい逆効果になるので気をつけたいところです。以下のサイト(ピアノ向けのスタッカート奏法のやり方)あたりを参考にすると良いです。
https://allabout.co.jp/gm/gc/448849/all/

上記サイトで挙げられているポイントを、デレステに応用した形に修正すると、

  • 指先を立て、iPadに触れる面積をできるだけ小さくする
  • 指先からiPadまでの距離をできるだけ揃える
  • 指先が硬いイメージをもつ(指先が小さなメタルや陶器のようなイメージ)
  • 手首をぶらぶらと上下に振りすぎない
  • 指先だけに意識を集中させず、肘でコントロールするイメージをもつと過度に力むことを防げる
  • 肩を上げない(上半身をかたくしない)
  • 軽く跳ね上げられた反動で次のノートをタップするように意識する

という感じになります。
これらのことをしっかりと意識して、まずはProや易しめのMasterの曲で試してみると良いかと思います。

⑤使う指
デレステのキー配置を (1)(2)(3)(4)(5) とすると、ホームポジションを
(1) 左手の薬指
(2) 左手の中指
(3) 左手の人差し指 + 右手の人差し指
(4) 右手の中指
(5) 右手の薬指
という風にします。

稀に小指も使います(左右両方使いますが、どちらかといえば左の方が良く使う)が、小指についてはデレステ(5鍵)であれば、使っても使わなくても運動量に大差は無いかもしれません。(5鍵なら5指使えば必要十分ですが、スライドで動かした後のノート処理で移動量を少なくするために小指を使います)

親指は、遊びで片手プレイをする時にのみ使います。

デレステは2指(人差し指のみ or 親指のみ)でもプレイ可能な配置しか無いので、6〜8指だと過剰かもしれませんが、使う指を多くした方が、目的とするキーを押すために必要な運動量を減らせるため、処理可能な曲の幅が増えたり、体力(ゲームのスタミナではなくプレイヤー自身のリアルなスタミナ)の消耗を抑えられるといったメリットがあります。

一応、親指勢でLv30フルコンとかしている人も居ますが、そういったプレイ動画を見てみると、明らかに無用な力みが入っていたり、運動量が無駄に多い(バタバタしている)ことが分かります。体力がある内はそれでも良いのでしょうけど、エネルギーを無駄に使いたくなかったり、より難しい曲をフルコンできるようになりたいといった場合は、6〜8指でプレイしましょう。

⑥端末について
一応、デレステの曲は全て2本指で処理可能なので、iPhoneでもiPadでも問題ありませんが、適正Lv27以上を目指す場合はiPadじゃないと(私は)キツかったです。
というか、6〜8指でのプレイはiPadじゃないと、画面が小さすぎて無理があります。
最低でもiPad miniのサイズが必要で、できれば9.7インチ or 12インチの方が良いです。

⑦別の音ゲーをプレイする(適正Lv28以上)
デレステの Perfect の判定は、かなりガバガバです。
だからこそ初心者でも気持ちよくプレイできるのですが、Lv28以上だとこのガバガバさが仇になって正確なノート処理できずにGoodやBadになって切れてしまうことが多くなるように感じました。
要するに、デレステのガバガバ判定に慣れてしまっていることがマズイのではないかと。
これを矯正する方法として効果的なのは、デレステよりも判定がキツめの音ゲーに慣れることかなと考えました。
そこで、他の音ゲーを色々と試してみたのですが、スクフェス(ラブライブ)のPerfect判定がデレステよりはシビアで良い感じでした。

Lv27強〜Lv28以上の曲で「何故、GoodやBadになったのか分からない」という場面を多々経験したことがある人は、例えばスクフェスのExpertをall perfectでクリアなどを目標にプレイする練習を取り入れることで、繋がるようになるかもしれません。(これはまだ私が秘密のトワレでフルコンを取るために試行中の段階なので、これで本当に上達できるかは不明)

2017年1月1日日曜日

課金をするでごぜーます

気長にスカウトチケット(3000円払えば無料でSSRをゲットできるという例のアレ)のリセットを待とうと思っていたら、まるで見計らっていたかのように元旦にリセットされたので、速攻で購入しました。

で、誰をスカウトするのか。

候補は12/29の記事で書いた、
①仁奈(ともだちたくさん)
②高森(てづくりのしあわせ)
③及川(はつらつハーヴェスト)
④相葉(束ねた気持ち)
の4人に絞ることができます。

ステータス的には、
vo:5,781, da:3,817, vi:3,169
vo:5,791, da:3,161, vi:3,812
vo:5,816, da:3,866, vi:3,218
vo:5,858, da:3,184, vi:3,845

何も考えずに④相葉で良さそうです。
④相葉は、SRでまずまず使い込んでいたので、育成手間という面でも割とお得です。

育成手間というのは、現時点で付いているファン数の少なさのことで、ポテンシャルを解放するには最低でも50万人(1属性maxするのに必要な最低数)揃えることが必要で、1曲のプレイで得られるファン数は(90万点ぐらいなら)だいたい1000人前後だから、少なくとも500曲プレイする必要があるということになります。(同種キャラクタの配置で減らすこともできますが)

という訳で現時点のファン数の降順で並べると、
②>④>①>③
で、②高森が一番多い。

②高森のSRが判定強化なので、Pa曲のフルコンを狙ったプレイ(粘着プレイ)でよく使っていたから、自然とファン数が多くなった感じのようです。
①仁奈は初期の頃に使い込んでいましたが、R止まりだったため最近は全く出番が無く、③及川に至っては編成した覚えが全くないという感じです。

しかし、スコア狙いであれば、単純にステータスの高さや現時点のファン数だけで見るのは不味くて、なるべく同系統&他キャラクタの特技の発動間隔と被らないようにする事が大事らしい。

そこで、今回の候補の特技を見てみると、
11秒毎、高確率でしばらくの間、PERFECT/GREATのスコア17%アップ
13秒毎、高確率でかなりの間、PERFECT/GREATのスコア17%アップ
6秒毎、中確率でわずかな間、PERFECT/GREATのスコア17%アップ
7秒毎、高確率でわずかな間、PERFECT/GREATのスコア17%アップ
という具合。

それらと、現状最強構成(以下a〜d)の特技発動との相性で見てみます。
a. コンボボーナス / 18%up / 7秒ごと / 高確率 / わずかな間
b. コンボボーナス / 18%up / 6秒ごと / 中確率 / わずかな間
c. スコアアップ / 17%up / 13秒ごと / 高確率 / かなりの間
d. スコアアップ / 17%up / 9秒ごと / 高確率 / 少しの間

コンボボーナス(a, b)はスコアアップと並走できるので考慮不要ですが、スコアアップ(c, d)は被ると無駄打ちになります。
だから、②高森(13秒毎)はcと被るため、候補から除外できます。

他は・・・パッと見ではよく分からない。

そこで、理論値を計算できるサイトで、現状の最強構成でポテンシャル+特技Lvをmaxまで育てた時の流れ星キセキの理論値を計算してみたところ、
①仁奈: 1207663
②高森: 1195138
③及川: 1211879
④相葉: 1207014
という感じでした。

あれ?
ダントツで相葉だと予想していたのですが理論値だと仁奈より低いのか。
高森は想像通り低くなりましたが。
単純にステータスだけ見れば④相葉で、特技相性から見ても④相葉を選ばない理由は無いと思っていたのですが、分からないものですね。実際、多少アピールが低くても特技構成を良い感じに編成した時の方がフルコン時の平均スコアが気持ち高かった気がするので、そういうものなのかも。

そんな感じで、様々なことを総合的に判断した結果、
さば・・・ではなく、仁奈をスカウト。

あとは、今やっているイベントを只管走り続けて、最強編成のファン数をモリモリ上げれば良いでしょう。今回のイベントは1/9迄で、ちょうど私の正月休暇が1/9迄だから、恐らく(初の)2000位以内が狙えるかもしれません。

2000位以内=SSSランクが取れる目安ということで。
SSSの場合、誰でも参加できるイベントと違って参加条件がキツイので、イベントで2000位以内よりはSSSの方が単位時間当たりで見れば楽なはず。(SSSの場合、測定期間が長いので、イベントが短距離走ならSSSはマラソンというイメージ)

今のところ3桁以内で走っています。
3桁以内で走れているのは Flip Frop以来。
その Flip Fropでは2000位以内入賞を逃しましたが。(2021位)


今回はMaster+のフルコンも期間中に狙えると思うので、ハイスコアランキングでも初のトロフィーを狙えるかもしれません。(というか、ハイスコアを狙っていない安全な編成でMasterをフルコンしただけのスコアで、既に銅トロフィーが狙えそうな位置に居るような気がする)

イケると思っていたFlip FropのMaster+のフルコンを取り逃しているので、Master+のフルコンが本当にいけるのかは、結構怪しいところですが。(Flip Fropと違って前座で3曲やらないといけないイベントだから、更に怪しい)

色々な意味で Flip Frop の雪辱を果たす良い機会かもしれません。

2016年12月29日木曜日

いけそう

デレステでPRP1,000獲得の為、昨日フェスでガチャを100連ほど回し、無事フェス限定SSRを3枚ほどゲットした(参照)ので、これで1,000に届く確認するため、試しに流れ星キセキ(Lv26)でフルコンしてみたのですが、
強い。
※Greatが多いのは気合の問題です

従来編成では全てを完全にALL OUTし尽くして94万でしたが、まだ全然(特技Lvが)育っていない状態 & Great多めのやる気が無いプレイで、アッサリと+4万点も超えてしまった。

こ れ が 金 の 力 か !

これなら、PRP1,000狙いは特技Lvを育て切れば余裕だろうと思います。

なお、この時の編成は、
①渋谷/オーバー・マイセルフ(Co/Vo), 特技Lv6, ポテ解放=16
②ウサミン・ザ・シークレット(Cu/Vo), 特技Lv5, ポテ解放=3
③杏/ぐうたら王国(Cu/Vi)特技Lv10, ポテ解放=20
④みく/キャットパーティー(Cu/Da),特技Lv9, ポテ解放=9
⑤なつきち/Jet to the Future(Pa/Da), 特技Lv10, ポテ解放=11

というアピール値的にはかなり微妙なもの。
ゲストにトリコロールボイスを持ってきてギリギリ30万点に届かないぐらい。

編成を特技で並べてみると、
①コンボボーナス / 18%up / 7秒ごと / 高確率 / わずかな間
②コンボボーナス / 18%up / 6秒ごと / 中確率 / わずかな間
③スコアアップ / 17%up / 13秒ごと / 高確率 / かなりの間
④スコアアップ / 17%up / 9秒ごと / 高確率 / 少しの間
⑤オーバーロード / 16%up / 9秒ごと / 中確率 / しばらくの間

⑤(オバロ)はテストランのつもりだったからチキン配置です。
Lv10のコンボボーナス持ちのSR/Pa(何体か持っている)を突っ込んでいれば、現時点の編成で100万点に届いたかも。

それでも、SSSを狙って走る時の時短のために、SSRの特技Lv10化はしますが。
ただし、餌が無いのでキャラバンやライブパーティー待ちです。
それまでの間にPaの枠を何とかしておきたい。

Voが強いPaで、尚且つコンボボーナス持ちであれば最強ですが、そうなると月末復活かフェス限定狙い(よく調べてませんが、多分グロリアス★グロウ1点狙いかな?死ねる)で期待値が薄いので、そこは妥協してスコアアップでも良いかなと。(オバロでも100万に乗りそうだったので無理する必要もない)

そうなると候補は、
・仁奈(ともだちたくさん)
・高森(てづくりのしあわせ)
・及川(はつらつハーヴェスト)
・相葉(束ねた気持ち)
辺りになりますが、これらをタイプセレクトで狙うにしても確率的にキツイのでスカチケを待つのが賢明かな。(ただし、年明けの宝くじは期待値ほぼ0だと思っている)

パッションが足りない

夏頃プレイを始めたデレステですが、昨日SSランクに昇格。
ここまで来たらSSSランクを1回は取っておきたいところですが、今の手札(恒常SSRの杏、みく、渋凛)では参加条件のPRP1,000を満たすのが難しい。

このSSRだと、全タイプのLv27〜28をフルコンして運が良ければ100万点に届くので、それをx10曲やれば届きそうですが、条件に合う曲が3曲(m@gic, evermore, goin'!!!)しか無いので、難しいというか無理ですね。

そんなタイミングで、狙いすましたかのようにシンデレラフェスが始まる。
フェス限定を1体でも入れれば、多分Lv26でも届きそうなので、課金して石を仕入れてガチャを回すことにした。

まず、20連でウサミンを引く。

えぇ...

いや、ウサミンは悪くないです。
問題はステータス(Vo)。
手持ちのCu系SSRは、杏(Vi)、みく(Da)で見事に割れてしまっている...
Viだったら、その時点で辞めれたのに。

という訳で、更に回してみたところ、60連目で周子を引く。

えぇ...

いや、周子は悪くないです。
問題はステータス(Da)。
手持ちは全般的にDa系の強いアイドルが居ないので、ステータス強化目的という意味ではハズレです。(強いアイドルとは...)

恐らく、もう1枚(Pa)が壁かー、などと考えつつ、更に回してみたところ70連目で初のSSR確定封筒が出る。
「100連未満で今回追加のフェス限定アイドルが全部出てくれれば悪くはない」
などと考えていたのですが、出たのは渋凛でした。(興奮してスクショは撮り忘れた)

これは大当たりです。
今回引いたウサミンと組ませて、特技LvをMaxまで育てれば、Lv26のフルコンとかで簡単に(100万点に)届きそう。

あとは、PaのSSRが1枚引ければ最強ではないかね?という悪魔の囁きに耳を貸し、トータル110連(約3万円)回しましたが、結局出ませんでした。
最初っから100連回すつもりで石を購入済みだったので問題ありません。
(10連余分に回しているのは無料石を使ったのでノーカン)

確率的にはキレイにだいたい3%。
提供割合の表示通りですね。
実際のところ100連回して3枚引けるのは60%ぐらいとかなので、まぁ良い方ではないでしょうか。

今回のガチャでSSRがトータル6枚になりましたが、CuとCoしか居ない偏った状態です。これって案外こういう風になるようにコントロールされているのではないかと勘ぐってしまう。(キレイにバラけるよりも、ある程度偏らせた方が運営サイドの収益性が良くなる筈なので)
※鍵を付けているのがSSR
そして、謎の渋谷率。
仕方がないので渋谷担当を名乗っておくことにしました。
なので、Trancing Pulseはフルコンしておこう(もうちょっとで出来そう)

ちなみに、累計の課金額は6万円ほど。
旧来のコンシューマゲームだと1本のゲームに6万とかあり得ないですが、デレステをプレイし始めてだいたい100日ちょっとで、コンシューマゲームだと1本のゲームで100日以上遊べるものはそうそう無いから、妥当な額かなと。

2016年12月18日日曜日

ゲーム機エミュレータの技術的な話

割と古めのエミュレータのソースコードを眺めてみて、プラットフォーム依存(主にWindows依存)の実装がモリモリと入っているものが多いなと。

エミュレータのコア部分は、必ずしもプラットフォームに依存する必要はなくて、Cの標準ライブラリやC++のSTLだけで実装できるものです。

何処までがプラットフォーム非依存(PIL)で、何処からがプラットフォーム依存(PDL)か。
その線引は、以下のようになります。

【プラットフォーム非依存】(PIL)
・CPUなどのエミュレーション全般
・プラットフォーム依存(PDL)間のブリッジ

【プラットフォーム依存】(PDL)
・映像出力
・音声出力
・入力機器からの入力

コードで書いた方が分かり易いので、LaiNESというファミコンエミュレータの実装をベースに見てみると分かり易いです。

オリジナルのLaiNESは、PIL と PDL が若干入り乱れているので、純粋な PIL だけを切り離した LaiNES を私の方で作ってみました。
https://github.com/suzukiplan/LaiNES

上記のSUZUKI PLANカスタム版LaiNESは純粋なPILのみ実装している キレイなエミュレータ なので、ターミナル上でファミコンを動かすこともできてしまいます。上記リポジトリのtest.cppが実際にターミナル上でファミコンを動かすプログラムの例です。

ファミコンを動かすといっても、ターミナル上でPDL(の全て)を再現するのは厳しいので、PDL部分(namespace HALの部分の実装)はダミーですが。

それだとあんまりなので、このSUZUKI PLANカスタム版LaiNESを用いてAndroidでPDLを実装してみた例も作ってみました。
https://github.com/suzukiplan/nes-view-android

なお、動作についてはPublic DomainのROMで確認してます。

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...