このゲームは386専用ソフトだったため、ちまたのエミュレーションでどこまで動くのか不明だったので、
そうだ!! Java で移植してみよう!!!
などと考えたわけですが、そんな簡単に出来るわきゃねーぢゃないすか。
ただでさえ約6万行のフル 80286/386 アセンブラで記述されているのに、Windows 移植だって何年かかるかわからんのに、別に普段Java 言語で仕事してるわけでもないのに、なぜに Java 版!!??
とは言うものの、2005年になにを血迷ったかコーディングを始めて、途中で忙しくなってほっときつつも、2007年にオープニングが見られるようになり、2009年会社の仕事をそっちのけで1ヶ月かけたら一気に組み上がってしまいました。
2007年に動いていたのは、オープニングとルーン占いだけです。すなわち、スクリプトで動いている部分が動くようになったわけです。 (あのルーン占いも、スクリプトだけで動いているのです。恐るべし)
スクリプトを修正すれば、エンディングも見られるようになるのですが、 そりゃー、もったいねー とゆわけで、また合う暇で。
その後 2008年にワールドマップが表示され、2009年に続きを始めて部隊編成画面が動き、フィールドマップが動き、ついに戦闘システムが動くようになりました。といってもかなりバグっていることが予想されます。エミュレータではなく java版へのソースレベルでの完全移植なので、コーディングミスやアルゴリズムの誤認識もいろいろあるからです。(オリジナルソースのバグも見つけましたけど・・)
一応 (デバッグモードで戦闘をずるしながら) 最後までクリアしてみましたが、全てのチェックは出来ていないので、もし吹っ飛んで先に進めないなどございましたら、セーブデータなどを送っていただければ解析します。m_O_m
なお、Ragna.jar を実行すると "RagnaSaveData" というフォルダが生成されます。こちらがセーブデータの格納先です。ゲーム上は8個までしかセーブ出来ませんが、このフォルダを丸ごとコピーして保存するなどすれば、いくらでもセーブ可能です。
ちなみにPC9801版のセーブデータとは「かなり」互換性があるかもです。もしエミュレータやFDDなどのセーブデータファイルがあれば、これらを小文字にして、"RagnaSaveData" フォルダに上書きしてみてください。 もしかしたら動くかも知れません。
それから現在アップしてある Ragna.jar はデバッグモード付きバージョンです。とりあえず、シフトキーまたは'F'キーでフィールド上の時間進行を加速できます。
さらにこちらの都合で作った機能なのですが、現代では無意味となった白黒液晶用の「モノクロモニタ」モードにすると、フィールド上で「暗視モード(笑)」となっています。スクロールさせてみて怪しげな白いBOXラインが見えたらそこに行ってみましょう。また格子状のBOXラインはそこで何かアイテムを使う必要があることを示しています。
さらに、佳境になってくるとたぶん砂時計アイコンなんてマウスでクリックする余裕など無いと思いますので、スペースキーでポーズ機能が働くようにしてみました。他にもいくつか修正・調整した項目があるので、以下を参照してください。
この実行ファイルは、Java 版です。Java-script でも、Javaサーブレットでもありません。
Windows の人は以下を参考に「Java 実行環境」をインストールする必要があります。
"Ragna.jar" をダウンロードしても、アイコンが「なんだかわからないファイル」のままであるならば、Java 実行環境をインストールする必要があります。
(あるいは、jar というのは一種のアーカイブファイルなので、クリックして中身が展開されるだけだったらやっぱりだめです)
ORACLE 社の Java ダウンロードページ (こちら) より、Java をインストールします。
たぶん、なにも不要です。うちの Mac Mini では、"Ranga.jar" をダウンロードして、そのままクリックしたら、ノープロブレムで動いてしまいました。
もし、動かないようであればWindows版と同様に Java をダウンロードしてインストールします。
いやーーー、Windows の嫌いな私にとって、mac で動いたのは ちとうれしい。java のコーディングで詰まりながら、やっぱり普通に Windows アプリにすればよかったかと、くじけそうになりながらも、せめてビジュアルまで動くようにと頑張った甲斐がありました。(´-`)ゞ
たぶん、linux でも動くのではないでしょうか
なんてものはちょっと公開しませんが、ベースとなっている仕組みだけでもご紹介しておこうと思います。以下のソースは不要な部分をカットしておりますが、実際に組んだソースから抜き出したものです。
(※ 受け渡しパラメータの変数名が、AL だの DX だのなっているものは分かる人は笑ってください)
Ragna.java | 起動ベース | |
Main.java | メイン処理移植ソース | |
Vram.java | 表示VRAMエミュレーション |
PC9801時代のプログラムとして特徴的なのは、いわゆるシングルプロセスのアプリであったため、プログラム本体にメインループを持ってしまっていることです。それどころかメニューの様ないわゆるダイアログベースの表示が動き出すと、その中でキー入力と表示を処理するループ待ちを行ってしまいます。
すなわち、OS から更新イベントからの呼び出しによって1サイクル分を動作するという、現代のマルチタスクのイベントドリブンとは全く相性の悪いプログラム構造となっています。
しかしながら各所にメインループがあるといっても、CPUノンストップでループするわけではなく、実際には何らかの VSYNC 割り込みと同期を取って待ちに入っているものがほとんどです。
そこで、起動となる Ragna.java では run() が 1/60秒で動作するスレッドとしてアプリの中核とし、本体の Main.java は何らかの同期待ちを行うスレッドクラスとして Ragna.java から生成され起動するようにしております。
そしてアプリベースとなるRagna.java は自身の run ()からメインの Main.java に _notify() によってシグナルを送るものとし、Main.java やその後に動作するクラスがループによって VSYNC待ちを行う場合に、この wait() で待つようにしてみました。
このようにすると、Ragna.java は実質的に PC9801 のVSYNC割り込み処理と等価なものになり、Main.java 以下のクラスの実行処理は、シングルアプリ的な作りのまま自由にループと同期待ちを行う処理を記述していくことが出来ます。
例 //メインプログラムでは、計算と表示と同期処理のループを行っている main_loop() { do { calc(); draw(); vsync_wait(); if ( menu button ? ) { menu_loop(); } } while (1); } //メニュー処理もこの中で、計算と表示と同期処理のループを行っている menu_loop() { do { calc(); draw(); vsync_wait(); if ( cancel button ? ) { return; } } while (1); } //Javaアプリ本体からの 1/60秒ごとの _notify() を待つ synchronized void vsync_wait() { try { wait(); } catch( InterruptedException e ) {} } 一見アプリをロックしてしまうループを持つプログラム構造だが、 実は丸ごとスレッドとなっていて、アプリ本体とは独立している。
表示処理については Vram.java のシングルトンにより、PC9801 ハードウェアそのまんまの
static final int _plane = 32768;//80*400; // プレーンサイズ static byte [][] _vram = new byte[2][_plane*4];
という 640x400 4プレーン分のバイト配列を定義し、これを Java 表示用の DataBufferByte に転写しています。 PC9801 では表示用と書き込み用の二つのバンクを持っているため、これと同様なしくみにも対応しています。
最近の3D表示系のアプリでは、描画処理においてフレームバッファを毎サイクル消去して背景からレンダリングし直すという
方式が一般的です。カメラがちょっと動くだけでほぼ全画面の表示内容が更新される3Dでは、前回の表示情報はブラーを掛けること
ぐらいにしか残しておく意味はほとんど無いからです。
PC9801時代にはCPUも遅くレンダリング速度も十分ではなかったため、フレームバッファの必要部分のみを更新するという
仕組みが必要とされます。マウスカーソルの描画なんてものは、現代であれば OS が勝手に合成してくれるか、画面を全部
レンダリングして最後にカーソルを描画すればいいわけですが、当時はマウスカーソルを移動するたびに
という動作を繰り返していたわけです。
いやー!! 楽な時代になったもんだ!!!
とはいうものの、こういった古典的手法は実はまだ 任天堂DS のようなハードウェアのアプリ開発には
利用できるものがあるのではないかと思います。
でもまー、もはや1バイト1サイクルが血の一滴だった時代を理解出来る人は少ないですよねー
以上、よくわかる現代魔法と古典魔法の違いでした。
16色しか使ってないのに綺麗ですよねー