diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 6d58e4c0..2b96041c 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -20,13 +20,13 @@ QT -= gui core CONFIG += plugin debug CONFIG -= thread exceptions qt rtti -INCLUDEPATH += $$[LIBACFUTILS]/SDK/CHeaders/XPLM -INCLUDEPATH += $$[LIBACFUTILS]/SDK/CHeaders/Widgets +INCLUDEPATH += $$[LIBACFUTILSBP]/SDK/CHeaders/XPLM +INCLUDEPATH += $$[LIBACFUTILSBP]/SDK/CHeaders/Widgets # Always just use the shipped OpenAL headers for predictability. # The ABI is X-Plane-internal and stable anyway. -INCLUDEPATH += $$[LIBACFUTILS]/OpenAL/include -INCLUDEPATH += $$[LIBACFUTILS]/src -INCLUDEPATH += $$[LIBACFUTILS]/acf_apis +INCLUDEPATH += $$[LIBACFUTILSBP]/OpenAL/include +INCLUDEPATH += $$[LIBACFUTILSBP]/src +INCLUDEPATH += $$[LIBACFUTILSBP]/acf_apis QMAKE_CFLAGS += -std=c99 -g -W -Wall -Wextra -Werror -fvisibility=hidden \ -Wno-unused-local-typedefs -Wunused-result @@ -53,7 +53,7 @@ DEFINES += BP_PLUGIN_VERSION=\'\"$$system("git describe --abbrev=0 --tags")\"\' !macx { LIBS += -static-libgcc } - +LIBACFUTILSBP win32 { CONFIG += dll DEFINES += APL=0 IBM=1 LIN=0 _WIN32_WINNT=0x0600 @@ -63,16 +63,16 @@ win32 { } win32:contains(CROSS_COMPILE, x86_64-w64-mingw32-) { - QMAKE_CFLAGS += $$system("$$[LIBACFUTILS]/pkg-config-deps win-64 \ + QMAKE_CFLAGS += $$system("$$[LIBACFUTILSBP]/pkg-config-deps win-64 \ --static-openal --cflags") # This must go first for GCC to properly find dependent symbols - LIBS += -L$$[LIBACFUTILS]/qmake/win64 -lacfutils - LIBS += $$system("$$[LIBACFUTILS]/pkg-config-deps win-64 \ + LIBS += -L$$[LIBACFUTILSBP]/qmake/win64 -lacfutils + LIBS += $$system("$$[LIBACFUTILSBP]/pkg-config-deps win-64 \ --static-openal --libs") - LIBS += -L$$[LIBACFUTILS]/SDK/Libraries/Win -lXPLM_64 -lXPWidgets_64 - LIBS += -L$$[LIBACFUTILS]/GL_for_Windows/lib -lglu32 -lopengl32 + LIBS += -L$$[LIBACFUTILSBP]/SDK/Libraries/Win -lXPLM_64 -lXPWidgets_64 + LIBS += -L$$[LIBACFUTILSBP]/GL_for_Windows/lib -lglu32 -lopengl32 LIBS += -ldbghelp } @@ -85,11 +85,11 @@ unix:!macx { } linux-g++-64 { - QMAKE_CFLAGS += $$system("$$[LIBACFUTILS]/pkg-config-deps linux-64 \ + QMAKE_CFLAGS += $$system("$$[LIBACFUTILSBP]/pkg-config-deps linux-64 \ --static-openal --cflags") - LIBS += -L$$[LIBACFUTILS]/qmake/lin64 -lacfutils - LIBS += $$system("$$[LIBACFUTILS]/pkg-config-deps linux-64 \ + LIBS += -L$$[LIBACFUTILSBP]/qmake/lin64 -lacfutils + LIBS += $$system("$$[LIBACFUTILSBP]/pkg-config-deps linux-64 \ --static-openal --libs") } @@ -101,18 +101,18 @@ macx { DEFINES += APL=1 IBM=0 LIN=0 TARGET = mac.xpl - LIBS += -F$$[LIBACFUTILS]/SDK/Libraries/Mac + LIBS += -F$$[LIBACFUTILSBP]/SDK/Libraries/Mac LIBS += -framework OpenGL -framework AudioToolbox LIBS += -framework CoreAudio -framework AudioUnit LIBS += -framework XPLM -framework XPWidgets } macx-clang { - QMAKE_CFLAGS += $$system("$$[LIBACFUTILS]/pkg-config-deps mac-64 \ + QMAKE_CFLAGS += $$system("$$[LIBACFUTILSBP]/pkg-config-deps mac-64 \ --static-openal --cflags") - LIBS += -L$$[LIBACFUTILS]/qmake/mac64 -lacfutils - LIBS += $$system("$$[LIBACFUTILS]/pkg-config-deps mac-64 \ + LIBS += -L$$[LIBACFUTILSBP]/qmake/mac64 -lacfutils + LIBS += $$system("$$[LIBACFUTILSBP]/pkg-config-deps mac-64 \ --static-openal --libs") } diff --git a/src/bp.c b/src/bp.c index 0fa27321..9aa2fe34 100644 --- a/src/bp.c +++ b/src/bp.c @@ -214,6 +214,8 @@ max_steer_angle(void) static bool_t pbrake_is_set(void) { + if (pb_set_remote) + return B_TRUE; if (drs.pbrake_is_custom) return (dr_getf(&drs.pbrake) != 0); return (dr_getf(&drs.pbrake) != 0 || dr_getf(&drs.pbrake_rat) != 0); @@ -1244,6 +1246,63 @@ bp_delete_all_segs(void) free(seg); } +void +bp_set_step(pushback_step_t stp) +{ + if (bp.step == stp) { + return; + } + + bp.step = stp; + bp.step_start_t = bp.cur_t; + + bp_msg_play_on_next_step(); +} + +void bp_msg_play_on_next_step(void) +{ + switch (bp.step) { + case PB_STEP_LOWERING: + msg_play(MSG_DISCO); + bp.last_voice_t = bp.cur_t; + break; + case PB_STEP_DRIVING_UP_CLOSE: + msg_play(MSG_DRIVING_UP); + bp.last_voice_t = bp.cur_t; + break; + case PB_STEP_STARTING: + // Message playe here depends on some logic + // which has been left in pb_step_connected(void) + // but probably should be moved into its own func + bp.last_voice_t = bp.cur_t; + break; + case PB_STEP_STOPPED: + msg_play(MSG_OP_COMPLETE); + bp.last_voice_t = bp.cur_t; + break; + default: + break; + } +} + +void +bp_set_step_local(pushback_step_t stp) +{ + bp_set_step(stp); +} + +void +bp_set_step_rcvd(pushback_step_t stp) +{ + + if (slave_mode) { + if (bp.step != stp) { + logMsg("[ADVISORY/DEBUG] bp.step change received with new value of %d (currently %d)", stp, bp.step); + } + //bp_set_step(stp); + } +} + bool_t bp_start(void) { @@ -1266,8 +1325,7 @@ bp_start(void) bp.last_pos = bp.cur_pos; bp.last_t = bp.cur_t; - bp.step = 1; - bp.step_start_t = bp.cur_t; + bp_set_step(1); /* * Memorize where we were at the start. We will use this to determine @@ -1604,9 +1662,8 @@ pb_step_tug_load(void) } else { tug_set_pos(bp_ls.tug, bp.cur_pos.pos, bp.cur_pos.hdg, 0); } - bp.step++; - bp.step_start_t = bp.cur_t; - + bp_set_step_local(bp.step+1); + return (B_TRUE); } @@ -1637,10 +1694,7 @@ pb_step_start(void) } } - msg_play(MSG_DRIVING_UP); - bp.step++; - bp.step_start_t = bp.cur_t; - bp.last_voice_t = bp.cur_t; + bp_set_step_local(bp.step+1); } static void @@ -1656,8 +1710,7 @@ pb_step_driving_up_close(void) tug_set_cradle_beeper_on(bp_ls.tug, B_TRUE); tug_set_cradle_lights_on(B_TRUE); tug_set_hazard_lights_on(B_TRUE); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -1704,8 +1757,7 @@ pb_step_waiting_for_pbrake(void) -(bp_ls.tug->info->apch_dist + bp_ls.tug->info->plat_z))); } VERIFY(tug_drive2point(bp_ls.tug, p_end, bp.cur_pos.hdg)); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } static void @@ -1721,8 +1773,7 @@ pb_step_driving_up_connect(void) bp.step_start_t = bp.cur_t; } else if (bp.cur_t - bp.step_start_t >= STATE_TRANS_DELAY) { bp.winching.start_acf_pos = bp.cur_pos.pos; - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -1741,8 +1792,7 @@ pb_step_connect_grab(void) } if (cradle_closed_fract >= 1) { - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -1753,6 +1803,8 @@ pb_step_connect_winch(void) const tug_info_t *ti = bp_ls.tug->info; double winch_total, winched_dist; + logMsg("[DEBUG] In step PB_STEP_GRABBING with pb_step_connect_winch ..."); + /* spend some time putting the winching strap in place */ if (!bp.winching.complete && d_t < STATE_TRANS_DELAY) return; @@ -1803,8 +1855,7 @@ pb_step_connect_winch(void) } if (bp.winching.complete) { - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -1883,8 +1934,7 @@ pb_step_lift(void) msg_play(MSG_CONNECTED); bp.last_voice_t = bp.cur_t; } - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -1920,9 +1970,7 @@ pb_step_connected(void) msg_play(MSG_START_PB); } - bp.step++; - bp.step_start_t = bp.cur_t; - bp.last_voice_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -1951,8 +1999,7 @@ pb_step_pushing(void) if (!slave_mode) { dr_seti(&drs.override_steer, 1); if (!bp_run_push()) { - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); op_complete = B_TRUE; } } else { @@ -2011,10 +2058,7 @@ pb_step_stopping(void) if (!slave_mode) brakes_set(B_TRUE); if (bp.cur_t - bp.step_start_t >= STATE_TRANS_DELAY) { - msg_play(MSG_OP_COMPLETE); - bp.step++; - bp.step_start_t = bp.cur_t; - bp.last_voice_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } } @@ -2027,6 +2071,9 @@ pb_step_stopped(void) push_at_speed(0, bp.veh.max_accel, B_FALSE, B_FALSE); brakes_set(B_TRUE); } + + logMsg("[DEBUG] In pb step stopped..."); + if (!pbrake_is_set()) { /* * Keep resetting the start time to enforce a delay @@ -2036,9 +2083,7 @@ pb_step_stopped(void) } else if (bp.cur_t - bp.step_start_t >= STATE_TRANS_DELAY && bp.cur_t - bp.last_voice_t >= msg_dur(MSG_OP_COMPLETE) + STATE_TRANS_DELAY) { - msg_play(MSG_DISCO); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); bp.last_voice_t = bp.cur_t; } } @@ -2085,8 +2130,7 @@ pb_step_lowering(void) if (lift_fract == 0) { tug_set_cradle_air_on(bp_ls.tug, B_FALSE, bp.cur_t); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -2146,8 +2190,7 @@ pb_step_ungrabbing(void) bp.reconnect = B_FALSE; bp.ok2disco = B_FALSE; - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -2189,8 +2232,7 @@ pb_step_closing_cradle(void) tug_set_hazard_lights_on(B_FALSE); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); bp.last_voice_t = bp.cur_t; } } @@ -2257,8 +2299,7 @@ recon_handler(XPLMCommandRef cmd, XPLMCommandPhase phase, void *refcon) */ op_complete = B_FALSE; bp.reconnect = B_TRUE; - bp.step = PB_STEP_GRABBING; - bp.step_start_t = bp.cur_t; + bp_set_step_local(PB_STEP_GRABBING); bp_reconnect_notify(); return (1); } @@ -2387,8 +2428,7 @@ pb_step_waiting4ok2disco(void) -bp.acf.nw_z + bp_ls.tug->info->apch_dist)); (void) tug_drive2point(bp_ls.tug, p, bp.cur_pos.hdg); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } } @@ -2434,8 +2474,7 @@ pb_step_starting2clear(void) VERIFY(tug_drive2point(bp_ls.tug, turn_p, turn_hdg)); VERIFY(tug_drive2point(bp_ls.tug, abeam_p, back_hdg)); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } static void @@ -2520,8 +2559,7 @@ pb_step_clear_signal(void) } } tug_set_clear_signal(B_FALSE, B_FALSE); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } /* @@ -2613,7 +2651,14 @@ bp_run(float elapsed, float elapsed2, int counter, void *refcon) bp.d_pos.spd = bp.cur_pos.spd - bp.last_pos.spd; bp.d_t = bp.cur_t - bp.last_t; - ASSERT(bp_ls.tug != NULL || bp.step <= PB_STEP_TUG_LOAD); + //ASSERT(bp_ls.tug != NULL || bp.step <= PB_STEP_TUG_LOAD); + + if (bp_ls.tug == NULL && bp.step > PB_STEP_TUG_LOAD) { + ASSERT3P(bp_ls.tug, ==, NULL); + if (!pb_step_tug_load()) + return (0); + } + if (bp_ls.tug != NULL) { /* drive slowly while approaching & moving away from acf */ tug_run(bp_ls.tug, bp.d_t, @@ -2673,9 +2718,9 @@ bp_run(float elapsed, float elapsed2, int counter, void *refcon) */ if (ABS(bp.cur_pos.spd) < SPEED_COMPLETE_THRESH && pbrake_is_set()) { - bp.step = PB_STEP_STOPPED; + bp_set_step_local(PB_STEP_STOPPED); } else { - bp.step = PB_STEP_STOPPING; + bp_set_step_local(PB_STEP_STOPPING); } } } @@ -2687,7 +2732,7 @@ bp_run(float elapsed, float elapsed2, int counter, void *refcon) if (bp.step < PB_STEP_CONNECTED) { double lift = bp_ls.tug->info->lift_height + bp.acf.nw_len; - bp.step = PB_STEP_CONNECTED; + bp_set_step_local(PB_STEP_CONNECTED); tug_set_lift_pos(1); tug_set_lift_arm_pos(bp_ls.tug, 0, B_TRUE); dr_setvf(&drs.leg_len, &lift, bp.acf.nw_i, 1); @@ -2746,8 +2791,7 @@ bp_run(float elapsed, float elapsed2, int counter, void *refcon) msg_play(MSG_RDY2CONN); bp.last_voice_t = bp.cur_t; } - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } break; } @@ -2772,8 +2816,8 @@ bp_run(float elapsed, float elapsed2, int counter, void *refcon) brakes_set(B_FALSE); } if (bp.cur_t - bp.step_start_t >= PB_START_DELAY) { - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); + } else if (!slave_mode) { seg_t *seg = list_tail(&bp.segs); ASSERT(seg != NULL); @@ -2830,8 +2874,7 @@ bp_run(float elapsed, float elapsed2, int counter, void *refcon) } if (tug_is_stopped(bp_ls.tug)) { tug_set_cradle_beeper_on(bp_ls.tug, B_TRUE); - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } break; case PB_STEP_CLOSING_CRADLE: @@ -2842,8 +2885,7 @@ bp_run(float elapsed, float elapsed2, int counter, void *refcon) break; case PB_STEP_MOVING2CLEAR: if (tug_is_stopped(bp_ls.tug)) { - bp.step++; - bp.step_start_t = bp.cur_t; + bp_set_step_local(bp.step+1); } break; case PB_STEP_CLEAR_SIGNAL: diff --git a/src/bp.h b/src/bp.h index a049d635..1293cbb2 100644 --- a/src/bp.h +++ b/src/bp.h @@ -162,6 +162,11 @@ void bp_fini(void); bool_t bp_start(void); bool_t bp_stop(void); +void bp_set_step(pushback_step_t stp); +void bp_msg_play_on_next_step(void); +void bp_set_step_local(pushback_step_t stp); +void bp_set_step_rcvd(pushback_step_t stp); + bool_t bp_can_start(const char **reason); unsigned bp_num_segs(void); void bp_delete_all_segs(void); diff --git a/src/bp_cam.c b/src/bp_cam.c index 3e77d1f2..5c6a899d 100644 --- a/src/bp_cam.c +++ b/src/bp_cam.c @@ -396,7 +396,7 @@ vp_unproject(double x, double y, double *x_phys, double *y_phys) ASSERT(!isnan(out_pt[0])); ASSERT(!isnan(out_pt[1])); ASSERT(out_pt[2] != 0); - glm_vec_scale(out_pt, ABS(cam_height / out_pt[2]), out_pt); + glm_vec3_scale(out_pt, ABS(cam_height / out_pt[2]), out_pt); ASSERT(!isnan(out_pt[0])); ASSERT(!isnan(out_pt[1])); *x_phys = out_pt[0]; diff --git a/src/xplane.c b/src/xplane.c index d241807f..7b8b9cb2 100644 --- a/src/xplane.c +++ b/src/xplane.c @@ -55,15 +55,16 @@ #define STATUS_CHECK_INTVAL 1 /* second */ enum { - SMARTCOPILOT_STATE_OFF = 0, /* disconnected */ - SMARTCOPILOT_STATE_SLAVE = 1, /* connected and we're slave */ - SMARTCOPILOT_STATE_MASTER = 2 /* connected and we're master */ + COUPLED_STATE_OFF = 0, /* disconnected */ + COUPLED_STATE_SLAVE = 1, /* connected and we're slave */ + COUPLED_STATE_MASTER = 2, /* connected and we're master */ + COUPLED_STATE_PASSENGER = -1 /* connected and we're passenger */ }; static bool_t inited = B_FALSE; static XPLMCommandRef start_pb, stop_pb, start_cam, stop_cam, conn_first; -static XPLMCommandRef cab_cam, recreate_routes; +static XPLMCommandRef cab_cam, recreate_routes, abort_push; static XPLMMenuID root_menu, dev_menu; static int plugins_menu_item, dev_menu_item; static int start_pb_plan_menu_item, stop_pb_plan_menu_item; @@ -78,6 +79,7 @@ static int stop_cam_handler(XPLMCommandRef, XPLMCommandPhase, void *); static int conn_first_handler(XPLMCommandRef, XPLMCommandPhase, void *); static int cab_cam_handler(XPLMCommandRef, XPLMCommandPhase, void *); static int recreate_routes_handler(XPLMCommandRef, XPLMCommandPhase, void *); +static int abort_push_handler(XPLMCommandRef, XPLMCommandPhase, void *); static bool_t start_after_cam = B_FALSE; @@ -89,6 +91,9 @@ const char *const bp_plugindir = plugindir; static bool_t smartcopilot_present; static dr_t smartcopilot_state; +static bool_t sharedflight_present; +static dr_t sharedflight_state; + int bp_xp_ver, bp_xplm_ver; XPLMHostApplicationID bp_host_id; airportdb_t *airportdb = NULL; @@ -139,11 +144,13 @@ static XPLMFlightLoopID reload_floop_ID = NULL; * disabled on the slave machine and stopping of the pushback can only be * performed by the master machine. */ -static dr_t bp_started_dr, bp_connected_dr, slave_mode_dr, op_complete_dr; +static dr_t bp_started_dr, bp_connected_dr, slave_mode_dr, pb_set_remote_dr; +static dr_t op_complete_dr, step_dr; static dr_t plan_complete_dr, bp_tug_name_dr; bool_t bp_started = B_FALSE; bool_t bp_connected = B_FALSE; bool_t slave_mode = B_FALSE; +bool_t pb_set_remote = B_FALSE; bool_t op_complete = B_FALSE; bool_t plan_complete = B_FALSE; char bp_tug_name[64] = { 0 }; @@ -232,6 +239,7 @@ init_core_state(void) bp_started = B_FALSE; bp_connected = B_FALSE; slave_mode = B_FALSE; + pb_set_remote = B_FALSE; op_complete = B_FALSE; plan_complete = B_FALSE; } @@ -448,6 +456,18 @@ bp_get_lang(void) return (acfutils_xplang2code(XPLMGetLanguage())); } + +static void +coupled_state_change() +{ + /* If we were in slave mode, reenable the menu items. */ + XPLMEnableMenuItem(root_menu, start_pb_menu_item, slave_mode ? 1 : 0); + XPLMEnableMenuItem(root_menu, start_pb_plan_menu_item, slave_mode ? 1 : 0); + + XPLMEnableMenuItem(root_menu, stop_pb_menu_item, B_FALSE); + XPLMEnableMenuItem(root_menu, stop_pb_plan_menu_item, B_FALSE); +} + void slave_mode_cb(dr_t *dr, void *unused) { @@ -457,16 +477,29 @@ slave_mode_cb(dr_t *dr, void *unused) if (slave_mode) { bp_fini(); - XPLMEnableMenuItem(root_menu, start_pb_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, stop_pb_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, start_pb_plan_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, stop_pb_plan_menu_item, B_FALSE); } else { - XPLMEnableMenuItem(root_menu, start_pb_menu_item, B_TRUE); - XPLMEnableMenuItem(root_menu, stop_pb_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, start_pb_plan_menu_item, B_TRUE); - XPLMEnableMenuItem(root_menu, stop_pb_plan_menu_item, B_FALSE); + pb_set_remote = B_FALSE; } + + coupled_state_change(); +} + +void +pb_set_remote_cb(dr_t *dr, void *new_remote_pb_ptr) +{ + UNUSED(dr); + + pb_set_remote = *((int*) new_remote_pb_ptr) ? B_TRUE : B_FALSE; +} + +void +step_cb(dr_t *dr, void *new_step_ptr) +{ + UNUSED(dr); + + pushback_step_t new_step = *((pushback_step_t*) new_step_ptr); + + bp_set_step_rcvd(new_step); } static float @@ -479,10 +512,11 @@ status_check(float elapsed, float elapsed2, int counter, void *refcon) XPLMEnableMenuItem(root_menu, cab_cam_menu_item, cab_view_can_start()); - if (!smartcopilot_present) + // Status check only needed if we have a known system of coupling installed... + if (!smartcopilot_present && !sharedflight_present) return (1); - if (dr_geti(&smartcopilot_state) == SMARTCOPILOT_STATE_SLAVE && + if (smartcopilot_present && dr_geti(&smartcopilot_state) == COUPLED_STATE_SLAVE && !slave_mode) { if (bp_started) { XPLMSpeakString(_("Pushback failure: smartcopilot " @@ -495,25 +529,40 @@ status_check(float elapsed, float elapsed2, int counter, void *refcon) * will control us. */ bp_fini(); - XPLMEnableMenuItem(root_menu, start_pb_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, stop_pb_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, start_pb_plan_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, stop_pb_plan_menu_item, B_FALSE); slave_mode = B_TRUE; - } else if (dr_geti(&smartcopilot_state) != SMARTCOPILOT_STATE_SLAVE && + coupled_state_change(); + } else if (sharedflight_present && dr_geti(&sharedflight_state) == COUPLED_STATE_SLAVE && + !slave_mode) { + if (bp_started) { + XPLMSpeakString(_("Pushback failure: Shared Flight " + "attempted to switch pilot flying or network " + "connection lost. Stopping operation.")); + } + bp_fini(); + slave_mode = B_TRUE; + coupled_state_change(); + } else if ((smartcopilot_present && dr_geti(&smartcopilot_state) != COUPLED_STATE_SLAVE) && + (!sharedflight_present || dr_geti(&sharedflight_state) != COUPLED_STATE_SLAVE) && slave_mode) { if (bp_started) { XPLMSpeakString(_("Pushback failure: smartcopilot " "attempted to switch master/slave or network " "connection lost. Stopping operation.")); } - /* If we were in slave mode, reenable the menu items. */ bp_fini(); - XPLMEnableMenuItem(root_menu, start_pb_menu_item, B_TRUE); - XPLMEnableMenuItem(root_menu, stop_pb_menu_item, B_FALSE); - XPLMEnableMenuItem(root_menu, start_pb_plan_menu_item, B_TRUE); - XPLMEnableMenuItem(root_menu, stop_pb_plan_menu_item, B_FALSE); slave_mode = B_FALSE; + coupled_state_change(); + } else if ((sharedflight_present && dr_geti(&sharedflight_state) != COUPLED_STATE_SLAVE && dr_geti(&sharedflight_state) != COUPLED_STATE_PASSENGER) && + (!smartcopilot_present || dr_geti(&smartcopilot_state) != COUPLED_STATE_SLAVE) && + slave_mode) { + if (bp_started) { + XPLMSpeakString(_("Pushback failure: Shared Flight " + "attempted to switch pilot flying or network " + "connection lost. Stopping operation.")); + } + bp_fini(); + slave_mode = B_FALSE; + coupled_state_change(); } return (STATUS_CHECK_INTVAL); @@ -608,6 +657,10 @@ XPluginStart(char *name, char *sig, char *desc) "BetterPushback/recreate_scenery_routes", _("Recreate scenery routes from WED files.")); + abort_push = XPLMCreateCommand("BetterPushback/abort_push", + _("Abort pushback during coupled push")); + + bp_boot_init(); dr_create_i(&bp_started_dr, (int *)&bp_started, B_FALSE, @@ -617,6 +670,12 @@ XPluginStart(char *name, char *sig, char *desc) dr_create_i(&slave_mode_dr, (int *)&slave_mode, B_TRUE, "bp/slave_mode"); slave_mode_dr.write_cb = slave_mode_cb; + dr_create_i(&pb_set_remote_dr, (int *)&pb_set_remote, B_TRUE, + "bp/pb_remote"); + pb_set_remote_dr.write_cb = pb_set_remote_cb; + dr_create_i(&step_dr, (int *)&bp.step, B_TRUE, + "bp/step"); + step_dr.write_cb = step_cb; dr_create_i(&op_complete_dr, (int *)&op_complete, B_TRUE, "bp/op_complete"); dr_create_i(&plan_complete_dr, (int *)&plan_complete, B_TRUE, @@ -640,6 +699,8 @@ XPluginStop(void) bp_shut_fini(); dr_delete(&bp_started_dr); dr_delete(&slave_mode_dr); + dr_delete(&pb_set_remote_dr); + dr_delete(&step_dr); dr_delete(&op_complete_dr); dr_delete(&bp_tug_name_dr); @@ -680,6 +741,9 @@ XPluginReceiveMessage(XPLMPluginID from, int msg, void *param) /* Force a reinit to re-read aircraft size params */ smartcopilot_present = dr_find(&smartcopilot_state, "scp/api/ismaster"); + sharedflight_present = dr_find(&sharedflight_state, + "SharedFlight/is_pilot_flying"); + stop_cam_handler(NULL, xplm_CommandEnd, NULL); bp_fini(); cab_view_fini(); @@ -731,6 +795,7 @@ bp_priv_enable(void) XPLMRegisterCommandHandler(cab_cam, cab_cam_handler, 1, NULL); XPLMRegisterCommandHandler(recreate_routes, recreate_routes_handler, 1, NULL); + XPLMRegisterCommandHandler(abort_push, abort_push_handler, 1, NULL); plugins_menu_item = XPLMAppendMenuItem(XPLMFindPluginsMenu(), "Better Pushback", NULL, 1); @@ -843,6 +908,21 @@ bp_sched_reload(void) XPLMScheduleFlightLoop(reload_floop_ID, -1, 1); } +static int +abort_push_handler(XPLMCommandRef cmd, XPLMCommandPhase phase, + void *refcon) +{ + UNUSED(cmd); + UNUSED(refcon); + if (phase != xplm_CommandEnd) + return (0); + bp_fini(); + logMsg("bp_fini called from abort_push_handler, bp_started = %d", bp_started); + slave_mode = B_FALSE; + coupled_state_change(); + return (1); +} + #if IBM BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID resvd) @@ -852,4 +932,4 @@ DllMain(HINSTANCE hinst, DWORD reason, LPVOID resvd) lacf_glew_dllmain_hook(reason); return (TRUE); } -#endif /* IBM */ +#endif /* IBM */ \ No newline at end of file diff --git a/src/xplane.h b/src/xplane.h index b659bf82..54428f9f 100644 --- a/src/xplane.h +++ b/src/xplane.h @@ -38,6 +38,7 @@ extern const char *const bp_plugindir; extern bool_t bp_started; extern bool_t bp_connected; extern bool_t slave_mode; +extern bool_t pb_set_remote; extern bool_t op_complete; extern bool_t plan_complete; extern char bp_tug_name[64];