From 6f60622619ed3b2606cc186d9d87cfe15e665e75 Mon Sep 17 00:00:00 2001
From: Ray <raysan5@gmail.com>
Date: Tue, 22 Jun 2021 21:20:14 +0200
Subject: [PATCH] ADDED: Example: core_custom_frame_control

---
 examples/core/core_custom_frame_control.c   | 126 ++++++++++++++++++++
 examples/core/core_custom_frame_control.png | Bin 0 -> 16952 bytes
 2 files changed, 126 insertions(+)
 create mode 100644 examples/core/core_custom_frame_control.c
 create mode 100644 examples/core/core_custom_frame_control.png

diff --git a/examples/core/core_custom_frame_control.c b/examples/core/core_custom_frame_control.c
new file mode 100644
index 000000000..c1290abff
--- /dev/null
+++ b/examples/core/core_custom_frame_control.c
@@ -0,0 +1,126 @@
+/*******************************************************************************************
+*
+*   raylib [core] example - custom frame control
+*
+*   WARNING: This is an example for advance users willing to have full control over
+*   the frame processes. By default, EndDrawing() calls the following processes:
+*       1. Draw remaining batch data: rlDrawRenderBatchActive()
+*       2. SwapScreenBuffer()
+*       3. Frame time control: WaitTime()
+*       4. PollInputEvents()
+*
+*   To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in
+*   config.h (it requires recompiling raylib). This way those steps are up to the user.
+*
+*   Note that enabling this flag invalidates some functions:
+*       - GetFrameTime()
+*       - SetTargetFPS()
+*       - GetFPS()
+*
+*   This example has been created using raylib 3.8 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2021 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main(void)
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    const int screenWidth = 800;
+    const int screenHeight = 450;
+    
+    InitWindow(screenWidth, screenHeight, "raylib [core] example - custom frame control");
+
+    // Custom timming variables
+    double previousTime = GetTime();    // Previous time measure
+    double currentTime = 0.0;           // Current time measure
+    double updateDrawTime = 0.0;        // Update + Draw time
+    double waitTime = 0.0;              // Wait time (if target fps required)
+    float deltaTime = 0.0f;             // Frame time (Update + Draw + Wait time)
+    
+    float timeCounter = 0.0f;           // Accumulative time counter (seconds)
+    float position = 0.0f;              // Circle position
+    bool pause = false;                 // Pause control flag
+    
+    int targetFPS = 60;                 // Our initial target fps
+    //--------------------------------------------------------------------------------------
+
+    // Main game loop
+    while (!WindowShouldClose())        // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        PollInputEvents();              // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL)
+        
+        if (IsKeyPressed(KEY_SPACE)) pause = !pause;
+        
+        if (IsKeyPressed(KEY_UP)) targetFPS += 20;
+        else if (IsKeyPressed(KEY_DOWN)) targetFPS -= 20;
+        
+        if (targetFPS < 0) targetFPS = 0;
+
+        if (!pause)
+        {
+            position += 200*deltaTime;  // We move at 200 pixels per second
+
+            if (position >= GetScreenWidth()) position = 0;
+            
+            timeCounter += deltaTime;   // We count time (seconds)
+        }
+        //----------------------------------------------------------------------------------
+
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(RAYWHITE);
+
+            for (int i = 0; i < GetScreenWidth()/200; i++) DrawRectangle(200*i, 0, 1, GetScreenHeight(), SKYBLUE);
+            
+            DrawCircle((int)position, GetScreenHeight()/2 - 25, 50, RED);
+            
+            DrawText(FormatText("%03.0f ms", timeCounter*1000.0f), position - 40, GetScreenHeight()/2 - 100, 20, MAROON);
+            DrawText(FormatText("PosX: %03.0f", position), position - 50, GetScreenHeight()/2 + 40, 20, BLACK);
+            
+            DrawText("Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate.", 10, 10, 20, DARKGRAY);
+            DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 30, 20, GRAY);
+            DrawText(FormatText("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME);
+            DrawText(FormatText("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN);
+
+        EndDrawing();
+
+        // NOTE: In case raylib is configured to SUPPORT_CUSTOM_FRAME_CONTROL, 
+        // Events polling, screen buffer swap and frame time control must be managed by the user
+
+        SwapScreenBuffer();         // Flip the back buffer to screen (front buffer)
+        
+        currentTime = GetTime();
+        updateDrawTime = currentTime - previousTime;
+        
+        if (targetFPS > 0)          // We want a fixed frame rate
+        {
+            waitTime = (1.0f/(float)targetFPS) - updateDrawTime;
+            if (waitTime > 0.0) 
+            {
+                WaitTime((float)waitTime*1000.0f);
+                currentTime = GetTime();
+                deltaTime = (float)(currentTime - previousTime);
+            }
+        }
+        else deltaTime = updateDrawTime;    // Framerate could be variable
+
+        previousTime = currentTime;
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    CloseWindow();        // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}
\ No newline at end of file
diff --git a/examples/core/core_custom_frame_control.png b/examples/core/core_custom_frame_control.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d615efe29c0e9561453344a33650c269810373d
GIT binary patch
literal 16952
zcmeHPdpwj`A0JFinyHa4W89lm*2-<t)g@EomRP#Tme9q7N|H*#grSUES=F>ekLW_F
z*p)75Y$@@Y5`~JDb`Z5iy2*Q<d7K$Z+I`>seBSr7>!0y>Jaf+P{Lc6H`+d*%oX1{=
z#g-&_syq&dBUxK5aKzzcG;lbnYXn(vXX2XdQXFo6ul0iYOLn-fSyb2C8&ddSCg(eS
zsx+b*sw5qenNMN9y1}|dAxS;c)aRKoovyP84WrqD4+gwBOa^W{K|e;ef<@qRiU$9v
z)WI|7Y9Jdn((z1&+aMpI?zu9CJi_3A1Yh8+B5*50xl>vNWD1Er$cI!xL=j7FE&W`~
z7j4iL*|7JEHn^cC$bQ*`)gluz{<kLNklT(6g{=KSh5jv$Ie~{vDMzd4Tj{+Qwx4A$
z4rDwmr0HH2{@^NWo9|erT9UL?*sPrPV#;!pyrwPrNjHRzblzjjBi>KKaosjL=cPNm
z-x%bW`n>aecw^&a)7@`W43~5kf52_kODocv@j>nz6)U^RCGVn_^pcg&gyqpGtM<%r
zSsXWnhn=nR_Es*EeMgvdWxc5|c|GTJp>IT!)vM<$CAuLawCW{kf=zyBBkw!Sr6zeE
zYw~|<5*&^b?2q10E}C(Ss9ZcHphPL-%!_do832LAsf|>HscTKIbfwMx(WQ|wEw)tk
zLFUpo-{~w*Xw|c5G^yJ9UPvru?KDAwDnjdk5A&bNZfQT+328n;nq#i(nwT=P^jh0#
zE2ni$Joi-5(Xz$G--327|Mg4al6lvzh1I`F_vgeeYl*7<eUZ+qEx*W}@pDUkXi(oe
z!S7Y0<D_n(f>VWiovKyGqOpM=$aB{)SWm;Mo5$ysjSvOP5+Xb8>T<UnEm=p;5~iZj
zYceHSO36-XaNB^X{-dOl*z(?vHItmY+YPg8T%C5s%s6R8&V8*O7^r#A)azngy}~k^
zrbrjsr4kP9%m?c>-^_rI=>b8F)GZnGV8nV}`{tagrB9yfSTv8CzSaF#p?5uUbDnNO
zz3*iDD+A}34_HUmuZ_UHbR`94x}`<RU(EDvlwalls?yVf@L;Bc(bOje(e*EAU5VfL
z@z>>Wy3Ly_1WNG&p8Fs%DvI0CO`1i9cdqfOX+MVF&h!rtpl>#}a7$&Lifkp!KH0*l
zZP{@mqRy%;)7JX(&m(7>BHGguOYJ<<D}suCv^uq$rd1eMty4vk@=D&bu*Eg(?2eA9
zQg3(Ubdb{SX*&zgEy^;f;vK%WPCd`_D#s>R4fs!Yr{$n21DGS6Aid<Ml;-xe`&>;k
z?v+lt=v^=OP4<CHuXp7%+xgX8b!v@cpFddLXy4{PZzX@@iJBF{X5%zJl?ieA9kVsY
zsXfUs@@t#u*RH(5$Q{{uws^d>(1?O$t{}y}N%LRtML#;<!p&cHEnVx&iA@)8l_I5-
z<^5b>dCE5?QQ#GK-ED=AirrIfdMEGVv4B|#UTV|3(qsMa)T!s+nVDxR@7J@?C;!fz
zqm??r+A(qL3b`ErFrCMGS~*kk4|+=KW%g_ubMb9bz0ydpOmF8m3B1u!*_q5bbC8Ku
zq{G)+2)Dhv>l;1Zj~}xPozdsMkChGQ$QZg*43+pOcVGARKHmI#BfS(j)0}~;v3h21
zISTm8^1xjdp^}D|o%5Lcbj(YSojFO{k&8(MSemcG(mX&!mBCOkrbKEJkW(!Q3&seP
zGc28M^i=_exp=014b{#`6ah37Jk!&h`RWTbg3G}@#N2&OpoM2zeqburvIq`lc;>5n
ztW#7;*59Y84+hNJG!!fl)p$XP@en3c+Ceq>X^=wFS6oJyvZ#Ys8uWo+%!E^aZxcXG
z#f>^=ywK7z?1$;A3KFNpB6)AabnOIng(bB!>zmkBzT~piW-cnECNgD1a|O#o4V|ST
zRq6WY+1BzYXZKhZx4OS`3tGuZJ&jbEdZ<QsEcWXX)Q0G9S2!=1vFSv(`pKQK&LIiZ
zvn3oIndBlNk-(q!MYpFeCy-5KEKY-paYBtG<zay{c8sxY_q9DrD=$PYLS7+jOCZm^
zW3Su2-&;MqQ&79Qq=KT*Hrmhfb)?suM)`>=KWc8vh;n`F3qm{hwz>pZpI)VYPl&%F
z7hXxwy)BoMu)*UVzf*84$nhb=yQ}l1-t=8j$+I<bm!(wYb*5j}3k*C)k4&wL(@}A?
zBd(3QzDDU{OPF)F;=ZG4DfWa2nd}}*pQ{=(uf$fb6U72w4=-Ei5*QevpXWK9Y4eCe
zn)%GY1dZdlL**LhX?Y`S2)bt!_}_KKlhu71jU0ByR&|=|ZXY}MmCT$GryoC4=HylF
zGYfnlS+6v{^RSwQky%yja*w8H$6kefacrBj$hKca(fNWT<yRxTYomTfNzKu|=h$+t
zg1ns9^B4`Z7I@ya>Z);j*v8gTMQK-3>yRa^Sgks}Lsj#hS*~%&iA$b2$H#bdZz3jM
zI+>huqJ4GX@ox65<+SX}lx!VQyl{dEsd4d&mpnsV-dT}~i;Wd6PCMmP@*|vgO-tUZ
z(d9qg&;Auv_@fc(j=-VVhHMY9)RFq|^5{|SE=TOW7L7LUCjNAJ)_s0tZ3ps0$c8Hi
z-BX+PF8ioleiX@jg$^5+Z9ikub`JZIk)rT*Oa>9q*+BUTuYHw3p(!^QYLo^43XLyd
z9*Ga^RIo-nyG<P5-5_si!$0V-gY?rC>BLyy13Xu`Q(4NwD`Rt0tW%d=rOoK!SMi^z
zCmSebmxG}TBXIW?A9P&jcBm^QsQ0edl<+F29|>>W(r<^yADM3T5V1IA!f5Z*aSo&c
zbFx*xNJT;2<8FB0+j}G6U&Rj5VFHC4>=*-=$X@ebHaBWd=derFk(Qmg6DabU`VMc`
z(6^zG`be>p0prVMh$`BMq1@`s<OkC6Q6t&x+S3Nqxr2Fy4+uTT<xZW0^L;Fr-@hHo
zO)+NF(T$v+Z=;-9_X{gfEqla(QE|L6THXGoT>MXA_GqB}j~5riCg3^$7puJCi5Q*;
zQJx%zBf9n*_QJ3iAiMu-uz*n<NJV@(Mb@fQ$3-4q{Xp(1zr;PrzXmBoj)ax{EPSd+
z{9)%*hk6;OxUyA9i%)-D#2i}%j)u+j|C{I@;Ax1F1|pUmWj7Gw=h5aDsfVv$RGFuE
zI;FNl#V%gLulQiSjIydXL$NAUkm#p!60Hc8UYl<T)e;4GsDp*|wIlq)?U2E8%9AX6
zsoOWXBcdz>F;YQR1oVxE6M!+ahM^c5s>69G_pP8bCjg}a$0@r_IK$F>QYcW`FZlL9
zw~a+0?j=)NjLeXm{?H^_%%tW&Y?8uQ>GTeglFu${&ihA60`9CnZGZ-(2H^6$?}l(y
zsKLhG-rk<|kC|aXr~x=z!nl-QJt*bsi1iveJ||Mdu7S)K3j7Xq@>Zae*JIcK>No`M
zfGZRm{{WGq$dGzc0&w6WJ-jJzmirHzaQlKwCh<eoKW2r-_7jwG6=ab#6DyussU3ud
zR-gE>3+~^hv?p?>oR|E?nZOMIb9W8ST?09l85wq{f$_6vF2j)54qg5PbO81Sy5ORR
zFiI+L+ng68bj~X?=hBcBzA$o^i5hhJ02_=aQ;4c#eCCt3*03zs(siJvr3AJBC`2|;
zJaAW&4$Es|t35+h69ichTj>1K`zg{37;Y#0=j4odE_|6K@R`|%Ks4y}CaKspLO0#E
zaGSQ>v=Z@{^>!T{k;r;LXZ0Uh&9Z^|i2GP+e%?9L0=hRn8XEROo{j3a<6yM$HSo-9
zi;9IlrL1MDebL#dAVOZ^ygmaM^YBbZeo(HWA#W8Fw1kmG!m(L`CE{m*hrHGV`CC`B
zl3+V&s-o<sy#ofN8wg6gzCM>z%&HbYq=a=g7k2h7o~isOil9u27CaN*)DvyZoD^pq
z2LjhP-+<;#U&OrdqHi*Y*&<|Q+=uf&NmIYJ^1AAGh`SLlMr?SvXsYv|L&#vJWQ`lG
zs3b&?B_0h;)SvdYKFeiyg8s7h#-$2!sO1%K9^NoSJ3=<FX)=iOFkWY=66wOH=?v^_
zX~WC}AqNq~0D`%GE!YL{fz4Wh75L<%AEJ~<mjpg=p2B8g9@q*kat9WrYR4rC^i|4h
z;a6v278yc|;=!I5|8Ss!AvFnkunT?_tYAP?I5k5M_lqu(^oq)?=vLQ#Xe&9QNEl_(
zMO#B(WO)JB9^x6y-KEgolfgI~GFC0%a@twO5ctK4qUo&?Lw?{k4A_DBGg529IBCQ-
zoTXlexX*LRfKpfkm_&f;#6R9k1DT?FICC|g%jseTKx5fsL{a;V%BMmfj3=OAe=l;K
zVjYAWKy+;BU9%UK{2+Q6%pOHpHW>jS_L-k6|J+VvK8Q8PRCaWuAV*zyHJp?NObhRl
z#6R>#Uw>ci<ul~<g&;%|__cq6;?Kr2yETYG&tk6^vy_bb9+m+U3@D8DW-*`#)U&Vm
z;y+5{b}>7EfRfAt(Bd-&+tkJGHBJ<na1v-zBIgKIq>&>><?Qz>$ABDS)@NuZHo2!D
z2l=d*fs;GHo#?NiMvw-%jqPg_3$g9Id;R?PDcZj}(7&Mx=D(2}%r0!E-<Go`aIgQu
za_kE(sdpe-0)O87&++@0@5kf9i-b>qW7`KHTl9HdFp0Wh+3+O{yw8CCRi-A&@2I%?
zd4Qq!fYvW!^<6Nlfa=yUpOT+GllmHY5De4ybgTmW7lHOkIMX!o%!ASbvm}taa($Hg
zf{hJ+qWs{`WzvNIK9lYdCFI?cxt!lw%V0t-?qec<+!{&FfLHxD>Jk8_2GwI?6XHJC
zB?U%u!${GX#WgBy8lWJzs^Yi;ebw?`;k4yrFqi~k@l_av0VZSl?BqmE#C<mJ3jEp&
z>=?>YSR6EnYyropIl++1K~{)Mv?o@gpF%|3AyYP*A5b?y+-LH##Z6%uX&Y?nt93?p
z3n*7l4yesW+>Lq1VKcs1AV$DuG(e)1o$<Q@ow^KpuoI#$1hc3GTEqqxIV;Ad3-qbw
zx1f*cn2#J`(@}tI$tZ7M5W^{F8H@J*KrKz{qXcvMqJe?ByY^7R4C)kQg_tY$G3{rt
zzjL5JU)m%e`nSvr&*9B07zL??xqJ_xATQRtQAlBeEHQU9!aFl*n<Uf4;^4BRJ_<@U
zELhmcy0M0S0}i|r99TlJFJ^%#?+pveeP!?o??toLcv$Q83G9SQef9Pr?)rPs3N=mr
z0=zd}OZ?18c4NV0@7yK>-a_b^9e`4S74bgk6!!_z{FB9|wQniqDbSlAunNCa+zwId
z3Fo~-UAk#)3#EKNeC#qt`mVvI4@DL^tl-V4{hd<24?bgvP0StmOn7*aTYD5YU>@^A
z1B6W$=FB&6819<-lqAoXfH}+y58*TQ*fSsDGsT*rj}%hx1t$nb-(VR_N^2;Fa$Oi=
zEJ6_j_q`>%YVl2$=NkHaNz!k?ivK$a$tqHo&Yv?5JyZ6s{Avv65$qeKsqujRb%Txh
zL(l*i<?z(k@MaL|nSY8Ga=6S^F+6a)8KFmx9GN_-Fu2ENqTIFmg{7v43UYgTZ~9Ht
z+*R4Um!x;-lJ!zE-bWY(;DC@aC<r-Br+RTK0}h{vkDNfn;v#V8j7W$Aex%gO#t850
zVN1G@Mwl@WP4lA|3ETi9@3WGRl0cAU#D`B9lku``t^|+nSnibE{;<YjDPoQ!G6r0s
zY!N;4C_bf<O4jJ2e|yO2WZp#Shjk?>lSVi#-y!cIeKFHNp{-Ydhba-*_D8mPQBopV
z>NpT8-v^Ib`Dnq>x2atw8c1eH%=(Ma-UpbPB{L*P>aTQiHV`VkGu%7JWeL8ei+yBn
zgUNOWVY`Ec_dq4FBt>oES*HxyGS>;6EESV=-gIx6F&jW}Mc0M1#XSt5VCd=-J%R@p
z-+--ZY`-45WOuG(T<{n|Uf7t24|894vt%W%Pu+~!m_L+_XpQKn!AjDg=<2I0v%j3#
zeg^Mh6VP%p?1f=3z=S`Hg<&iVW1)Yc7><bHh!~ED;fNUc+SYJh7|sjBd0{v&4CjRb
z>-yovJ(?K*MqWT)rhW9tb$`(6l`DzM%<8)o<P!zH43egEfrfE?)KdHGti5Wh4b8)L
zjcGDYc4_%B-psv&dLn3H`<r7wg_PPYPkj2XVlTbpjiaJB2mV$lV1n18A!g7cLR!v<
z_HN0}#HUy2o0Jx(>`G#*jvcYp*_~f+-%+ZX&HTV>R$EESXK1C!db>tOtVUnx2)?kH
zQjs2ze?WP3m~Ju>cNuvfUCEWX*phU|f5E0%cWMi(ZmH*guq^E%BA;x}v&f>Y^P66u
zb}e}ZHNucu4TMb_Lgg;IS?{7|7xa{zX;fcTw)m*OEBB}FXmZGj->$M>J{R8pg>@00
zR{;`ZBK9Up58Pgn3|)c|@NQ&_*6%>Gv}YZUtE^pbp=o_qVVj?2Ym4fmCmHi>YF;;;
zKY0J}D4V-d1wHz`<T)co9W)JWc5^wdW8=y7EhiGI&nMsMv^^7YGjIEei07<i)BaLl
zDJDy*4JAu1F#~OuZ7HXdsT;JmO-^#|64K(Hw9>{oCGu=LtmvA%pHyU#l?xdrWBAv`
z)Mz_D;mG7&+nsu6{K?;KHoeoTR`c+bCbS<;O`5x5sjGs`W@MKI^Lvs+|7B=nCkWd<
zb3h*yP>s20aWQoje;(cGt<b8C)k3E*QV*5h{h8zaEbV;={fAF{=!Wf6bq=X&zSw0>
zC=ZVhyk)PKY~M0zoKw{!@A++s^V?p~w#Cew-ko~HsOp-MiJJ8`v*RDNW~>&RUT~~x
zH5lsXB|9AI9tjS|3#$1Niyg2NHvVwaPBOf{EA&n3zW)sHvp_?%fm;NQRHp2iL5%{B
z?6+{Ehj25xMQ{Hh*gHqK4orMi{j4#l(*6?<Ou(^AobrF+1u0zc_b<1$&hDrO{}BRb
Ny>Rh@GZt=p{tXQ$!rlM?

literal 0
HcmV?d00001