ONScripter on Android for MEDIAS W N-05Eまとめ

 ONScripter on Androidの仕様上、MEDIAS Wで二画面フルスクリーンにすると左右二画面になるため、中央のキャラが縦に真っ二つになるのが切なかったので、上下二画面固定で見やすいよう微調整してみたりした際の覚え書き。
※注:オープンソースのONScripter on Androidをいじったついでに参考としてまとめてあるだけで、apkは配布していません。

 ボタンの表示/非表示に関わらず、ゲーム画面が下から3分の1で切れるので、下記の画面イメージのとおり、普通のレイアウトの作品ならテキストウインドウの真上辺りで切れて、テキストもキャラも見苦しくなりにくいはず。
 当然ながらイベント絵など状況によってはデフォの左右二画面時より残念な切れ方をするので、あくまで“概ねデフォよりマシ”という程度だし、4:3でなくワイドな作品なら二画面にしない方がいい。

 ついでにMEDIAS Wだと起動時に外部SDカードを開いてくれないので、内部ストレージに置いた設定ファイルでパスを直書きし、MEDIAS Wに限らずどの端末でも起動時に任意のフォルダを開けるようにも修正。
 こちらはMEDIAS Wに限らず応用の利く処理で、一々ビルドし直さなくてもパラメータを調節したりできるので実用的かと。

画面イメージ(作品アスペクト比4:3、ボタン非表示の場合)

 MEDIAS Wの一画面の解像度は4.3インチ960x540pixel。黄色がゲーム画面、青がテキストウインドウ(目安)、灰色はナビゲーションバー、黒が余白。
 Android 3.x以降は、一時的には消せても操作中は必ず現れるナビゲーションバーのため、実際にアプリケーションが使える領域はナビゲーションバーを除いた897x540pixcel程度になる。
 pixel等倍にすると、(家のPCモニタで見た時に)大き過ぎてあまり参考にならなかったので、イメージ図のサイズは2分の1に縮小。24インチWUXGA(1920x1200)モニタで実寸の2割増しくらい。

修正前(シングルスクリーン時)
 Android 4.xのスマホなら、解像度はともかく大体こうなる。
 
←720→








540
 
 
 

修正前(二画面フルスクリーン時)
 ナビゲーションバーの影響も無く、ゲーム画面の面積はシングルスクリーンの倍以上と段違いなので、一度体験するとシングルに戻り辛くなるものの、基本となる中央に表示されたキャラクターやテキストウインドウが真っ二つになってしまうのが難点。
 画面の間隔は適当だが概ねこれくらいあるので、流石にキャラやテキストが切れるのは気になるし、ヒロインが常時真っ二つなのはかなり切ない。
 
←540→














810
 
 
 

 
←540→














810
 
 
 

修正後
 テキストは格段に読み易くなり、イベント絵以外では画面の分断もあまり気にならない。
 しかし横960なら左右二画面時の横1080と大差ないかと思いきや、MEDIAS Wの仕様で画面の向きに関わらずナビゲーションバーの位置は固定なため、横幅が63pixel詰まって897x672となり、ゲーム画面の面積はシングル時の2倍足らず。
 5インチ端末よりは広いと思われるが、分断してまでやるほどかといわれると微妙かも?
 
 
←897→







448
←897→
 




224
 

ONScripter.java修正箇所(赤字部分を追加)

 とりあえず以下の修正を行う前にAndroidManifest.xmlのandroid:screenOrientationはportrait(またはunspecified等)にすること。
 その他の設定についてはONScripter on Android配布元の「カスタマイズ」を参照。

resetLayout(500行目辺り)
 画面が縦向き(mIsLandscape != true)の時に、「("画面の高さ"−"ゲーム画面の縦幅の3分の4")/2」をゲーム画面上部の余白の高さ(h1)にすることで、ゲーム画面の下から3分の1が画面の中央に来るようにする処理の追加。
 上下二画面にした時に、画面の下から3分の1で切れるようにするのが目的なので、ボタンの表示設定による制御より優先してあり、オリジナル版と違ってボタンの表示/非表示に関わらずゲーム画面の位置は変わらない(ゲーム画面上部の余白も固定)。
 元のソースを極力変えたくなかったのでif文を継ぎ足したが、作品のアスペクト比が4:3より縦長でない限り"dh >= screen_h * 4 / 3"はtrueになるので、後ろの元のif文は事実上無意味(あったとしても5:4(1280x1024)くらい?)。
if (mIsLandscape == true) {
    if (!mButtonVisible) {
        w1 = bw - bw/2;
        bw /= 2;
    }
    if (bw > bh*2) bw = bh*2;
    h1 = dh;
    w2 = bw;
}
else {
    // screen adjust for dual display
    if (dh >= screen_h * 4 / 3) {
        h1 = (dh - screen_h * 4 / 3) / 2;
        bh = dh - screen_h - h1;
    } else if (!mButtonVisible) {
        h1 = bh - bh/2;
        bh /= 2;
    }
    if (bh > bw*2) bh = bw*2;
    w1 = dw;
    h2 = bh;
}

onCreate(600行目辺り)
 どの端末でもビルドし直すことなく外部SDカードのフォルダを起動時に開けるように、設定ファイルで任意のパスを起動フォルダに指定出来るようにする処理の追加。
 デフォルトのパス"/sdcard/ons"(Environment.getExternalStorageDirectory() + "/ons")直下に"config.txt"を置き、"launch_dir:/storage/sdcard1/ons"の様に設定する。
 従ってゲームデータはSDカードに入れてあっても、設定ファイルだけは内蔵ストレージに置く必要がある。
 一行一項目の設定ファイルを読み込む形式の処理にしてあるので、if文を追加したりハッシュに流し込むなりして、その他の改造の取っ掛かりにするのもご自由に。
 万一ここの設定がおかしくても、この先のrunLauncherで、指定フォルダが無ければEnvironment.getExternalStorageDirectory()を開く様になっている様なので、意図したフォルダが開かれるまで設定を書き換えてアプリを再起動するべし。
 こちらは修正の際に以下のクラスの追加も必要なので、java.io.*にするのも面倒なら、gCurrentDirectoryPathを自分の端末に合わせて直接指定してしまえば、赤字部分の追加自体不要なはず。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
if (getResources().getBoolean(R.bool.use_launcher)) {
    gCurrentDirectoryPath = Environment.getExternalStorageDirectory() + "/ons";

    // load config file
    File configFile = new File(gCurrentDirectoryPath, "config.txt");
    if (configFile.exists()) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(configFile)));
            String line;
            while ((line = reader.readLine()) != null) {
                String[] cfgDat = line.split(":");
                if ("launch_dir".equals(cfgDat[0]) && cfgDat[1] != null && cfgDat[1].length() > 0) {
                    File file = new File(cfgDat[1]);
                    if (file.exists()) gCurrentDirectoryPath = cfgDat[1];
                }
            }
        } catch (FileNotFoundException e) {
            showErrorDialog(e.getMessage());
        } catch (IOException e) {
            showErrorDialog(e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    showErrorDialog(e.getMessage());
                }
            }
        }
    }

    runLauncher();
}

追記:ステータスバーの表示について

 縦向きにするとゲーム画面の上に余白ができるのと、充電しながらのプレイはかなり発熱するので、ステータスバーを表示して電池残量や時刻を常時見えるように修正してみた際のメモ。
 単にgetWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);でフルスクリーンモードを解除すると、アプリケーション領域の大きさも変わってしまうので、ゲーム画面の位置を再調整する必要があって計算もちょっと面倒。
 そこで、フルスクリーンモードを解除した上で、getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);とすれば、アプリケーション領域の広さを変えずにステータスバーをオーバーレイ出力できます。
 具体的な修正内容については、無駄にフルスクリーンモードを切り替えてステータスバーが出たり消えたりしないようにとか、きちんと考えると少々ややこしい感じだったので省略。
 固定でステータスバーが表示されるようにするだけなら、FLAG_FULLSCREENをaddFlagsしてるのを取り消して、ステータスバーを上記のとおりオーバーレイ出力にすればOKです。

≪HomePage