2010-12-19 22:09:53 +00:00
|
|
|
###############################################################################
|
|
|
|
##
|
|
|
|
## Nasal for dual control of a KX165 NavComm radio over the multiplayer
|
|
|
|
## network.
|
|
|
|
##
|
2011-07-11 18:22:26 +00:00
|
|
|
## Copyright (C) 2007 - 2011 Anders Gidenstam (anders(at)gidenstam.org)
|
2010-12-19 22:09:53 +00:00
|
|
|
## This file is licensed under the GPL license version 2 or later.
|
|
|
|
##
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
# Note:
|
|
|
|
# This module MUST be loaded as KX165.
|
|
|
|
#
|
|
|
|
|
|
|
|
# Slave button presses.
|
|
|
|
var swap_btn = "frq-swap-btn";
|
|
|
|
var freq_decS = "freq-decS-clicked";
|
|
|
|
var freq_incS = "freq-incS-clicked";
|
|
|
|
var freq_decL = "freq-decL-clicked";
|
|
|
|
var freq_incL = "freq-incL-clicked";
|
|
|
|
|
|
|
|
# Settings
|
|
|
|
var freq_selected = "frequencies/selected-mhz";
|
|
|
|
var freq_standby = "frequencies/standby-mhz";
|
|
|
|
|
|
|
|
var comm_base = ["instrumentation/comm[0]",
|
|
|
|
"instrumentation/comm[1]"];
|
|
|
|
var nav_base = ["instrumentation/nav[0]",
|
|
|
|
"instrumentation/nav[1]"];
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
var master_kx165tso = {
|
|
|
|
new : func(n) {
|
|
|
|
var obj = {};
|
|
|
|
obj.parents = [master_kx165tso];
|
|
|
|
obj.nav_base = props.globals.getNode("instrumentation/nav[" ~ n ~ "]");
|
|
|
|
obj.comm_base = props.globals.getNode("instrumentation/comm[" ~ n ~ "]");
|
|
|
|
return obj;
|
|
|
|
},
|
|
|
|
swap_nav : func() {
|
|
|
|
var tmp = me.nav_base.getNode(freq_selected).getValue();
|
|
|
|
me.nav_base.getNode(freq_selected).setValue
|
|
|
|
(me.nav_base.getNode(freq_standby).getValue());
|
|
|
|
me.nav_base.getNode(freq_standby).setValue(tmp);
|
|
|
|
},
|
|
|
|
swap_comm : func() {
|
|
|
|
var tmp = me.comm_base.getNode(freq_selected).getValue();
|
|
|
|
me.comm_base.getNode(freq_selected).setValue
|
|
|
|
(me.comm_base.getNode(freq_standby).getValue());
|
|
|
|
me.comm_base.getNode(freq_standby).setValue(tmp);
|
|
|
|
},
|
|
|
|
adjust_nav_frequency : func(d) {
|
|
|
|
adjust_radio_frequency(
|
|
|
|
me.nav_base.getNode(freq_standby),
|
|
|
|
d,
|
|
|
|
108,
|
|
|
|
117.95);
|
|
|
|
},
|
|
|
|
adjust_comm_frequency : func(d) {
|
|
|
|
adjust_radio_frequency(
|
|
|
|
me.comm_base.getNode(freq_standby),
|
|
|
|
d,
|
|
|
|
118,
|
|
|
|
135.975);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
var slave_kx165tso = {
|
|
|
|
new : func(n, airoot) {
|
|
|
|
var obj = {};
|
|
|
|
obj.parents = [slave_kx165tso];
|
|
|
|
obj.root = airoot;
|
|
|
|
obj.nav_base = props.globals.getNode("instrumentation/nav[" ~ n ~ "]");
|
|
|
|
obj.comm_base = props.globals.getNode("instrumentation/comm[" ~ n ~ "]");
|
|
|
|
return obj;
|
|
|
|
},
|
|
|
|
swap_nav : func() {
|
|
|
|
var p = me.nav_base.getNode(swap_btn);
|
|
|
|
# print("KX165tso[?].NAVSWAP");
|
|
|
|
if (!p.getValue()) {
|
|
|
|
p.setValue(1);
|
|
|
|
settimer(func { p.setValue(0); },
|
|
|
|
1.0);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
swap_comm : func() {
|
|
|
|
var p = me.comm_base.getNode(swap_btn);
|
|
|
|
# print("KX165tso[?].COMMSWAP");
|
|
|
|
if (!p.getValue()) {
|
|
|
|
p.setValue(1);
|
|
|
|
settimer(func { p.setValue(0); },
|
|
|
|
1.0);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
adjust_nav_frequency : func(d) {
|
|
|
|
var p = 0;
|
|
|
|
if (abs(d) < 0.99) {
|
|
|
|
p = (d < 0) ? me.nav_base.getNode(freq_decS)
|
|
|
|
: me.nav_base.getNode(freq_incS);
|
|
|
|
} else {
|
|
|
|
p = (d < 0) ? me.nav_base.getNode(freq_decL)
|
|
|
|
: me.nav_base.getNode(freq_incL);
|
|
|
|
}
|
|
|
|
if (!p.getValue()) {
|
|
|
|
p.setValue(1);
|
|
|
|
settimer(func { p.setValue(0); },
|
|
|
|
1.0);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
adjust_comm_frequency : func(d) {
|
|
|
|
var p = 0;
|
|
|
|
if (abs(d) < 0.99) {
|
|
|
|
p = (d < 0) ? me.comm_base.getNode(freq_decS)
|
|
|
|
: me.comm_base.getNode(freq_incS);
|
|
|
|
} else {
|
|
|
|
p = (d < 0) ? me.comm_base.getNode(freq_decL)
|
|
|
|
: me.comm_base.getNode(freq_incL);
|
|
|
|
}
|
|
|
|
if (!p.getValue()) {
|
|
|
|
p.setValue(1);
|
|
|
|
settimer(func { p.setValue(0); },
|
|
|
|
1.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# The KX-165 pick animations default to master.
|
|
|
|
# NOTE: Use make_master() and make_slave_to().
|
|
|
|
# Do NOT change kx165tso directly.
|
|
|
|
var kx165tso = [master_kx165tso.new(0), master_kx165tso.new(1)];
|
|
|
|
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# API for pick animations and dual control setup.
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# n - NavComm#
|
|
|
|
var make_master = func(n) {
|
|
|
|
kx165tso[n] = master_kx165tso.new(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# n - NavComm#
|
|
|
|
var make_slave_to = func(n, airoot) {
|
|
|
|
kx165tso[n] = slave_kx165tso.new(n, airoot);
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# n - NavComm#
|
2011-07-11 18:22:26 +00:00
|
|
|
var swap_nav = func(n) {
|
2010-12-19 22:09:53 +00:00
|
|
|
kx165tso[n].swap_nav();
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# n - NavComm#
|
2011-07-11 18:22:26 +00:00
|
|
|
var swap_comm = func(n, b) {
|
2010-12-19 22:09:53 +00:00
|
|
|
kx165tso[n].comm_base.getNode(swap_btn, 1).setValue(b);
|
|
|
|
if (b) kx165tso[n].swap_comm();
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# n - NavComm#
|
|
|
|
# d - adjustment
|
2011-07-11 18:22:26 +00:00
|
|
|
var adjust_nav_frequency = func(n, d) {
|
2010-12-19 22:09:53 +00:00
|
|
|
kx165tso[n].adjust_nav_frequency(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# n - NavComm#
|
|
|
|
# d - adjustment
|
2011-07-11 18:22:26 +00:00
|
|
|
var adjust_comm_frequency = func(n, d) {
|
2010-12-19 22:09:53 +00:00
|
|
|
kx165tso[n].adjust_comm_frequency(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# Create aliases to drive a radio 3d model in an AI/MP model.
|
|
|
|
# n - NavComm#
|
|
|
|
var animate_aimodel = func(n, airoot) {
|
|
|
|
# Comm
|
|
|
|
var base = comm_base[n];
|
|
|
|
var p = "systems/electrical/outputs/comm["~ n ~"]";
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = "instrumentation/comm["~ n ~"]/serviceable";
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = base ~ "/" ~ freq_selected;
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = base ~ "/" ~ freq_standby;
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = base ~ "/" ~ swap_btn;
|
|
|
|
props.globals.getNode(p, 1).alias(airoot.getNode(p));
|
|
|
|
# Nav
|
|
|
|
base = nav_base[n];
|
|
|
|
p = "systems/electrical/outputs/nav["~ n ~"]";
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = "instrumentation/nav["~ n ~"]/serviceable";
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = base ~ "/" ~ freq_selected;
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = base ~ "/" ~ freq_standby;
|
|
|
|
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
|
|
|
p = base ~ "/" ~ swap_btn;
|
|
|
|
props.globals.getNode(p, 1).alias(airoot.getNode(p));
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# Create a TDMEncoder node array for sending the current radio state to
|
|
|
|
# slaves.
|
|
|
|
# n - NavComm#
|
|
|
|
var master_send_state = func(n) {
|
|
|
|
var cb = props.globals.getNode(comm_base[n]);
|
|
|
|
var nb = props.globals.getNode(nav_base[n]);
|
|
|
|
return
|
|
|
|
[
|
|
|
|
cb.getNode(freq_selected),
|
|
|
|
cb.getNode(freq_standby),
|
|
|
|
nb.getNode(freq_selected),
|
|
|
|
nb.getNode(freq_standby)
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# Create a SwitchDecoder action array for processing button presses
|
|
|
|
# from a slave.
|
|
|
|
# n - Comm#
|
|
|
|
var master_receive_slave_buttons = func(n) {
|
|
|
|
return
|
|
|
|
[
|
|
|
|
# Comm
|
|
|
|
func (b) {
|
|
|
|
if (b) {
|
|
|
|
swap_comm(n, 1);
|
|
|
|
settimer(func { swap_comm(n, 0); }, 1.0)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_comm_frequency(n, -0.025); }
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_comm_frequency(n, 0.025); }
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_comm_frequency(n, -1.0); }
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_comm_frequency(n, 1.0); }
|
|
|
|
},
|
|
|
|
# Nav
|
|
|
|
func (b) {
|
|
|
|
if (b) { swap_nav(n); }
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_nav_frequency(n, -0.05); }
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_nav_frequency(n, 0.05); }
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_nav_frequency(n, -1.0); }
|
|
|
|
},
|
|
|
|
func (b) {
|
|
|
|
if (b) { adjust_nav_frequency(n, 1.0); }
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# Create a TDMDecoder action array for processing the radio state
|
|
|
|
# from the master.
|
|
|
|
# n - NavComm#
|
|
|
|
var slave_receive_master_state = func(n) {
|
|
|
|
var cb = props.globals.getNode(comm_base[n]);
|
|
|
|
var nb = props.globals.getNode(nav_base[n]);
|
|
|
|
return
|
|
|
|
[
|
|
|
|
func (v) {
|
|
|
|
cb.getNode(freq_selected).setValue(v);
|
|
|
|
},
|
|
|
|
func (v) {
|
|
|
|
cb.getNode(freq_standby).setValue(v);
|
|
|
|
},
|
|
|
|
func (v) {
|
|
|
|
nb.getNode(freq_selected).setValue(v);
|
|
|
|
},
|
|
|
|
func (v) {
|
|
|
|
nb.getNode(freq_standby).setValue(v);
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# Create a SwitchEncoder node array for sending button presses
|
|
|
|
# to the master
|
|
|
|
# n - NavComm#
|
|
|
|
var slave_send_buttons = func(n) {
|
|
|
|
var cb = props.globals.getNode(comm_base[n]);
|
|
|
|
var nb = props.globals.getNode(nav_base[n]);
|
|
|
|
return
|
|
|
|
[
|
|
|
|
# Comm
|
|
|
|
cb.getNode(swap_btn, 1),
|
|
|
|
cb.getNode(freq_decS, 1),
|
|
|
|
cb.getNode(freq_incS, 1),
|
|
|
|
cb.getNode(freq_decL, 1),
|
|
|
|
cb.getNode(freq_incL, 1),
|
|
|
|
# Nav
|
|
|
|
nb.getNode(swap_btn, 1),
|
|
|
|
nb.getNode(freq_decS, 1),
|
|
|
|
nb.getNode(freq_incS, 1),
|
|
|
|
nb.getNode(freq_decL, 1),
|
|
|
|
nb.getNode(freq_incL, 1)
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
###########################################################################
|
|
|
|
# Generic frequency stepper.
|
|
|
|
# f - frequency property
|
|
|
|
# d - change
|
|
|
|
# min - min frequency
|
|
|
|
# max - max frequency
|
|
|
|
var adjust_radio_frequency = func(f, d, min, max) {
|
|
|
|
var old = f.getValue();
|
|
|
|
var new = old + d;
|
|
|
|
if (new < min - 0.005) { new = int(max) + (new - int(new)); }
|
|
|
|
if (new > max + 0.005) {
|
|
|
|
new = int(min) + (new - int(new));
|
|
|
|
if (int(new + 0.005) > min) new -= 1;
|
|
|
|
}
|
|
|
|
# print("Old: " ~ old ~ " Intermediate: " ~ (old + d) ~ " New: " ~ new);
|
|
|
|
f.setValue(new);
|
|
|
|
}
|