FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgDelayRegulate

目次→教本→プログラマーのための案内Fine-grain procedure for waiting and in-loop procedure for fine-regulating FPS←オリジナル・サイト

待機のきめ細かな手続きと、FPSを微調整するループ内手続き 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

-きめ細かな待機手続きを使った SLEEP 機能の改善。
-FPS (フレーム/秒)をループ内の微調整手続きで制御する。

前文:
ユーザー手続きで SLEEP キーワードと TIMER キーワードを適切に使うには、それらの限界と動作について十分な知識が必要です。

SLEEP keyword
一般に、SLEEP 機能は、要求された遅延に関して精度が良くなく、非常に短い待機時間を生成することはできません。

SLEEP の精度は、OS のサイクルタイムによって異なります:
Windows NT/2K/XP: 15 ms, 9x/Me: 50 ms, Linux: 10ms, DOS: 55 ms.
また、これらの精度値よりも低い遅延値に対して使うと、SLEEP は遅延値「0」を除いて、対応する待機値を生成できません。(常に高い待時間でこれ値の順序になります。)

TIMER keyword
TIMER によって戻される時間の精度は、待機を生成するための SLEEP キーワードの一般的な精度よりもはるかに高いものです:
最新のプロセッサでは、サブマイクロ秒の精度が期待できます。

一部のプラットフォーム (Windows と Linux 以外) では、TIMER の戻り値は深夜にリセットされます。
このため、開始時刻と終了時刻がリセット ポイントの両側にある場合、このイベントを無視すると、一部のプログラムで予期しない動作が発生する可能性があります。

1. SLEEP キーワードと TIMER キーワードの不利な行動を克服するための原則
SLEEP と TIMER キーワードに基づく効果的な時間管理手順を実装するには、上記のようないくつかの悪い動作を克服する必要があります。

正確な遅延で待機機能を生成するための原理
SLEEP を使うと CPU を占有しませんが、精度が悪く、非常に短い遅延には対応できません。
TIMER 値のテスト中にループを使うと、精度は高くなりますが、CPU を占有します。

原則は、次のチェーンです:
- 要求された遅延の最初の部分に SLEEP を使って大粒の遅延、
- その後 TIMER 値をテストするループを使って残り時間を細かく遅延。
時間しきい値を設定して、この 2 種類の動作を切り替えることができます。

このしきい値の典型的な設定は、OS サイクル期間の 2 倍の値に相当します。
この値は、CPU 負荷と遅延精度の兼ね合いになります。

TIMER 戻り値のリセットの可能性を応える原理
2 つの呼び出し間の TIMER のリセット (真夜中) の可能性は、TIMER から返された 2 つの値の差の符号をテストすることでの検出されます。
2 番目の値が 1番目の値より小さい場合 (TIMER のリセットにより)、 1番目の値に負の時間的補償が適用され、秒単位で表される日に対応します。

2. 手続き本体(宣言なし)の説明
ここで、3つの手続きについて説明します。:
- 'delay()' procedure => 正確な時間(ミリ秒で表される浮動小数点値)の待機を生成します。
- 'regulate()'procedure => ループ周波数(整数値で1秒あたりのループ回数)を細かく制御・調整します。
- 'framerate()' procedure => 瞬間的なループ周波数 (1 秒あたりのループ数の整数値) を測定するツール

最初の 2 つの手続きは、画像リフレッシュの FPS (1 秒あたりのフレーム数) を細かく調整/制御するのに適しています。
「delay()」は時々ワンショットで使うのに適しています。一方「regulate()」はループに細かい遅延を挿入して FPS を全体的に調整するのに適しています。

「regulate()」と「framerate()」は、ともに「Static」変数を使うため、スレッドセーフではありません。

注意:他の待機機能と同様、画面がロックされている場合は、[ScreenLock...ScreenUnlock] ブロック内からの呼び出しを行わないように、'delay()' または 'regulate()' を使うことを強く推奨しません。

'delay()' 手続き本体(きめ細かな待機を使って SLEEP 機能を改善)
'delay()' サブルーチンは、正確な待機機能を生成するのに役立ちます。SLEEP キーワードで提供される機能よりも正確で、非常に短い待機時間にも対応します。
要求された待機「量'amount'」が「しきい値'threshold'」(+ 0.5) より大きい場合、要求された待機時間 (「量」 - 「しきい値」) の最初の部分が SLEEP キーワードで実行されます (CPU を占有しない)。 残り時間は、ループ内で TIMER の正確な値を目標値までテストすることによって生成されます。
TIMER の最終的なリセットもテストされ、リセットが発生した場合にそれを補正します。
Sub delay(ByVal amount As Single, ByVal threshold As Ulong)
    '' 'amount'  : requested temporisation to apply, in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Dim As Double t1 = Timer
    Dim As Double t2
    Dim As Double t3 = t1 + amount / 1000
    If amount > threshold + 0.5 Then Sleep amount - threshold, 1
    Do
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
        t2 = Timer
        If t2 < t1 Then t1 -= 24 * 60 * 60 : t3 -= 24 * 60 * 60
    Loop Until t2 >= t3
    #else
    Loop Until Timer >= t3
    #endif
End Sub
インクルードされる "delay_regulate_framerate.bi" ファイルから、上記の 'delay()' サブルーチンが、呼び出されるとき (下記の段落 3 の定義を参照)、サブルーチンの本体の前に追加された宣言により、その 2 番目のパラメータ ('threshold') がオプションのパラメータとして定義され、そのデフォルト値が設定されます。

'regulate()' 手続き本体 (ループ内調整を使って FPS を微調整)
regreg()' 関数は 'delay()' サブ関数を中心に構築されていますが、ここで適用される待機時間(もし残っていれば)は、要求されたフレーム期間(FPS の逆数)と前回の呼び出しからの経過時間から差し引かれます。
デバッグのために、'reregate()'関数は適用した遅延(最初のループに追加された遅延)を返します。ユーザーがこのデバッグデータを使わない場合は、関数を Sub として呼び出すだけです。
この遅延値が非常に小さい場合、FPSの設定値に到達することが困難になります。それ以外の場合は、(レギュレーションが非常に正確であると仮定して)返される遅延の変動は、ループ内で実行されるユーザーコードのフレーム間の変動を表します。
Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Single
    '' 'MyFps' : requested FPS value, in frames per second
    '' function return : applied delay (for debug), in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Static As Double t1
    Dim As Single tf = 1 / MyFps
    Dim As Double t2 = Timer
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
    If t2 < t1 Then t1 -= 24 * 60 * 60
    #endif
    Dim As Single dt = (tf - (t2 - t1)) * 1000
    delay(dt, threshold)
    t1 = Timer
    Return dt
End Function
インクルードされる "lay_regulate_framerate.bi" ファイルから、上記の 'regulate()' 関数が、呼び出される場合 (下記の段落 3 の定義を参照)、関数の本体の前に追加された宣言は、その 2 番目のパラメーター ('threshold') をオプションのパラメーターとして定義し、そのデフォルト値を設定します。

'framerate()'手続き本体 (FPS計測用ツール)
デバッグの目的で、ループ内の任意の場所から次の非常に単純なツール関数 'framerate()' を呼び出すことで、FPS の瞬間的な測定 (フレーム時間を測定し、その逆数を計算する) ができます。
'framerate()' が'regulate()'のすぐ隣に配置されている場合、これは規制の本質的な精度を測定します。
'framerate()' がプログラム ループ内の別の場所に配置されている場合、フレーム間のプログラム実行の変動によってさらに影響を受ける可能性があります。
Function framerate() As Ulong
    '' function return : measured FPS value (for debug), in frames per second
    Static As Double t1
    Dim As Double t2 = Timer
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
    If t2 < t1 Then t1 -= 24 * 60 * 60
    #endif
    Dim As Ulong tf = 1 / (t2 - t1)
    t1 = t2
    Return tf
End Function
'delay()'や'reregate()'と異なり、上記の'framerate()'関数は、画面がロックされているときでも使用できるので、[ScreenLock...ScreenUnlock]ブロックの中からでも呼び出すことができます。

3. すべての宣言と手続き本体を含む完全なソース コードを含める
ヘッダーには、上記の 3 つの手続きの本体の宣言が含まれています。
'delay()' と 'regulate()' の場合、2 番目のパラメータをオプションとして宣言し、使用するプラットフォーム (Windows、Linux、DOS、またはその他) に応じてデフォルト値を設定できます。

含めるファイル: "delay_regulate_framerate.bi"
'  delay_regulate_framerate.bi

#if defined(__FB_WIN32__)
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 16)
Declare Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 16) As Single
Declare Function _setTimer Lib "winmm" Alias "timeBeginPeriod"(ByVal As Ulong = 1) As Long
Declare Function _resetTimer Lib "winmm" Alias "timeEndPeriod"(ByVal As Ulong = 1) As Long
Declare Sub delayHR(ByVal amount As Single, ByVal threshold As Ulong = 2 * 1)
Declare Function regulateHR(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 1) As Single
Sub delayHR(ByVal amount As Single, ByVal threshold As Ulong)
    '' 'amount'  : requested temporisation to apply, in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Dim As Double t1 = Timer
    Dim As Double t2
    Dim As Double t3 = t1 + amount / 1000
    If amount > threshold + 0.5 Then
        _setTimer()
        Sleep amount - threshold, 1
        _resetTimer()
    End If
    Do
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
        t2 = Timer
        If t2 < t1 Then t1 -= 24 * 60 * 60 : t3 -= 24 * 60 * 60
    Loop Until t2 >= t3
    #else
    Loop Until Timer >= t3
    #endif
End Sub
Function regulateHR(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Single
    '' 'MyFps' : requested FPS value, in frames per second
    '' function return : applied delay (for debug), in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Static As Double t1
    Dim As Single tf = 1 / MyFps
    Dim As Double t2 = Timer
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
    If t2 < t1 Then t1 -= 24 * 60 * 60
    #endif
    Dim As Single dt = (tf - (t2 - t1)) * 1000
    delayHR(dt, threshold)
    t1 = Timer
    Return dt
End Function
#elseif defined(__FB_LINUX__)
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 10)
Declare Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 10) As Single
#elseif defined(__FB_DOS__)
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 55)
Declare Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 55) As Single
#else
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 16)
Declare Function regulate(ByVal MyFps As Ulong, ByVal Ulong As Single = 2 * 16) As Single
#endif

Declare Function framerate() As Ulong

'------------------------------------------------------------------------------

Sub delay(ByVal amount As Single, ByVal threshold As Ulong)
    '' 'amount'  : requested temporisation to apply, in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Dim As Double t1 = Timer
    Dim As Double t2
    Dim As Double t3 = t1 + amount / 1000
    If amount > threshold + 0.5 Then Sleep amount - threshold, 1
    Do
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
        t2 = Timer
        If t2 < t1 Then t1 -= 24 * 60 * 60 : t3 -= 24 * 60 * 60
    Loop Until t2 >= t3
    #else
    Loop Until Timer >= t3
    #endif
End Sub

Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Single
    '' 'MyFps' : requested FPS value, in frames per second
    '' function return : applied delay (for debug), in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Static As Double t1
    Dim As Single tf = 1 / MyFps
    Dim As Double t2 = Timer
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
    If t2 < t1 Then t1 -= 24 * 60 * 60
    #endif
    Dim As Single dt = (tf - (t2 - t1)) * 1000
    delay(dt, threshold)
    t1 = Timer
    Return dt
End Function

Function framerate() As Ulong
    '' function return : measured FPS value (for debug), in frames per second
    Static As Double t1
    Dim As Double t2 = Timer
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
    If t2 < t1 Then t1 -= 24 * 60 * 60
    #endif
    Dim As Ulong tf = 1 / (t2 - t1)
    t1 = t2
    Return tf
End Function
このコード('delay_regulate_framerate.bi'ファイル)は、ユーザーが3つの手続きを呼び出せるように、ユーザー・ソース・プログラムの先頭にインクルードする必要があります:
#include "delay_regulate_framerate.bi"

4. 使用例
ここで、次の 2 つの例を示します:
- 最初の例は 'delay()' サブルーチンを使用
- 2 番目の例は 'regulate()' 関数を使用 (およびデバッグツールとしての 'framerate()' 関数)

'delay()' sub の使用例
'delay()' によって、値が減少する4つの小さな待ち時間を生成する例:
100 ms, 10 ms, 1 ms, 0.1 ms
#include "delay_regulate_framerate.bi"

Dim As Double t
Dim As Single t0 = 100

For N As Integer = 1 To 4
    Print "Requested delay :"; t0; " ms"
    For I As Integer = 1 To 4
        t = Timer
        delay(t0)
        Print Using"  Measured delay : ###.### ms"; (Timer - t) * 1000
    Next I
    Print
    t0 /= 10
Next N

Sleep
測定結果は、使用範囲全体にわたってかなり正確なようです。

'regulate()' 関数と 'framerate()' ツール関数の使用例
'regulate()' で、描画イメージの FPS(フレーム/秒)リフレッシュを制御する例:
FPSの範囲は 10 から 100 まで1ステップ単位で利用可能
#include "delay_regulate_framerate.bi"

Screen 12
Dim As Ulong FPS = 60
Do
    Static As ULongInt l
    Static As Single dt
    ScreenLock
    Cls
    Color 11
    Print Using "Requested FPS : ###"; FPS
    Print
    Print Using "Applied delay : ###.### ms"; dt
    Print Using "Measured FPS  : ###"; framerate()
    Print
    Print
    Print
    Color 14
    Print "<+>      : Increase FPS"
    Print "<->      : Decrease FPS"
    Print "<Escape> : Quit"
    Line (0, 80)-(639, 96), 7, B
    Line (0, 80)-(l, 96), 7, BF
    ScreenUnlock
    l = (l + 1) Mod 640
    Dim As String s = Inkey
    Select Case s
    Case "+"
        If FPS < 100 Then FPS += 1
    Case "-"
        If FPS > 10 Then FPS -= 1
    Case Chr(27)
        Exit Do
    End Select
    dt = regulate(FPS)
Loop
測定された FPS はほぼ安定しており、要求された FPS をうまく追跡します。
レギュレーションを監視するために、 'regulate()' によってループに追加される遅延も可視化されます。

5. 実際のOSサイクル周期に応じて、'delay()' と 'regulate()' 手続きの整流しきい値(大粒/小粒)を調整
ユーザーが 'delay()' または 'regulate()' 手続きの大粒度/細粒度整流しきい値のデフォルト値を調整または変更したい場合は、2 番目のパラメータを明示的に指定して呼び出すだけです (ミリ秒単位で指定される整数値)。
ただし、このしきい値の一般的な設定は、OS サイクル期間の 2 倍の値に相当します (含まれるファイルに設定されているデフォルト値: "delay_regulate_framerate.bi"):
- 2 times the OS cycle period is the recommended value => tradeoff between CPU load and delay accuracy.
- A higher threshold would promote the delay accuracy (increasing), but to the detriment of CPU load (increasing).
- A lower threshold would promote the CPU load (decreasing), but to the detriment of delay accuracy (decreasing).
- A downright null threshold would induce no CPU load as long as the required delay is greater than 0.5 ms. Only for a necessary required delay < 0.5 ms, the CPU load would not be minimized, but this small value already means that it will become difficult to reach the FPS setpoint.

使用するプラットフォームに応じて、'delay_regulate_framerate.bi' ファイルのヘッダーに設定されるデフォルト値:
- Windows (basic resolution OS cycle period = 16 ms) => threshold = 2 * 16 ms
- Windows (high resolution OS cycle period = 1 ms) => threshold = 2 * 1 ms (only used by 'delayHR() and 'regulateHR(), see paragraph 6 below).
- Linux (OS cycle period = 10 ms) => threshold = 2 * 10 ms.
- DOS (OS cycle period = 55 ms) => threshold = 2 * 55 ms.
- Other (OS cycle period per default = 16 ms) => threshold = 2 * 16 ms by default.
OSのサイクル周期の実際の分解能が、上記のデフォルトの分解能よりも優れている場合(プラットフォームによって異なる)、ユーザーは、2番目のパラメータ(ms単位で指定されたこの実際の分解能値の2倍)を明示的に指定することで、'delay()'と'reregate()'を呼び出すことができます。

6. Windows プラットホーム
Windows プラットフォームの場合のみ、ユーザーは代わりに 'delayHR()' または 'regulateHR()' を呼び出すことで、OS サイクル周期の高解像度を一時的に (16 ミリ秒ではなく) 1 ミリ秒に強制できます。
正しいしきい値 (2 * 1 ミリ秒) も一時的に適用されます。
これにより、しきい値を低くすることができるため、主にCPU負荷が軽減されます。

"delay_regulate_framerate.bi" ファイルに含まれる 'delayHR()' 手続き:
Sub delayHR(ByVal amount As Single, ByVal threshold As Ulong)
    '' 'amount'  : requested temporisation to apply, in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Dim As Double t1 = Timer
    Dim As Double t2
    Dim As Double t3 = t1 + amount / 1000
    If amount > threshold + 0.5 Then
        _setTimer()
        Sleep amount - threshold, 1
        _resetTimer()
    End If
    Do
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
        t2 = Timer
        If t2 < t1 Then t1 -= 24 * 60 * 60 : t3 -= 24 * 60 * 60
    Loop Until t2 >= t3
    #else
    Loop Until Timer >= t3
    #endif
End Sub

"delay_regulate_framerate.bi" ファイルに含まれる'regulateHR()' 手続き:
Function regulateHR(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Single
    '' 'MyFps' : requested FPS value, in frames per second
    '' function return : applied delay (for debug), in milliseconds
    '' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
    Static As Double t1
    Dim As Single tf = 1 / MyFps
    Dim As Double t2 = Timer
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
    If t2 < t1 Then t1 -= 24 * 60 * 60
    #endif
    Dim As Single dt = (tf - (t2 - t1)) * 1000
    delayHR(dt, threshold)
    t1 = Timer
    Return dt
End Function
'regulateHR()' は 'Static' 変数を使うため、スレッドセーフではありません。

いずれにせよ、'delay()' と 'regulate()' の呼び出しは常にデフォルトの解像度で実行されますが、しきい値は基本解像度 (2 * 16 ミリ秒) に適合します。
したがって、OSサイクル周期がすでに高分解能(1ms)の場合、'delayHR()'と'regulateHR()'を使用して、対応する正しい閾値も適用する必要があり、そうでなければ、この高分解能と高すぎる閾値の組み合わせは、基本分解能と比較してCPU負荷を軽減しません(一方、遅延精度は良好です)。
'delay()' と 'regulate()' は、OS サイクル期間が基本分解能 (16 ms) の場合にのみ使用することを推奨します。

注意:
Windows プラットフォームの場合、"delay_regulate_framerate.bi" ファイルは Windows 2000 からのみサポートされます (OS サイクル期間の高解像度を参照するため)。
これ以前のWindowsシステムでは、"delay_regulate_framerate.bi" ファイル('#if defined(__FB_WIN32__)' の最後の部分)から高解像度への参照をすべて削除します。:
- remove declarations of '-setTimer', '_resetTimer', 'delayHR' and 'regulateHR',
- delete the body of the 'delayHR' and 'regulateHR' procedures.

7. 使用例の充実
この例は、パラグラフ 4 の 2 番目の例と比較して改善されています。

さらに、次のことが可能になります:
-Windows プラットフォームだけで OS サイクル期間の通常の解像度と高解像度を切り替えます。
-オプション・パラメータ 'threshold' の値を変更します。
#include "delay_regulate_framerate.bi"

Screen 12, , 2
ScreenSet 1, 0

Dim As ULongInt MyFps = 100
   
Dim As String res = "N"
Dim As Ulong thresholdNR = 32
Dim As Ulong thresholdHR = 2

Do
    Static As ULongInt l
    Static As Double dt
    Static As Ulong fps
    Static As Double t
    Static As Ulong averageFps
    Static As Double sumFps
    Static As Double averageDelay
    Static As Double sumDelay
    Static As Long N
    Static As Ulong fpsE
    Dim As Double t1
    Dim As Double t2
    t = Timer
    Cls
    Print
    Color 15
    Select Case res
    Case "N"
        Print "                      NORMAL RESOLUTION"
    Case "H"
        Print "                      HIGH RESOLUTION (for Windows only)"
    End Select
    Print
    Select Case res
    Case "N"
        Print " Procedure : regulate( " & MyFPS & " [, " & thresholdNR & " ])"
    Case "H"
        Print " Procedure : regulateHR( " & MyFPS & " [, " & thresholdHR & " ])"
    End Select
    Print
    Color 11
    Print Using " Measured FPS  : ###          (average : ###)"; fpsE; averageFps
    Print Using " Applied delay : ###.### ms   (average : ###.### ms)"; dt; averageDelay
    Print
    Print
    Print
    Color 14
    #if defined(__FB_WIN32__)
    Print " <n> or <N> : Normal resolution"
    Print " <h> or <H> : High resolutiion"
    Print
    #endif
    Print " <+>        : Increase FPS"
    Print " <->        : Decrease FPS"
    Print
    Print " Optional parameter :"
    Select Case res
    Case "N"
        Print "    <i> or <I> : Increase NR threshold"
        Print "    <d> or <D> : Decrease NR threasold"
        Draw String (320, 280), "(optimal value : 32)"
    Case "H"
        Print "    <i> or <I> : Increase HR threshold"
        Print "    <d> or <D> : Decrease HR threasold"
        Draw String (320, 280), "(optimal value : 2)"
    End Select
    Print
    Print " <escape>   : Quit"
    Line (8, 128)-(631, 144), 7, B
    Line (8, 128)-(8 + l, 144), 7, BF
    Do
    #if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
        t2 = Timer
        If t2 < t Then t -= 24 * 60 * 60
    Loop Until t2 >= t + 0.002
    #else
    Loop Until Timer >= t + 0.002
    #endif
    ScreenCopy
    l = (l + 1) Mod 624
    Dim As String s = UCase(Inkey)
    Select Case s
    Case "+"
        If MyFPS < 500 Then MyFPS += 1
    Case "-"
        If MyFPS > 10 Then MyFPS -= 1
    #if defined(__FB_WIN32__)
    Case "N"
        If res = "H" Then
            res = "N"
        End If
    Case "H"
        If res = "N" Then
            res = "H"
        End If
    #endif
    Case "I"
        Select Case res
        Case "N"
            If thresholdNR < 64 Then thresholdNR += 16
        Case "H"
            If thresholdHR < 4 Then thresholdHR += 1
        End Select
    Case "D"
        Select Case res
        Case "N"
            If thresholdNR > 0 Then thresholdNR -= 16
        Case "H"
            If thresholdHR > 0 Then thresholdHR -= 1
        End Select
    Case Chr(27)
        Exit Do
    End Select
    sumFps += fpsE
    sumDelay += dt
    N += 1
    If N >= MyFps / 2 Then
        averageFps = sumFps / N
        averageDelay = sumDelay / N
        N = 0
        sumFps = 0
        sumDelay = 0
    End If
    Select Case res
    Case "N"
        dt = regulate(MyFps, thresholdNR)
    #if defined(__FB_WIN32__)
    Case "H"
        dt = regulateHR(MyFps, thresholdHR)
    #endif
    End Select
    fpsE = framerate()
Loop

参照
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2024-02-18 00:41:27
日本語翻訳:WATANABE Makoto、原文著作者:fxm

ホームページのトップに戻る

表示-非営利-継承