FreeBSD機上で実行したら、登録サイト全スキャンが走ってしまいました。調べてみたら、リミッタがまともに働いていませんでした。早い話、バグ。
ところで、何故Perlのバージョンが5.005_03なんでしょう。
謝られてもなあ。
夜になってから頭痛。原因はきっとアレです、昼間にアニメを12話分ぶっ続けで見たから。
今ごろになって、Linux機とFreeBSD機間でrcpできないことに気づきました。
rcmd系ってtcpdなんだっけ。inetdでごちゃごちゃやりたくないんだよなあ…
ていうか、何でrshdがインストールされてないのですか、Vine。
試験稼動開始。不定期更新。
今週アニメまみれ。
デフォルトでジョイスティックに対応してないので、ジョイスティックプラグインを作成すべく奮闘努力するも、撃沈。明日に持ち越し。
Layerを継承してスプライトを作成。ウィンドウサイズ640*480、たかだかスプライト数256でCPUがヒーヒー言ってるよ…スクリプトじゃしょうがないか…
60FPSを実現するには、0.0166秒以内に描画を含めたすべての処理を終わらせなければならず、終わらない場合は次の描画タイミングまでわざと待って「処理落ち」としたい。
本当はディスプレイの垂直表示期間に演算と裏バックグラウンドレイヤーの描画を終わらせて、垂直帰線期間にバックグラウンドレイヤーの切り替えを行いたいのだが、Windowsではリフレッシュレートが60とは限らない(環境依存)ためにこの技法は少々使いづらい。垂直同期に対応したイベントがあればいいのだが。いや、吉里吉里が内部的にやってくれているかも知れない。
表と裏の2つの親バックグラウンドレイヤーを切り替えることでダブルバッファを実現し、表示更新時のちらつきを防止しようとしたのですが、Layer#parentプロパティで親を切り替え(つまり代入)すると、実体をコピーしてるんじゃないかと思うほど遅くて使い物にならず、ポインタ渡しじゃないのかよーと文句を垂れながら結局一つのスプライトにつき表用と裏用の2つのレイヤーを持たせるという、KAG3のサンプルに付属のsnowプラグインでやってることとほぼ同じ形式にしました。なんか、かっこ悪いな。
見つけました。ジョイスティックプラグイン。Borland C++ Builder(フリーのやつ)とかDirectX 9.0b SDKとかSDLとかインストールしてがんばったのになあ。ま、いいや。
空気がべたべたしてて気持ち悪いです。もう梅雨入りですか(違)
吉里吉里 v2.21 beta 4 からはジョイスティックが使える模様。ソースを見た限りでは、DirectInput使用してるみたい。内部実装だからプラグインよりも軽いだろうということで、こっちを採用。β版だけど気にしない。
タイマーイベントの発生タイミングがおかしい。インターバルを5msにしても16ms間隔でイベントが発生したり所々で31msになったり、20msにしても発生間隔が16ms, 31msごちゃ混ぜになったり。ディスプレイのリフレッシュレートの倍数と奇妙に一致しているのは気のせいか。
たかだかスプライト数256でCPUがヒーヒー言って
いたのは、待ちイベントがエンキューされまくっていたせいかも。イベントキュー・キャパシティを1にすれば解決…かと思ったが、そううまくはいきません。
利用者が違法コピーするのを可能にしたとして著作権法違反幇助の疑いでインターネット発案者を逮捕、とかいろいろ思い浮かぶんですが、この辺は【Winny】一斉逮捕のガイドライン【幇助】が面白いかと。
来るところまで来たか、といった感じ。
暑いですねー。もう梅雨明けですか(違)
インターバルを16ミリ秒にして、イベント発生時刻と前回イベント発生時刻の差を採ってみた。
… 15 16 16 15 16 16 15 16 31 16 15 16 16 15 16 31 31 16 16 15 16 15 16 16 …
所々に31ミリ秒の空白ができており、その時におそらく一回分のイベントを採り逃しているものと思われる。タイマー周りのソースを読んだところ、enabledプロパティ変更時にタイマカウンタをリセットしているようなので、これを利用してみる。推奨できるやり方ではないが。
function onTimer() { timer.enabled = true; // ... }
これをやると、結果的にタイマイベント1回につき1回分破棄されることになるようなので、16ミリ秒間隔でイベントを発生させたい場合はタイマオブジェクトのintervalを8msにしてやらないといけない。
… 15 16 15 16 16 15 16 16 15 16 15 16 16 15 16 16 15 16 15 16 16 15 16 16 …
稀に取りこぼして31msになることもあるが、頻度としては問題ないレベル。
timer.enabled = false は不要。というより、そもそもWindowsタイマの限界なのかも。
正弦を求めるのに、Math.sinを使った場合と正弦テーブルを使った場合とで実行速度を比較。最終的には角度も算出値も整数に正規化して使う予定なので、テーブルの方は予め正規化したものを使用。テーブルといってもただの配列(Array class)なので、当然こっちの方が圧倒的に速い。単純forループ(100万回)での測定で、Math.sinでの算出法より恒常的に3倍以上速かった。
明日は逆正接テーブル。逆正接は正規化が面倒なんだよなー。
長さんに、イワエモンさんに、…
今年は何かに呪われているような気がします。
某氏の指摘でFTPサーバ用のHDDが使用率100%になっていることに気づきました。ディスクの状態を見てみると、パーティションサイズと使用量が一致していないのに使用率が100%になっていてなんじゃこりゃーな状態。inode絡みかなーと思い、FTPサーバを止めてアンマウントしてfsckをかけたところ、案の定inodeがイカれてました。
前もinodeがダブっててエラー吐いたことがありましたねー。ext2って、どこかアレだよなあ。カーネルがアレなのかなあ。
せっかくだから、inetdでキックしていたFTPサーバをStand-alone型にしました。
逆正接テーブルを作ろうと思ったが、頭痛がひどいので、以前JAVAで書いたソースを確認しただけで終了。あと、ブレゼンハムのアルゴリズムをおさらいしておく。ブレゼンハムのアルゴリズムは線分描画にだけ使われるものと思われがちだがデジタル微分解析の一種であるブレゼンハムのアルゴリズムの本質は整数値の線形的離散的変動解析であってこの性質が線分描画だとか自機を狙って直進する敵弾の弾道計算だとかに応用されるのだからその本質を見抜きさえすれば応用先が画像処理に限らないことは明白なのである云々。
頭痛なんだから早く寝なさい。俺。
著作権法の名の下に、Webサイトでソフトウェアの使い方を解説したら家宅捜索されたり、CDの輸入が無差別に禁止されそうな今日この頃。
蒸し暑いですね。
置く場所がありません。
三角形が大好きな良い子のみんなは三角関数と聞くと円を連想するが、ここでは円の出番はない。
直交座標軸に平行な、一辺の長さがNの正方形の左下の点をO、右下、右上、左上の点をそれぞれA、B、Cとする。点Pが線分AB上にあるとき、APの長さをa、角POAの大きさをθとすると、
θ = arctan(a/N) .
点Pが、点Cを除く線分BC上にあるとき、CPの長さをcとすると、
θ = arctan(N/c) .
点Pが点Aから点Bを経由して点Cまで移動するとき、点P(px, py)の位置が離散的、つまりpx, pyが整数値しか取らないとすると、点Pの取りうる位置は (N, 0), (N, 1), ..., (N, N-1), (N, N), (N-1, N), (N-2, N), ..., (1, N), (0, N) の2N + 1箇所。それぞれの点をP[0], P[1], ..., P[2N]とするとき、各点P[n]における角θ[n]は下記の通り。
θ[n] = arctan(n/N)
θ[n] = arctan(N/n)
θ[n] = π/2
θ[n]を要素数2N+1の配列と見なして、第一象限の逆正接テーブル完成。
何で「象限」を変換できないんだMS-IME。
第一象限上のある点をE(x, y)、角EOAをωとすると、
ω = θ[m]
が成り立つ。mは配列θにアクセスするためのインデックスであり、以下に示すxとyの関数Mによって定まる。 *1
int( Ny/x )
int( N(2-x/y) )
2N
以上をまとめると、
ω = θ[M(x, y)]
となる。第二、第三、第四象限についても基本的に同じなので省略。
これを関数化して、
function arctangent(x, y) { // ... 面倒なので省略 return omega; }
といった感じ。
しかし、実はインデックスを求めるM(x, y)には、象限による分岐、xとyの大小関係による分岐、ほとんどのケースで必要となる乗算&除算など、意外と重い処理になってしまうという大きな落とし穴がある。これをどう回避するか、元を辿ればインデックスと角度の関係をどうするかによって arctangent(x, y) の実行速度は変わってくる。下手をすると、インデックス値の算出に膨大な時間を消費してしまい、Math.atan() 一発の方が速いという目も当てられない状態にもなりかねない。
続きは明日。
ディスプレイのリフレッシュレートの倍数と奇妙に一致しているのは気のせい
でした。が、インターバルを5msにしても22msにしても、15msか16msの倍数単位でイベントが起こる。Timerの精度がnormalだからなのだろうが、精度を上げるとCPU負荷も上がるしなあ。
-waitvsync や -dbstyle を使用するとCPUの負荷が急上昇。反って動作が重くなった。X680x0だったらI/Oポートを直接叩けば垂直同期待ちが簡単にできるんだけどなー。とか言ってもしょうがないんだけど。
第一象限上の点については算出可能なので、次は座標上の任意の点F(x, y)について考えてみる。逆正接テーブルは、全象限に対応したものが作成されているとして話を進める。第一象限のケースでは、正方形OABC上の点P(つまりインデックス)はA→B→Cと、原点Oを中心に左回りに進むものとしているが、他の象限でも同様に左回りとする。
インデックスの算出方法はいくつかあるだろうが、ここではx, yの絶対値を使ってインデックスmを求める。
まずはx=0またはy=0のケースを特例として扱い、除外する。
m = 2N
m = 6N
m = 0
m = 4N
次にx, yの絶対値を元に仮のインデックスm'を求める。この計算式は、第一象限でのケースと基本的に同じである。 *1
m' = abs(int( Ny/x ))
m' = abs(int( N(2-x/y) ))
最後にm'を、F(x, y)の位置(象限)によって補正し、インデックスmを求める。
m = m'
m = 4N - m'
m = 4N + m'
m = 8N - m'
実際のコーディングにおいては整数演算のみになるだろうから、乗算と除算の入り混じっている箇所では演算順序に注意して精度を保つようにする。以上。
…さすがにこれだけの分岐があると、辛いかも。コーディング量がそのままパース量に跳ね返ってくるわけだし。10回や20回の実行ならともかく、秒間数千回も実行されるような場合は少なからずCPUパワーを殺ぐ事になるわけで。
ちなみに、このテーブルの長所は、参照時に実数演算が不要なことと、(整数の割には)精度がかなり高いこと。短所は、インデックスの算出が面倒なこと。
逆正接テーブルのインデックス算出をTJS2でやるのもなんだし、DLL形式のプラグイン制作の練習も兼ねて、吉里吉里プラグインを作ってみた。テンプレートを作っておき、新規にプラグインを作るときはテンプレートから起こすのが楽だろう。
ちゃんとDLLが作成されたら、テンプレートの出来上がり。テンプレートとしては、吉里吉里ソースからコピー&改変した4ファイル以外は不要なので、それらを削除。新規にプラグインを作成するときは、このディレクトリを丸ごと新規ディレクトリにコピーして、それを叩き台にすればよい。
以前JAVAで作ったブレゼンハム関連のソースを、TJS2に移植。たいした量じゃないのですぐに終わる。何でこんなものが要るのかといえば、線分を描く関数を作るためで、実は吉里吉里(v2.21beta8)には線分を描く機能がなかったりする。また、円を描くことも点を打つことも、標準ではできない。あるのは矩形塗りつぶしのみ *2 。無いものは作るということで、TJS2で実装。だが遅い。
ブレゼンハムのロジックそのものはC++で実装して処理速度を稼いでもいいが、いかんせん描画そのものが遅い(矩形だし)ので、全体的な速度向上にはならないかも。まあ、ブレゼンハムのアレはほかにも使い道があるから、プラグインとして作っておいても無駄にはなるまい。
…プラグイン関数から配列を返すにはどうすればいいのかな。
調子に乗って円を描く関数も作る。これはミッチェナーのアルゴリズム。某ソースからのパクり。
プラグインを改良。逆正接テーブルをDLL内部に持つことで、TJS2側からはarctan(x, y)
みたいに呼べるようになった。単純にコールするだけだと、TJS2関数のMath.atan()よりも二割ほどしか速くないが、実戦においては、Math.atan()はコールしたあとに象限判定や整数補正などの処理を追加しなければならないため、実戦での速度パフォーマンスは数倍〜十数倍の差が出るだろう。実際、Math.atan()に単純な整数補正を加えただけでも4倍ほどの差が出た。まあ、用途が特化、限定されているから、汎用のものより速くなるのは当然なんだけど。
ついでに、正弦と余弦、距離算出関数も追加。距離算出には、平方根を使わない方法にした。原点と点(x, y)との距離は、三平方の定理からSQRT(x^2 + y^2)で求められるが、平方根計算は嫌なので、x / cos(arctan(y/x))でやる。cosもarctanもテーブル化してあるからさほど重くはないだろう。
吉里吉里プラグインとして関数を作成するときには、関数一つにつきクラスを一つ作ることになるので、コードを書くのがちょっと面倒。また、プラグインリンク時、アンリンク時の手続きも少々面倒なのだが、決して難しいわけではない。吉里吉里にはコメントのたくさん入ったわかりやすいテンプレートがあるから、それを真似、というかほとんどコピーすれば、割と簡単にプラグインを作れる。このあたり、開発者にやさしいと思うのだが、どうだろう。
プラグイン関数から配列を返す
のではなくて、プラグイン関数にTJS2 Arrayオブジェクトへの参照を引数で渡し、プラグイン関数はその参照に対して操作を行う、という形式ならいけるかも。
セブンイレブン。
受け取った袋にはちゃんと割り箸が入っていました。これで累計三回目です、セブンイレブン。人の話をぜんぜん聞いてません。
あー、もしかして、「結構です」ってのがまずかったですか。「要りません」と言ったほうがいいですか。いや待てよ、割り箸を袋に入れるという動作は、実はレジ打ちという一連の動作の中に埋め込まれていて、レジ打ち関数を呼び出すとまるで常に発動する副作用のごとく作動してしまうのかもしれません。通常は、引数として受け取っているはずの割り箸フラグによって条件分岐するはずなのですが、この辺のロジックに不具合があると割り箸が入ってしまう可能性があります。
とか、くだらないことを考えながら店を出ました。
今日こそ早く寝よう。
べたべたと蒸し暑いですねー。
Plugins.link("foo.dll");
とするとネイティブクラスFooを使えるようになってTJS2からvar foo = new Foo();
みたいに呼べるといいなと思ってTJS2ネイティブクラスを実装しようとしたが、C++名前空間の壁とかいろんなものに阻まれて撃沈。少なくとも、既存のプラグイン作成テンプレートそのままでは使えないようだ。
憂さ晴らしに矩形接触判定関数を作る。接触しない条件を考えてみれば話は簡単。
マニュアルを読んでいたところ、iTJSDispatch2を実装すればできそうな気がしてきた。明日、じっくりやってみよう。
さすが、面白すぎですマイクロソフト。いついかなる場所でもネタを忘れません。
吉里吉里2.21beta8のソースを読んでいたら、drawLine() なる関数を発見。ずばり、レイヤーに直線を描画するプラグイン関数のようだが、完全に実装されてないように見える。Blurの使いまわしのような…
こいつを雛型にするくらいのことはできそう。C++内でのレイヤーオブジェクトの扱い方は参考になるかも。
DLLプラグインでクラスを。
tTJSDispatchを継承してゴニョゴニョすれば何とかなりそうなのだが、「ゴニョゴニョ」の具体的な内容が見えてこない。天下のGoogle様で検索したり、いいサンプルはないかと吉里吉里ソースをひっくり返して探してみたりしたが、見つからなかった。CreateNew()を実装することが、クラスオブジェクトとして振舞うための初めの一歩だと思うのだが…わからないことがたくさん。メソッドをFuncCall()で受け取ったときの振る舞い方――FuncCallByNum()のラッパーとして振舞えばよいのだろうか――、これもよくわからないし。むー。
寝る前に文庫本のマリみてをぱらぱらとめくって斜め読みしたんですが、目や脳が拒否反応を示します。やはり耽美系は体が受け付けないようです。まあ、無理に読むことないし。
TJS2側で作ったクラスを、C++側で扱うテスト。とりあえず、クラス名を取得することはできた。明日はプロパティの扱いやメソッド呼び出しなんかをやってみる。予定。
TJS2側で作ったクラスを、C++側で扱うテスト。受け取ったオブジェクトのプロパティを扱う練習。練習ついでに矩形同士の接触・交差判定処理をC++で実装してみた。といっても、判定処理自体は一行で書けてしまうほど簡単なわけで、要はあれあれ、ネイティブ実装してみたかっただけ。
プロパティと関数、どっちが速いかを簡単にテストしてみた。単にforループで100万回くらいget, setを繰り返しただけ。結果、単純な値のset, getでは、プロパティ経由のほうが1割くらい速かった。まあ、forループ自身のコストを無視しているので誤差は結構大きいかもしれないが。
ついでに、矩形接触判定処理をC++(DLLプラグイン)で実装した場合と、TJSで実装した場合の実行速度を比べてみて、実はTJS実装の方が1割ほど速かったという結果を見て愕然とするテスト。
DLLプラグイン呼び出しが遅いのは、実際にやりたい処理が極小なのに対して、呼び出しのオーバーヘッドが大きいからなのだろう。まあ、この結果は予測の範疇ではあったのだが。DLLプラグインは、使いどころを見極めないと。
たったこれだけでCPUパワー *1 を50%近くも消費しているのをタスクマネージャで確認して愕然としてみるテスト。んー、これじゃゲームにならんな。
「ヤンマーニ」ばかりが有名になってなんだかアレですが…
主に偶数話に登場する電波全開の御主人様マーガレットと、素敵過ぎるメイドのエリノアさん。この二人の言動を見て楽しむアニメ、それがMADLAX。
ちなみにnowhereはいい歌ですよ。
オブジェクトプールを高速化。あと、使用中のオブジェクトに対してobj.recycle();
とすることで、然るべきPoolに帰るようにした。
サクラエディタ用のマクロを作りました。内蔵の補完機能だけではできないことをやりたかったので。
サクラエディタ用マクロの実装方法として、pascal, VBScript, JScript 等がありますが、外部ファイルを扱う必要があるため、VBScript(+ WSH)で実装することにしました。VBは文字列処理能力が貧弱なので、コーディングは少々面倒です。PerlかRubyに対応していれば、喜んでそちらを使うのですが。
DVD-Rとか本とか光ケーブルとかいろいろ買ってきました。吉里吉里の本は、内容がKAGに偏っていたので買いませんでした。今のところ、KAGにはあまり興味がないのです。
70へぇ。
はい、こんにちは。
プラネタリウムに結構な旅行が進みそして「morph」にストレート outer space に見出されるロケットへ乗っているバスを含みそして彼女がどんなここで見出しかもしれないに関して手掛かりを使わないで教師を次に失うのを想像します。
どなたか、この怪電波を日本語にデコードできる方、いらっしゃいますか?
太陽系を検索
する前に、まずは御社サイト内のおかしな文章を検索していただければと思います。
20〜30行程度のVBScriptマクロひとつでここまで出来ます。それなりの仕込みは必要ですけどね。
そういえば、まだコンパイルしたことないですね…(ぉ
ムービープレイヤーを作ってみた。といっても、VideoOverlayクラスを使えば楽勝なんだが。現状、DivX5を再生できない、オープン中は再生サイズを変更できないなどの欠点はあるが、Macromedia Shockwave Flashプレイヤーとしては十分。
人の首とか腕とか脚とか、いろんなものが千切れて飛んでいくこの作品が、テレビアニメ化されるようです。どう表現するんでしょうね、あのシーンとか、あのシーンとか、あのシーンとか…
JavaScriptが有効でないと何も出来ないサイト。elfen liedのサイトとかLASTEXILEのサイトとか。なんか、門前払いを喰らった感じがして、実に不快です。
- Q.
- 「ロストユニバース」の第4話は、TV放送時のものではありませんでした。TV放送時のソースを放送する ということではなかったでしょうか?
- A.
- がっかりさせてしまったのは、ごめんなさい!
それはがっかり。日本全国十億人のヤシガニファンはさぞ落胆したことでしょう。
延々とこればかりやっていたような気がします。
2ボスの暗闇、あれは卑怯です。1ボスのラストスペルもかなりアレです。
とりあえず、博麗霊夢(NORMAL)で3.5億。
自作のフレームワーク周りを整理。骨組みがもろくてはビルが建たないわけで。
暑いです。もう夏ですか。部屋の温度計は35度を示しています。まだ五月だというのに…暑さに耐え切れず、クーラーをつけてしまいました。
今年、初クーラー、初冷麦。
ここ1〜2ヶ月、CDプレイヤーの「開けたら閉まる」現象が再発しています。暖かくなると起こるようです。困ったものですね。
プールを継承して弾丸プールを、銃を継承してハンドガンとショットガンを作成。ショットガンのパラメータをちょいと弄るだけで全方位弾が出来上がるし、ハンドガンの発射間隔、リロード時間、初速度誤差(速度のばらつき)、命中精度誤差(下手くそ度)を弄ればアサルトライフルになるのだが、それはまた別の話。この2タイプを元にすれば、大抵の弾幕は作れる。かもしれない。
相変わらず自機の弾がない、って別にシューティングゲームを作りたいわけじゃないんだが、なぜかシューティングになってしまう。まあ、世の中そんなもんだ。
ていうか、何だこれ。
- "。男性を言う何"。
- "。全フル kinja を与えるはい"。
- "。。記憶する"。
句点で始まる文章って初めて見ました。
レーザーのような直線ベースのオブジェクトと、矩形ベースのオブジェクトとの接触判定方法を考えてたら、どうにも面倒くさそう。
のどちらかを満たせば、交差すると言えるのだが…すべての条件が偽にならなければ、全体として「偽」とはいえない。統計的に、ゲーム中には接触判定が偽になるケースのほうが圧倒的に多いため、意外と速くはないのかも。
円と線分の交差・接触判定方法を考える。単純に考えると、円と直線の不等式から交点を算出して…ということになろう。が、ちょっとひねって考えてみると、円の中心点と直線との距離が、円の半径よりも大きい場合、絶対に交わらないといえる。この命題を利用して、真っ先に交わらない場合を除外してしまえば、ゲームにおいては意外と速いかも。
さて、どうしたものか。どっちにしても、計算が多いことには変わりないから、実装はC++になるだろうな。
画像を回転させて保存するプログラムを作る。吉里吉里のアフィン変換で梃子摺った。まあ、いろいろと。高校数学は大事ってことだ。