解像度の選択
とりあえず、起動時の解像度を使ってフルスクリーン化(最大化)して、プログラム側でアスペクト比を保って画面を拡大するのが安全な方法ということで落ち着いたのですが、すると「ソフト側の拡大が汚い、バイキュービックとかじゃなくて、液晶の拡大を使いたい」という意見もあるようです。
個人的には、そこに拘りはないのですが、仕方ありません。
任意の解像度を選べるようにして「勝手に最も最適なものを選んでね!」で済ます方法が適切ではあるんですが、もうちょっと自動的に計算して出せないものか考えてみましょう。
800x600とか1280x720などの、規格制定され液晶がまんま対応しているものは、まんまの解像度を使用すればいいので外します。
1024x576(16:9)とか1024x640(16:10)あたりのどっち付かずなものを例としてとしましょう。
液晶の拡大を使いたいと言うことは、ソフトウェアで一切拡大してはいけませんから、等倍で表示することになります。
等倍表示をして最もスッポリと収まる(内包する最小サイズ)を導けばいいのでしょうか。
//初期値 aa1 := 4096*4096; w := 0; h := 0; for i:=0 to DisplayCount-1 do begin //ディスプレイが使用できる解像度配列 ww := DisplayList[i].dwWidth; hh := DisplayList[i].dwHeight; //内包できるかどうか //GameWidth,GameHeightはゲーム画面解像度 if (ww>=GameWidth)and(hh>=GameHeight)then begin //面積を求める aa2 := ww*hh //最も小さいのを採用 if (aa1>aa2)then begin w := ww; h := hh; aa1 := aa2; end; end; end; //結果 RESULT.X := w; RESULT.Y := h;
これだと、1024x576、1024x640共にどんな液晶でも1024x768を返します。(環境で変化有り。カスタム解像度が有る場合等)
まぁこれでもいいんですが、もうちょっと欲を出すと、これより大きく表示される解像度というのが液晶解像度によって存在します。
各解像度がアスペクト比固定拡大を行った際に、何倍に拡大されるかをリストにしてみると。
■1600x1200(4:3)の液晶の場合 1024x768...1.56,1.56=1.56倍(最良) 1280x720...1.25,1.66=1.25倍 1280x960...1.25,1.25=1.25倍 ■1920x1200(16:10)の液晶の場合 1024x768...1.87,1.56=1.56倍(最良) 1280x720...1.50,1.66=1.50倍 1280x960...1.50,1.25=1.25倍 ■1920x1080(16:9)の液晶の場合 1024x768...1.87,1.40=1.40倍 1280x720...1.50,1.50=1.50倍(最良) 1280x960...1.50,1.12=1.12倍 ※本当は使用できる解像度を用いるので、4:3液晶で16:9解像度などは使用できません。 今回は計算の例と言うことで入れてあります。
大きく表示された方が良いので、拡大率が一番大きいのがこの場合の「最良」となります。
16:10と16:9で最良となる解像度が異なる点が、重要なところです。
これを導くには、先ほどのコードに、液晶の解像度から表示倍率を求めて、表示倍率が大きいものを選択すればいいので。
function GetSizeCmp(w,h:Integer):Integer; var s1,s2 : Single; begin //液晶に対してゲーム画面が何倍に引き延ばされるかを計算 //w,hはフルスクリーン候補となる解像度 //DisplayDotByDotWidth,DisplayDotByDotHeightは液晶の解像度 s1 := DisplayDotByDotWidth/w; s2 := DisplayDotByDotHeight/h; if (s1>s2)then s1 := s2; //倍率がそのまま比較値になる RESULT := trunc(1024*s1); //比較値は小さい方が優先されるので、マイナスに反転させる RESULT := -RESULT; end; (省略) if (ww>=GameWidth)and(hh>=GameHeight)then begin //******比較値を求める****** aa2 := GetSizeCmp(ww,hh); //最も小さいのを採用 if (aa1>aa2)then begin w := ww; h := hh; aa1 := aa2; end; end; (省略)
と、GetSizeCmp関数を一枚挟むだけで後は同じです。
液晶の解像度は、俗に言う液晶がドットバイドット時の解像度です。
正確な取得方法はありませんが、OSの解像度、つまり解像度を変更する前の起動時直後の解像度を取得して保存しておけば、おおまかこれに相当すると思われます。
ところで、「液晶側で拡大表示されない場合、液晶がアスペクト比を維持せずに拡大しちゃう場合はどうするの?」なんですが、冒頭にあるように安全な手段が用意されているからそれを使えばいいよねって事で落ち着きます。
なので、高性能な液晶を使っていて適確な設定がされていることを前提としても問題ないわけです。