###############
# SWFビューア #
###############

「SWF形式」のFlashムービーファイルを、P/ECE上で再生します。

================
インストール方法
================

1. 「swfplay.pex」を、P/ECEに転送してください。
2. SWFファイルを、P/ECEに転送してください。
   SWFビューアは、ファイルの内容を見てSWFファイルかどうかを判断しているので、拡張子は何でも構いません。

========
操作方法
========

上下ボタン　　　　　　ファイルを選択します。
Ａボタン　　　　　　　ファイルを決定します。
Ｂボタン　　　　　　　メニューを消します。
ＳＥＬＥＣＴボタン　　プログラムを終了します。

========
あとがき
========

SWF形式の勉強をしながら、P/ECEでSWF形式のFlashムービーファイルを再生する、SWFビューアを作りました。
非常に限定した機能にしか対応できていなくて、以下のような制限があります。

・SWFバージョン4の、ごく基本的な機能までの対応です。
　ファイルの中に、対応していない機能のデータがあったら、読み飛ばして再生を続けるように作りました。
　SWFバージョン5以上のファイルでも一応再生しますが、機能不足で正しく再生できない可能性が高いです。

・テキストは、ダイナミックテキスト形式のみ対応しました。
　テキスト描画の、拡大・縮小・回転は、対応していません。
　フォントサイズは、P/ECEに特化した方法で、データを解釈するように作りました。

・グラフィック素材の描画だけに、対応しています。(ムービークリップでもokです。)
　ベクトル図形の描画は、対応していません。

・サウンドは対応していません。

・アクションスクリプトは、playとstop、および、ターゲット指定だけ対応しています。
　それ以外のアクションスクリプトは、すべて読み飛ばします。

制限が多すぎて、Webで公開されているSWFファイルを見るために使うのは、かなりキビシイです。
あらかじめ制限を意識してSWFファイルを作成して、ゲームの演出で再生するような使い方ならできそうです。

SWF形式の勉強をしていて難しいと感じたことは、Flashツールの違いによって、生成されるSWFの内容がかなり違うことです。
「ParaFla(http://www.geocities.jp/coa9999/)」や「Suzuka(http://www.cty-net.ne.jp/~uzgensho/)」などのフリーツールは、比較的素直で判り易い構造のSWFファイルを生成します。
一方、本家「Adobe Flash(http://www.adobe.com/jp/products/flash/)」は、ツール上の見た目の構造と対応しない、複雑なSWFファイルを生成する傾向があるようです。
たぶん、「Adobe Flash」の方が高度に最適化したSWFファイルを生成するために、複雑になってしまっているのだと思います。
また、「Flash MX」のような古いバージョンのFlashは、既知の不具合(仕様?)を含んだ画像データを生成してしまったりして、扱いづらいです。
SWF形式を勉強する場合は、理解しやすさのために、まずフリーツールでSWFファイルを作って見る方が良いと思いました。

まだまだSWF形式について理解不足なのですけれど、ここまでのところで特に難しいと思ったのは、以下の点でした。

・同じ深度に複数のオブジェクトを置くことができる。
　SWF仕様書の説明を読むと、ひとつの深度にはひとつのオブジェクトしか置けないように受け取られるのですが、実際には複数のオブジェクトを置けてしまいます。
　PlaceObject2タグの、PlaceFlagHasCharacter=1、かつ、PlaceFlagMove=1の組み合わせによるものですが、挙動が直観的でなくて理解しづらかったです。

・DefineBitsJPEG2タグやDefineBitsJPEG3タグのデータは、普通のJPEGファイルとは違う構造の場合がある。
　「Flash MX」のような古いバージョンのFlashでSWFファイルを生成すると、DefineBitsJPEG2(3)の中のJPEGデータが、分断された構造で格納されるようです。
　普通のJPEGファイルと同じようにデコードしようとすると展開できず、JPEGTablesタグ＋DefineShapeタグの場合と同様に考えて扱わないと正しく展開できません。

・静止したグラフィックシンボルは、ひとつのシェイプにまとめられる。
　「Adobe Flash」の特性として、複数のグラフィックシンボルが画面上で静止していると、それらをまとめてひとつのシェイプに定義してしまうようです。
　最適化のためだとは思うのですが、オブジェクトが動いているか動いていないかで、データの階層構造まで変わってしまうことに戸惑いました。

備忘録として、次回、それぞれの内容をもう少し詳しく記録しておこうと思います。

==================
Fri Jun 12 2009
Naoyuki Sawa
nsawa@piece-me.org
==================

--------------
2009/06/27追記
--------------

バグ修正しました。

・テキストが改行されないことがあるバグを修正しました。

具体的には、Suzukaで作成したSWFファイルならば改行されるのですけれど、Adobe FlashやParaFlaで生成したSWFファイルの場合に改行できていませんでした。
原因は、ツールによってテキストの改行コードが違う点を、見落としていたことでした。
・Suzukaは、テキストの改行コードとして、LF(&h0A)を出力します。
・Adobe FlashとParaFla!は、テキストの改行コードとして、CR(&h0D)を出力します。
Adobe純正のFlash Playerが、どの改行コードでも正しく改行して表示するところから推測すると、SWFファイルの仕様に改行コードの決まりは無いみたいです。

今回のバージョンアップで、改行コードがCR(&h0D)でも、LD(&h0A)でも、CR+LF(&h0D,&h0A)でも、改行するように修正しました。

==================
Sat Jun 27 2009
Naoyuki Sawa
nsawa@piece-me.org
==================

--------------
2009/08/22追記
--------------

・親タイムラインがループしたときの、ムービークリップの継続動作を修正しました。

前回までの版では、親タイムラインがループするときに、その上に置かれているオブジェクトをすべてリセットしていました。
これは正しくない処理で、たとえば、親タイムラインよりも長いムービークリップを置いた場合に、不具合が生じていました。
親タイムラインがループしても、ムービークリップはそのまま継続しなければいけないのですが、前回の版では、ムービークリップも巻き戻ってしまうのです。
今回の版で修正し、親タイムラインよりも長いムービークリップが、親タイムラインのループに影響されず、継続するようになりました。

テスト用に、「お散歩スフィー」のサンプルムービーを作ってみました。
・メインタイムラインは、4フレームでループします。各フレームで、「1/4」「2/4」「3/4」「4/4」と表示します。
・メインタイムライン上に、スクロールする背景ムービークリップを置きました。128フレームでループします。
・メインタイムライン上に、アニメーションするスフィーのムービークリップを置きました。6フレームでループします。

前回の版では、こんなふうに、正しくない動作になってしまっていました。
今回の版では、こんなふうに、正しい動作になりました。

今回の修正は、「親タイムラインの最終フレームと先頭フレームに同じムービークリップがあったら、親タイムラインがループするときもそのまま継続させる」
という、かなり無理やりな特例処理で対応してしまいました。
本物のFlash Playerは、どのような条件でムービークリップの継続を判断しているのでしょうか。
興味があります。

==================
Sat Aug 22 2009
Naoyuki Sawa
nsawa@piece-me.org
==================

--------------
2009/08/29追記
--------------

・アクションを実行するタイミングを修正しました。

前回までの版では、アクションを実行するタイミングが間違っていたため、間違った動作が発生していました。
アクションを実行するオブジェクトとターゲットの、親子や前後関係によって、アクションが1フレーム早く実行されてしまうことがありました。(不具合①)
また、オブジェクトを配置した直後に、そのオブジェクトをターゲットとしてアクションを実行すると、エラー終了してしまうことがありました。(不具合②)
今回の版で、アクションを実行するタイミングを修正し、正しく動作するようになりました。

これまでは、Flashを使ってムービーを作る際、アクションの実行タイミングを「なんとなく」の感覚でしか理解していませんでした。
今回、バグ修正のためにSWFの仕様を勉強して、アクションの実行タイミングの仕組みが良く判りました。

==================
Sat Aug 29 2009
Naoyuki Sawa
nsawa@piece-me.org
==================

--------------
2009/09/06追記
--------------

・「静止テキスト」に対応しました。

これまでの版は、「ダイナミックテキスト」だけに対応していました。
静止テキストの方が、一文字づつの座標が入っているので、より正確なレイアウトで表示できます。
SWFファイルの中にはフォントも入っているので、きちんと解析すればP/ECE上でも完全な表示ができるはずなのですけれど、まだ対応できていません。
座標はSWFファイルから取得しますが、描画するフォントはP/ECE内蔵の10ドットフォント固定です。

Flash MXと、Suzukaと、ParaFla!を使って、テストデータを作ってみました。

Flash MXで作ったデータは、P/ECE上でも上手く表示できました。
Flash MXは、ひとつの静止テキストの中で文字属性を一文字ごとに編集できるので、タイトルの文字をボールドにしてみました。

Suzukaで作ったデータも、P/ECE上でも上手く表示できました。
Suzukaは、ひとつの静止テキストの中では文字属性を変更できないので、タイトルのボールド化は無しです。(もちろん、静止テキストを分割すれば、可能です。)

ParaFla!で作ったデータは、文字化けしてしまいました。位置も間違っていて、一行分ぐらい上にずれているようです。

文字化けする理由は、ParaFla!が生成するSWFファイルの文字コードが、Unicodeで格納されているのが原因のようです。
SWFの仕様では、バージョン5以前はシフトJIS、バージョン6以降はUnicodeなのですが、ParaFla!は古いバージョンのSWFを生成するときも常にUnicodeで格納してしまうみたいです。

行がずれる理由は、ParaFla!が生成するSWFファイルに、フォントレイアウト情報が欠けているのではないかと考えています。僕のプログラムが間違っている可能性も高いのですが…
静止テキストに入っている一文字づつの座標は、通常は、文字のベースラインを基準とします。Flash MXが生成するSWFデータは、そうなっています。
また、フォンレイアウト情報を付加すれば、文字の左上や任意の位置を基準とすることも可能です。Suzukaが生成するSWFデータがそうなっていて、文字の左上を基準としています。
ParaFla!は、フォントレイアウト情報無しに、文字の左上を基準とした座標を格納しているため、P/ECE上の表示で行がずれてしまっているようです。

文字コードの種類も、フォントレイアウト情報の有無も、PC上の本物のフラッシュプレイヤーには影響しません。
本物のフラッシュプレイヤーは、静止テキストの中の文字コードやフォントレイアウト情報を使わずに、SWFファイルの中のフォントデータを直接図形として描画しているからです。
P/ECE版SWFプレイヤーは、フォントデータを図形として描く処理に対応できなかったため、代わりに文字コードとフォントレイアウト情報を使ったところ、影響が生じたのでした。

==================
Sat Sep 06 2009
Naoyuki Sawa
nsawa@piece-me.org
==================
