172172 * v2.8.12 [changed] Fixed issue with do_on_mouse_click now is only called once per mouse click Thanks apn from x-plane.org
173173 * v2.8.13 [Added] do_every_frame_after() callback to run in FlightLoop Phase 1 (after physics processing, thus eliminating
174174 * graphic jitter
175+ * [Added] do_every_frame_before() callback to run in FlightLoop Phase 1 (before physics processing)
176+ *
175177 * Markus (Teddii):
176178 * v2.1.20 [changed] bug fixed in Luahid_open() and Luahid_open_path(), setting last HID device index back if no device was found
177179 * [changed] extended logMsg() with logType=logToAll|logToDevCon|logToSqkBox. If XSquawkBox is not connected logMsg() will fall back to DevCon
@@ -2898,6 +2900,77 @@ static int LuaDoEveryFrame(lua_State* L)
28982900 return 0 ;
28992901}
29002902
2903+
2904+ // --- MULTI-CALLBACK VERSION OF: FlightLoop Callback BeforeFlightModel ---
2905+
2906+ static XPLMFlightLoopID g_DoEveryFrameBefore_ID = nullptr ;
2907+ static std::vector<std::string> do_every_frame_before_code;
2908+
2909+ // Called every frame before flight model is updated
2910+ float Do_Every_Frame_Before (float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop,
2911+ int inCounter, void * inRefcon)
2912+ {
2913+ if (!LuaIsRunning) return -1 .0f ;
2914+
2915+ CopyDataRefsToLua ();
2916+
2917+ for (const auto & code : do_every_frame_before_code)
2918+ {
2919+ if (luaL_loadstring (FWLLua, code.c_str ()) == LUA_OK)
2920+ {
2921+ if (lua_pcall (FWLLua, 0 , 0 , 0 ) != LUA_OK)
2922+ {
2923+ const char * err = lua_tostring (FWLLua, -1 );
2924+ logMsg (logToDevCon, std::string (" Error in do_every_frame_before(): " ) + err);
2925+ lua_pop (FWLLua, 1 );
2926+ }
2927+ }
2928+ else
2929+ {
2930+ const char * err = lua_tostring (FWLLua, -1 );
2931+ logMsg (logToDevCon, std::string (" Syntax error in do_every_frame_before(): " ) + err);
2932+ lua_pop (FWLLua, 1 );
2933+ }
2934+ }
2935+
2936+ CopyDataRefsToXPlane ();
2937+
2938+ return -1 .0f ; // every frame
2939+ }
2940+
2941+ void Register_Do_Every_Frame_Before ()
2942+ {
2943+ if (g_DoEveryFrameBefore_ID != nullptr )
2944+ return ;
2945+
2946+ XPLMCreateFlightLoop_t loop_params{};
2947+ loop_params.structSize = sizeof (XPLMCreateFlightLoop_t);
2948+ loop_params.phase = xplm_FlightLoop_Phase_BeforeFlightModel;
2949+ loop_params.callbackFunc = Do_Every_Frame_Before;
2950+ loop_params.refcon = nullptr ;
2951+
2952+ g_DoEveryFrameBefore_ID = XPLMCreateFlightLoop (&loop_params);
2953+ XPLMScheduleFlightLoop (g_DoEveryFrameBefore_ID, -1.0 , 0 );
2954+ }
2955+
2956+ static int LuaDoEveryFrameBefore (lua_State* L)
2957+ {
2958+ if (!lua_isstring (L, 1 ))
2959+ {
2960+ logMsg (logToDevCon, " FlyWithLua Error: do_every_frame_before() needs a string of Lua code." );
2961+ LuaIsRunning = false ;
2962+ return 0 ;
2963+ }
2964+
2965+ std::string lua_code = lua_tostring (L, 1 );
2966+ do_every_frame_before_code.push_back (lua_code);
2967+
2968+ return 0 ;
2969+ }
2970+
2971+ // --- End DoEveryFrameBefore routines
2972+
2973+
29012974// --- MULTI-CALLBACK VERSION OF: FlightLoop Callback AfterFlightModel ---
29022975
29032976static XPLMFlightLoopID g_DoEveryFrameAfter_ID = nullptr ;
@@ -6096,6 +6169,7 @@ void RegisterCoreCFunctionsToLua(lua_State* L)
60966169 lua_register (L, " do_on_mouse_wheel" , LuaDoEveryMouseWheel);
60976170 lua_register (L, " do_every_draw" , LuaDoEveryDrawCallback);
60986171 lua_register (L, " do_every_frame" , LuaDoEveryFrame);
6172+ lua_register (L, " do_every_frame_before" , LuaDoEveryFrameBefore); // Callback before FlightModel
60996173 lua_register (L, " do_every_frame_after" , LuaDoEveryFrameAfter); // Callback after FlightModel
61006174 lua_register (L, " do_often" , LuaDoOften);
61016175 lua_register (L, " do_sometimes" , LuaDoSometimes);
@@ -7434,6 +7508,14 @@ PLUGIN_API void XPluginDisable(void)
74347508 XPLMUnregisterFlightLoopCallback (MyFastLoopCallback, nullptr );
74357509 XPLMUnregisterFlightLoopCallback (MySlowLoopCallback, nullptr );
74367510 XPLMUnregisterFlightLoopCallback (MyEveryFrameLoopCallback, nullptr );
7511+
7512+ // Unregister and clean up the BeforeFlightModel flight loop
7513+ if (g_DoEveryFrameBefore_ID != nullptr )
7514+ {
7515+ XPLMDestroyFlightLoop (g_DoEveryFrameBefore_ID);
7516+ g_DoEveryFrameBefore_ID = nullptr ;
7517+ do_every_frame_before_code.clear ();
7518+ }
74377519
74387520 // Unregister and clean up the AfterFlightModel flight loop
74397521 if (g_DoEveryFrameAfter_ID != nullptr )
@@ -7443,7 +7525,6 @@ PLUGIN_API void XPluginDisable(void)
74437525 do_every_frame_after_code.clear ();
74447526 }
74457527
7446-
74477528 // write to Log.txt
74487529 logMsg (logToDevCon, " FlyWithLua Info: FlyWithLua plugin disabled." );
74497530}
@@ -7498,6 +7579,8 @@ PLUGIN_API int XPluginEnable(void)
74987579 nullptr ); /* refcon not used. */
74997580
75007581 XPLMRegisterDrawCallback (FWLDrawWindowCallback, xplm_Phase_Window, 0 , (void *) " FWLWindowDrawer" );
7582+
7583+ Register_Do_Every_Frame_Before (); // Provide a callback that runs in FlightLoop Phase Before mode.
75017584
75027585 Register_Do_Every_Frame_After (); // Provide a callback that runs in FlightLoop Phase After mode.
75037586
0 commit comments