diff --git a/LaunchConfig/minicave.cfg b/LaunchConfig/minicave.cfg
index b58e85793decb841a6885d311626affe358e432f..77b4267e821b5968417a8e26996dd262f2cb6e08 100644
--- a/LaunchConfig/minicave.cfg
+++ b/LaunchConfig/minicave.cfg
@@ -1,20 +1,28 @@
+[projection] id="proj_screen_floor" type="simple" screen="screen_floor"
+[projection] id="proj_screen_front" type="simple" screen="screen_front"
+[projection] id="proj_screen_left" type="simple" screen="screen_left"
+[projection] id="proj_screen_right" type="simple" screen="screen_right"
+[projection] id="proj_screen_back" type="simple" screen="screen_back"
+# AUTO_CONVERSION, new entities finish
+
+
 #####################################################################
 # nDisplay config file for aixCAVE
 #####################################################################
 
 #####################################################################
 # Config info
-#******************************************************************** 
+#********************************************************************
 # This is a config file header.
 #
 # Properties:
 # version - specifies the version of the configuration file (UE4.xx)
-#******************************************************************** 
-[info] version=22
+#********************************************************************
+[info] version="23"
 
 #####################################################################
 # Cluster nodes
-#******************************************************************** 
+#********************************************************************
 # Cluster node is an application instance. It's allowed to use
 # multiple instances on the same PC. Sometimes its necessary.
 #
@@ -30,16 +38,16 @@
 # Optional properties:
 # eye_swap - Swap eyes for this node; default is 'false'
 # sound    - turns on/off sound for this application instance; default is 'false'
-#********************************************************************      
+#********************************************************************
 [cluster_node] id=node_floor addr=127.0.0.1 window=wnd_floor port_cs=41001 port_ss=41002 port_ce=41003 master=true sound=true
 [cluster_node] id=node_front addr=127.0.0.1 window=wnd_front
-[cluster_node] id=node_left  addr=127.0.0.1 window=wnd_left 
+[cluster_node] id=node_left  addr=127.0.0.1 window=wnd_left
 [cluster_node] id=node_right addr=127.0.0.1 window=wnd_right
 [cluster_node] id=node_back  addr=127.0.0.1 window=wnd_back
- 
+
 #####################################################################
 # Application windows
-#******************************************************************** 
+#********************************************************************
 # The window entitty defines properties of application's game window.
 #
 # Properties:
@@ -50,7 +58,7 @@
 # resx       - Width
 # resy       - Height
 # viewports  - Array of viewports
-#******************************************************************** 
+#********************************************************************
 
 [window] id=wnd_floor viewports=vp_floor
 [window] id=wnd_front viewports=vp_front
@@ -60,7 +68,7 @@
 
 #####################################################################
 # Projection screens
-#******************************************************************** 
+#********************************************************************
 # Projection screen is a rectangle which determines the camera frustum.
 # Usually the projection screen has the same dimensions as an output
 # display but in some cases it may differ.
@@ -79,17 +87,17 @@
 # parent     - ID of parent component in VR hierarchy; default is VR root.
 # tracker_id - ID of tracking device; no tracking by default.
 # tracker_ch - ID of tracking device's channel; no tracking by default.
-#******************************************************************** 
+#********************************************************************
 
 [screen] id=screen_floor loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=5.25,Y=5.25" parent=loc_floor
 [screen] id=screen_front loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=5.25,Y=3.3"  parent=loc_front
-[screen] id=screen_left  loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=3.3,Y=5.25"  parent=loc_left 
+[screen] id=screen_left  loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=3.3,Y=5.25"  parent=loc_left
 [screen] id=screen_right loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=3.3,Y=5.25"  parent=loc_right
-[screen] id=screen_back  loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=5.25,Y=3.3"  parent=loc_back 
+[screen] id=screen_back  loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=5.25,Y=3.3"  parent=loc_back
 
 #####################################################################
 # Viewports
-#******************************************************************** 
+#********************************************************************
 # Viewport is a rectangle area of game window where rendered frame is
 # mapped. Usually the viewport starts at 0:0 and has the same size as
 # its parent window but in some cases these settings may differ.
@@ -100,17 +108,17 @@
 # y      - Y coordinate of viewport's top left corner
 # width  - width of viewport in pixels
 # height - height of viewport in pixels
-#******************************************************************** 
+#********************************************************************
 
-[viewport] id=vp_floor screen=screen_floor x=0 y=0 width=480 height=480
-[viewport] id=vp_front screen=screen_front x=0 y=0 width=480 height=300
-[viewport] id=vp_left  screen=screen_left  x=0 y=0 width=300 height=480
-[viewport] id=vp_right screen=screen_right x=0 y=0 width=300 height=480
-[viewport] id=vp_back  screen=screen_back  x=0 y=0 width=480 height=300
+[viewport] id=vp_floor x=0 y=0 width=480 height=480 projection="proj_screen_floor"
+[viewport] id=vp_front x=0 y=0 width=480 height=300 projection="proj_screen_front"
+[viewport] id=vp_left   x=0 y=0 width=300 height=480 projection="proj_screen_left"
+[viewport] id=vp_right x=0 y=0 width=300 height=480 projection="proj_screen_right"
+[viewport] id=vp_back   x=0 y=0 width=480 height=300 projection="proj_screen_back"
 
 #####################################################################
 # Cameras
-#******************************************************************** 
+#********************************************************************
 # Camera is a predefined point frome where the stereoscopic view built.
 # It's possible to define multiple cameras and swith the active one
 # during runtime. You're free to attach any camera to a tracking device
@@ -127,13 +135,13 @@
 # parent     - ID of parent component in VR hierarchy; default is VR root.
 # tracker_id - ID of tracking device; no tracking by default.
 # tracker_ch - ID of tracking device's channel; no tracking by default.
-#******************************************************************** 
+#********************************************************************
 
-[camera] id=camera_dynamic loc="X=0,Y=0,Z=0" parent=shutter_glasses
+[camera] id=camera_dynamic loc="X=0,Y=0,Z=0" parent=shutter_glasses eye_swap="false" eye_dist="64" force_offset="0"
 
 #####################################################################
-# Scene nodes (hierarchy transforms) 
-#******************************************************************** 
+# Scene nodes (hierarchy transforms)
+#********************************************************************
 # Scene node is an actor component which is basically a transformation
 # matrix. Scene nodes can be helpful to build a component hierarchy, to
 # define some special places (like a socket) within VR space.
@@ -153,7 +161,7 @@
 # parent     - ID of parent component in VR hierarchy; default is VR root.
 # tracker_id - ID of tracking device; no tracking by default.
 # tracker_ch - ID of tracking device's channel; no tracking by default.
-#******************************************************************** 
+#********************************************************************
 
 [scene_node] id=cave_origin     loc="X=0,Y=0,Z=0"    rot="P=0,Y=0,R=0"
 [scene_node] id=cave_center     loc="X=0,Y=0,Z=1.65" rot="P=0,Y=0,R=0" parent=cave_origin
@@ -174,7 +182,7 @@
 
 #####################################################################
 # Input devices
-#******************************************************************** 
+#********************************************************************
 # Input devices are VRPN devices. The nDisplay supports the following
 # types: analog, button and tracker. Many of physical input devices
 # can be connected via VRPN.
@@ -199,17 +207,17 @@
 # Optional properties:
 # remap - VRPN device channel remapping. Value format is: "from0:to0,from1:to1,...,fromN:toN".
 #         For example: remap="0:3,1:4,5:2"
-#******************************************************************** 
+#********************************************************************
 
 #####################################################################
 # Stereoscopic settings
-#******************************************************************** 
+#********************************************************************
 # Properties:
 # eye_dist - interoccular distance in meters
-[stereo] eye_dist=0.064
+[stereo]
 #####################################################################
 # General settings
-#******************************************************************** 
+#********************************************************************
 # Properties:
 # swap_sync_policy - swap synchronization policy
 #                  - 0 - no synchronization
@@ -219,7 +227,7 @@
 
 #####################################################################
 # Network settings
-#******************************************************************** 
+#********************************************************************
 # Optional properties:
 # cln_conn_tries_amount - how many times a client tries to connect to a server
 # cln_conn_retry_delay  - delay before next client connection try (milliseconds)
@@ -229,7 +237,7 @@
 
 #####################################################################
 # Custom arguments
-#******************************************************************** 
+#********************************************************************
 # Any custom arguments available in runtime can be specified here.
 # Format:  ARG_NAME=ARG_VAL
 [custom] Hardware_Platform=VirtualCAVE
diff --git a/LaunchConfig/tileddisplaywall.cfg b/LaunchConfig/tileddisplaywall.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..4999d1af8c9ce1d1b4af30093ce451cf0464610a
--- /dev/null
+++ b/LaunchConfig/tileddisplaywall.cfg
@@ -0,0 +1,283 @@
+[projection] id="proj_screen_bottom_right" type="simple" screen="screen_bottom_right"
+[projection] id="proj_screen_bottom_middle" type="simple" screen="screen_bottom_middle"
+[projection] id="proj_screen_bottom_left" type="simple" screen="screen_bottom_left"
+[projection] id="proj_screen_top_right" type="simple" screen="screen_top_right"
+[projection] id="proj_screen_top_middle" type="simple" screen="screen_top_middle"
+[projection] id="proj_screen_top_left" type="simple" screen="screen_top_left"
+# AUTO_CONVERSION, new entities finish
+
+
+#####################################################################
+# nDisplay config file for aixCAVE
+#####################################################################
+
+
+#####################################################################
+# Config info
+#********************************************************************
+# This is a config file header.
+#
+# Properties:
+# version - specifies the version of the configuration file (UE4.xx)
+#********************************************************************
+[info] version="23"
+
+
+#####################################################################
+# Cluster nodes
+#********************************************************************
+# Cluster node is an application instance. It's allowed to use
+# multiple instances on the same PC. Sometimes its necessary.
+#
+# Properties:
+# id       - Unique node name
+# window   - Window ID
+# addr     - Network address (IPv4 only)
+# master   - Specifies if current node is master; default is 'false'
+# port_cs  - Cluster Synchronization port (required on master node only)
+# port_ss  - Swap Synchronization port (required on master node only)
+# port_ce  - Cluster Events port (required on master node only)
+#
+# Optional properties:
+# eye_swap - Swap eyes for this node; default is 'false'
+# sound    - turns on/off sound for this application instance; default is 'false'
+#********************************************************************
+
+[cluster_node] id=node_tr   addr=127.0.0.1   window=wnd_top_right        mono_eye=left
+[cluster_node] id=node_tm   addr=127.0.0.1   window=wnd_top_middle       mono_eye=left
+[cluster_node] id=node_tl   addr=127.0.0.1   window=wnd_top_left         mono_eye=left  port_cs=41001 port_ss=41002 port_ce=41003 master=true sound=true
+[cluster_node] id=node_br   addr=127.0.0.1   window=wnd_bottom_right     mono_eye=left
+[cluster_node] id=node_bm   addr=127.0.0.1   window=wnd_bottom_middle    mono_eye=left
+[cluster_node] id=node_bl   addr=127.0.0.1   window=wnd_bottom_left      mono_eye=left
+
+#####################################################################
+# Application windows
+#********************************************************************
+# The window entitty defines properties of application's game window.
+#
+# Properties:
+# id         - Unique window name
+# fullscreen - Fullscreen or windowed mode
+# winx       - X location
+# winy       - Y location
+# resx       - Width
+# resy       - Height
+# viewports  - Array of viewports
+#********************************************************************
+# Here we have 7 windows. They all run in fullscreen mode on a
+# default output device with individual viewports assigned.
+
+[window] id=wnd_bottom_right          viewports=vp_bottom_right       fullscreen=true
+[window] id=wnd_bottom_middle         viewports=vp_bottom_middle      fullscreen=true
+[window] id=wnd_bottom_left           viewports=vp_bottom_left        fullscreen=true
+[window] id=wnd_top_right             viewports=vp_top_right          fullscreen=true
+[window] id=wnd_top_middle            viewports=vp_top_middle         fullscreen=true
+[window] id=wnd_top_left              viewports=vp_top_left           fullscreen=true
+
+#####################################################################
+# Projection screens
+#********************************************************************
+# Projection screen is a rectangle which determines the camera frustum.
+# Usually the projection screen has the same dimensions as an output
+# display but in some cases it may differ.
+#
+# Properties:
+# id     - unique projection screen name
+# loc    - relative location to the parent component. Location is relative
+#          to the VR root if no parent specified. The pivot is a screen's
+#          center and the values are in meters.
+# rot    - relative rotation to the parent component. Rotation is relative
+#          to the VR root if no parent specified. The pivot is a screen's
+#          center and the values are in degrees.
+# size   - width (X) and height (Y) of the screen. Values are in meters.
+#
+# Optional properties:
+# parent     - ID of parent component in VR hierarchy; default is VR root.
+# tracker_id - ID of tracking device; no tracking by default.
+# tracker_ch - ID of tracking device's channel; no tracking by default.
+#********************************************************************
+# We have 5 output displays. That means we have to have 5 projection
+# screens. Sometimes it's possible to use only one projection screen
+# (Nvidia mosaic/surround + projections with blending) but in this
+# particular case each display is managed by its own PC.
+
+[screen] id=screen_bottom_right    loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=1.022,Y=0.58"  parent=display_bottom_right
+[screen] id=screen_bottom_middle   loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=1.022,Y=0.58"  parent=display_bottom_middle
+[screen] id=screen_bottom_left     loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=1.022,Y=0.58"  parent=display_bottom_left
+[screen] id=screen_top_right       loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=1.022,Y=0.58"  parent=display_top_right
+[screen] id=screen_top_middle      loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=1.022,Y=0.58"  parent=display_top_middle
+[screen] id=screen_top_left        loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=1.022,Y=0.58"  parent=display_top_left
+
+#####################################################################
+# Viewports
+#********************************************************************
+# Viewport is a rectangle area of game window where rendered frame is
+# mapped. Usually the viewport starts at 0:0 and has the same size as
+# its parent window but in some cases these settings may differ.
+#
+# Properties:
+# id     - unique viewport name
+# x      - X coordinate of viewport's top left corner
+# y      - Y coordinate of viewport's top left corner
+# width  - width of viewport in pixels
+# height - height of viewport in pixels
+#********************************************************************
+# In this example we have different output resolutions. Let's enumerate
+# correspondent viewport settings. Each viewport has its own projection
+# screen.
+
+[viewport] id=vp_bottom_right    x=0 y=0 width=480 height=272 projection="proj_screen_bottom_right"
+[viewport] id=vp_bottom_middle  x=0 y=0 width=480 height=272 projection="proj_screen_bottom_middle"
+[viewport] id=vp_bottom_left      x=0 y=0 width=480 height=272 projection="proj_screen_bottom_left"
+
+[viewport] id=vp_top_right          x=0 y=0 width=480 height=272 projection="proj_screen_top_right"
+[viewport] id=vp_top_middle        x=0 y=0 width=480 height=272 projection="proj_screen_top_middle"
+[viewport] id=vp_top_left            x=0 y=0 width=480 height=272 projection="proj_screen_top_left"
+
+#####################################################################
+# Cameras
+#********************************************************************
+# Camera is a predefined point frome where the stereoscopic view built.
+# It's possible to define multiple cameras and swith the active one
+# during runtime. You're free to attach any camera to a tracking device
+# for head tracking. Consider a camera as a viewer's head.
+#
+# Properties:
+# id  - unique camera name
+# loc - relative location to the parent component. Location is relative
+#       to the VR root if no parent specified.
+# rot - relative rotation to the parent component. Rotation is relative
+#       to the VR root if no parent specified.
+#
+# Optional properties:
+# parent     - ID of parent component in VR hierarchy; default is VR root.
+# tracker_id - ID of tracking device; no tracking by default.
+# tracker_ch - ID of tracking device's channel; no tracking by default.
+#********************************************************************
+# In this example we have only one static camera (no tracking).
+[camera] id=camera_dynamic loc="X=0,Y=0,Z=0" parent=shutter_glasses eye_swap="false" eye_dist="64" force_offset="0"
+
+
+#####################################################################
+# Scene nodes (hierarchy transforms)
+#********************************************************************
+# Scene node is an actor component which is basically a transformation
+# matrix. Scene nodes can be helpful to build a component hierarchy, to
+# define some special places (like a socket) within VR space.
+#
+# It might be difficult to understand what VR space origin is. Consider
+# it as a point in space where VR space starts. Any componenent listed
+# in this config file is relative to its parent or this origin.
+#
+# Properties:
+# id  - unique scene node name
+# loc - relative location to the parent component. Location is relative
+#       to the VR root if no parent specified.
+# rot - relative rotation to the parent component. Rotation is relative
+#       to the VR root if no parent specified.
+#
+# Optional properties:
+# parent     - ID of parent component in VR hierarchy; default is VR root.
+# tracker_id - ID of tracking device; no tracking by default.
+# tracker_ch - ID of tracking device's channel; no tracking by default.
+#********************************************************************
+# Here we build our VR hierarchy. We do it in such a way that the center
+# of floor screen is in the VR space origin.
+[scene_node] id=tdw_origin_floor               loc="X=0,Y=0,Z=0"          rot="P=0,Y=0,R=0"
+[scene_node] id=tdw_center                     loc="X=1.95,Y=0,Z=1.72"    rot="P=0,Y=0,R=0"   parent=tdw_origin_floor
+
+[scene_node] id=display_bottom_right           loc="X=0,Y=1.05,Z=-0.302"  rot="P=0,Y=0,R=0"   parent=tdw_center
+[scene_node] id=display_bottom_middle          loc="X=0,Y=0.00,Z=-0.302"  rot="P=0,Y=0,R=0"   parent=tdw_center
+[scene_node] id=display_bottom_left            loc="X=0,Y=-1.05,Z=-0.302" rot="P=0,Y=0,R=0"   parent=tdw_center
+[scene_node] id=display_top_right              loc="X=0,Y=1.05,Z=0.302"   rot="P=0,Y=0,R=0"   parent=tdw_center
+[scene_node] id=display_top_middle             loc="X=0,Y=0.00,Z=0.302"   rot="P=0,Y=0,R=0"   parent=tdw_center
+[scene_node] id=display_top_left               loc="X=0,Y=-1.05,Z=0.302"  rot="P=0,Y=0,R=0"   parent=tdw_center
+
+[scene_node] id=flystick                       loc="X=0,Y=0,Z=0"          rot="P=0,Y=0,R=0"   parent=tdw_origin_floor      tracker_id=dtrack_tracker tracker_ch=1
+[scene_node] id=shutter_glasses                loc="X=0,Y=0,Z=1.80"       rot="P=0,Y=0,R=0"   parent=tdw_origin_floor      tracker_id=dtrack_tracker tracker_ch=0
+
+
+#####################################################################
+# Input devices
+#********************************************************************
+# Input devices are VRPN devices. The nDisplay supports the following
+# types: analog, button and tracker. Many of physical input devices
+# can be connected via VRPN.
+#
+# Properties:
+# id    - nique device name
+# type  - VRPN type (analog, button or tracker).
+# addr  - address of a VRPN server which handles this particular device.
+#         The value must match the following format: DEVICENAME@SERVER_ADDRESS
+#         where DEVICENAME is a VRPN name of this device and SERVER_ADDRESS
+#         is IPv4 address of VRPN server.
+# loc   - relative location to the parent component. Location is relative
+#         to the VR root if no parent specified.
+# rot   - relative rotation to the parent component. Rotation is relative
+#         to the VR root if no parent specified.
+#
+# front (tracker only) - mapping of a tracking system axis to X axis of VR origin
+# right (tracker only) - mapping of a tracking system axis to Y axis of VR origin
+# up    (tracker only) - mapping of a tracking system axis to Z axis of VR origin
+# * The following values are allowed for axes mapping: X, -X, Y, -Y, Z, -Z
+#
+# Optional properties:
+# remap - VRPN device channel remapping. Value format is: "from0:to0,from1:to1,...,fromN:toN".
+#         For example: remap="0:3,1:4,5:2"
+#********************************************************************
+#[input] id=dtrack_axis    type=analog  addr=DTrack2@134.61.201.230
+#[input] id=dtrack_buttons type=buttons addr=DTrack2@134.61.201.230
+#[input] id=dtrack_tracker type=tracker addr=DTrack2@134.61.201.230 loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" right=X up=Y front=-Z
+
+#Flystick
+#   Trigger button
+[input_setup] id=dtrack_buttons ch=0 bind="nDisplay Button 0"
+#   Blue Flystick buttons, from left to right nDisplay Button 1 to 4
+[input_setup] id=dtrack_buttons ch=1 bind="nDisplay Button 4"
+[input_setup] id=dtrack_buttons ch=2 bind="nDisplay Button 3"
+[input_setup] id=dtrack_buttons ch=3 bind="nDisplay Button 2"
+[input_setup] id=dtrack_buttons ch=4 bind="nDisplay Button 1"
+#   Coolie Head Button
+[input_setup] id=dtrack_buttons ch=5 bind="nDisplay Button 5"
+
+# Axes
+#   Coolie head x axis, left/right
+[input_setup] id=dtrack_axis ch=0 bind="nDisplay Analog 0"
+#   Coolie head y axis, up/down
+[input_setup] id=dtrack_axis ch=1 bind="nDisplay Analog 1"
+
+#####################################################################
+# Stereoscopic settings
+#********************************************************************
+# Properties:
+# eye_dist - interoccular distance in meters
+[stereo]
+
+#####################################################################
+# General settings
+#********************************************************************
+# Properties:
+# swap_sync_policy - swap synchronization policy
+#                  - 0 - no synchronization
+#                  - 1 - software swap synchronization
+#                  - 2 - NV swap lock (Nvidia cards only, OpenGL only)
+[general] swap_sync_policy=1
+
+
+#####################################################################
+# Network settings
+#********************************************************************
+# Optional properties:
+# cln_conn_tries_amount - how many times a client tries to connect to a server
+# cln_conn_retry_delay  - delay before next client connection try (milliseconds)
+# game_start_timeout    - timeout before all data is loaded and game started (milliseconds)
+# barrier_wait_timeout  - barrier timeout for both game and render threads (milliseconds)
+[network] cln_conn_tries_amount=300 cln_conn_retry_delay=1000 game_start_timeout=600000 barrier_wait_timeout=600000
+
+
+#####################################################################
+# Custom arguments
+#********************************************************************
+# Any custom arguments available in runtime can be specified here.
+# Format:  ARG_NAME=ARG_VAL
+[custom] Hardware_Platform=TiledDisplayVideo
diff --git a/LaunchConfig/twoscreen.cfg b/LaunchConfig/twoscreen.cfg
index 47d81cc5e51e11f008524f9c08c43fa8b7d1175a..7b9a20280d3fc5fa19509cb25ec05eee21c7361f 100644
--- a/LaunchConfig/twoscreen.cfg
+++ b/LaunchConfig/twoscreen.cfg
@@ -1,20 +1,25 @@
+[projection] id="proj_screen_left" type="simple" screen="screen_left"
+[projection] id="proj_screen_right" type="simple" screen="screen_right"
+# AUTO_CONVERSION, new entities finish
+
+
 #####################################################################
 # nDisplay config file for aixCAVE
 #####################################################################
 
 #####################################################################
 # Config info
-#******************************************************************** 
+#********************************************************************
 # This is a config file header.
 #
 # Properties:
 # version - specifies the version of the configuration file (UE4.xx)
-#******************************************************************** 
-[info] version=22
+#********************************************************************
+[info] version="23"
 
 #####################################################################
 # Cluster nodes
-#******************************************************************** 
+#********************************************************************
 # Cluster node is an application instance. It's allowed to use
 # multiple instances on the same PC. Sometimes its necessary.
 #
@@ -30,13 +35,13 @@
 # Optional properties:
 # eye_swap - Swap eyes for this node; default is 'false'
 # sound    - turns on/off sound for this application instance; default is 'false'
-#********************************************************************      
+#********************************************************************
 [cluster_node] id=node_left  addr=127.0.0.1 window=wnd_left port_cs=41001 port_ss=41002 port_ce=41003 master=true sound=true
 [cluster_node] id=node_right addr=127.0.0.1 window=wnd_right
- 
+
 #####################################################################
 # Application windows
-#******************************************************************** 
+#********************************************************************
 # The window entitty defines properties of application's game window.
 #
 # Properties:
@@ -47,14 +52,14 @@
 # resx       - Width
 # resy       - Height
 # viewports  - Array of viewports
-#******************************************************************** 
+#********************************************************************
 
 [window] id=wnd_left  viewports=vp_left
 [window] id=wnd_right viewports=vp_right
 
 #####################################################################
 # Projection screens
-#******************************************************************** 
+#********************************************************************
 # Projection screen is a rectangle which determines the camera frustum.
 # Usually the projection screen has the same dimensions as an output
 # display but in some cases it may differ.
@@ -73,14 +78,14 @@
 # parent     - ID of parent component in VR hierarchy; default is VR root.
 # tracker_id - ID of tracking device; no tracking by default.
 # tracker_ch - ID of tracking device's channel; no tracking by default.
-#******************************************************************** 
+#********************************************************************
 
-[screen] id=screen_left  loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=2.0,Y=2.0"  parent=loc_left 
+[screen] id=screen_left  loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=2.0,Y=2.0"  parent=loc_left
 [screen] id=screen_right loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=2.0,Y=2.0"  parent=loc_right
 
 #####################################################################
 # Viewports
-#******************************************************************** 
+#********************************************************************
 # Viewport is a rectangle area of game window where rendered frame is
 # mapped. Usually the viewport starts at 0:0 and has the same size as
 # its parent window but in some cases these settings may differ.
@@ -91,14 +96,14 @@
 # y      - Y coordinate of viewport's top left corner
 # width  - width of viewport in pixels
 # height - height of viewport in pixels
-#******************************************************************** 
+#********************************************************************
 
-[viewport] id=vp_left  screen=screen_left  x=0 y=0 width=480 height=480
-[viewport] id=vp_right screen=screen_right x=0 y=0 width=480 height=480
+[viewport] id=vp_left   x=0 y=0 width=480 height=480 projection="proj_screen_left"
+[viewport] id=vp_right x=0 y=0 width=480 height=480 projection="proj_screen_right"
 
 #####################################################################
 # Cameras
-#******************************************************************** 
+#********************************************************************
 # Camera is a predefined point frome where the stereoscopic view built.
 # It's possible to define multiple cameras and swith the active one
 # during runtime. You're free to attach any camera to a tracking device
@@ -115,13 +120,13 @@
 # parent     - ID of parent component in VR hierarchy; default is VR root.
 # tracker_id - ID of tracking device; no tracking by default.
 # tracker_ch - ID of tracking device's channel; no tracking by default.
-#******************************************************************** 
+#********************************************************************
 
-[camera] id=camera_dynamic loc="X=0,Y=0,Z=0" parent=shutter_glasses
+[camera] id=camera_dynamic loc="X=0,Y=0,Z=0" parent=shutter_glasses eye_swap="false" eye_dist="64" force_offset="0"
 
 #####################################################################
-# Scene nodes (hierarchy transforms) 
-#******************************************************************** 
+# Scene nodes (hierarchy transforms)
+#********************************************************************
 # Scene node is an actor component which is basically a transformation
 # matrix. Scene nodes can be helpful to build a component hierarchy, to
 # define some special places (like a socket) within VR space.
@@ -141,7 +146,7 @@
 # parent     - ID of parent component in VR hierarchy; default is VR root.
 # tracker_id - ID of tracking device; no tracking by default.
 # tracker_ch - ID of tracking device's channel; no tracking by default.
-#******************************************************************** 
+#********************************************************************
 
 [scene_node] id=cave_origin     loc="X=0,Y=0,Z=0"    rot="P=0,Y=0,R=0"
 [scene_node] id=cave_center     loc="X=0,Y=0,Z=1.65" rot="P=0,Y=0,R=0" parent=cave_origin
@@ -154,7 +159,7 @@
 
 #####################################################################
 # Input devices
-#******************************************************************** 
+#********************************************************************
 # Input devices are VRPN devices. The nDisplay supports the following
 # types: analog, button and tracker. Many of physical input devices
 # can be connected via VRPN.
@@ -179,17 +184,17 @@
 # Optional properties:
 # remap - VRPN device channel remapping. Value format is: "from0:to0,from1:to1,...,fromN:toN".
 #         For example: remap="0:3,1:4,5:2"
-#******************************************************************** 
+#********************************************************************
 
 #####################################################################
 # Stereoscopic settings
-#******************************************************************** 
+#********************************************************************
 # Properties:
 # eye_dist - interoccular distance in meters
-[stereo] eye_dist=0.064
+[stereo]
 #####################################################################
 # General settings
-#******************************************************************** 
+#********************************************************************
 # Properties:
 # swap_sync_policy - swap synchronization policy
 #                  - 0 - no synchronization
@@ -199,7 +204,7 @@
 
 #####################################################################
 # Network settings
-#******************************************************************** 
+#********************************************************************
 # Optional properties:
 # cln_conn_tries_amount - how many times a client tries to connect to a server
 # cln_conn_retry_delay  - delay before next client connection try (milliseconds)
@@ -209,7 +214,7 @@
 
 #####################################################################
 # Custom arguments
-#******************************************************************** 
+#********************************************************************
 # Any custom arguments available in runtime can be specified here.
 # Format:  ARG_NAME=ARG_VAL
 [custom] Hardware_Platform=TwoScreen
diff --git a/Source/NDisplayLaunchButton/NDisplayLaunchButton.Build.cs b/Source/NDisplayLaunchButton/NDisplayLaunchButton.Build.cs
index 240688253b04d3dde73290e42b8389105f124447..5e904268c4f1c3cdc1f9ce61b5d67981ddc27d51 100644
--- a/Source/NDisplayLaunchButton/NDisplayLaunchButton.Build.cs
+++ b/Source/NDisplayLaunchButton/NDisplayLaunchButton.Build.cs
@@ -26,6 +26,7 @@ public class NDisplayLaunchButton : ModuleRules
 			new string[]
 			{
 				"Core",
+				"DeveloperSettings"
 				// ... add other public dependencies that you statically link with here ...
 			}
 			);
diff --git a/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp b/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp
index 5d552abe4380c30bce9b717b4659481ecdb6e30e..aecc2ef83c528777eeaf0938ccc7948ebf262e99 100644
--- a/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp
+++ b/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp
@@ -1,195 +1,337 @@
-// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
-#include "NDisplayLaunchButton.h"
-
-#include "NDisplayLaunchButtonStyle.h"
-#include "NDisplayLaunchButtonSettings.h"
-#include "NDisplayLaunchButtonCommands.h"
-#include "Misc/MessageDialog.h"
-#include "Framework/MultiBox/MultiBoxBuilder.h"
-#include "Interfaces/IPluginManager.h"
-#include "Misc/EngineVersion.h"
-#include "Networking.h"
-#include "SocketHelper.h"
-#include "LevelEditor.h"
-#include "FileHelpers.h"
-
-DEFINE_LOG_CATEGORY(LogNDisplayLaunchButton);
-
-void FNDisplayLaunchButtonModule::StartupModule()
-{
-	const UNDisplayLaunchButtonSettings* Settings = GetDefault<UNDisplayLaunchButtonSettings>();
-	FNDisplayLaunchButtonStyle::Initialize();
-	FNDisplayLaunchButtonStyle::ReloadTextures();
-	FNDisplayLaunchButtonCommands::Register();
-
-	TSharedPtr<class FUICommandList> PluginCommands = MakeShareable(new FUICommandList);
-	PluginCommands->MapAction(
-		FNDisplayLaunchButtonCommands::Get().PluginAction,
-		FExecuteAction::CreateRaw(this, &FNDisplayLaunchButtonModule::PluginButtonClicked),
-		FCanExecuteAction());
-
-	FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
-	TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
-	ToolbarExtender->AddToolBarExtension("Game", EExtensionHook::First, PluginCommands, FToolBarExtensionDelegate::CreateLambda([](FToolBarBuilder& Builder)
-	{
-		Builder.AddToolBarButton(FNDisplayLaunchButtonCommands::Get().PluginAction);
-	}));
-	LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);	
-}
-
-void FNDisplayLaunchButtonModule::ShutdownModule()
-{
-	FNDisplayLaunchButtonStyle::Shutdown();
-	FNDisplayLaunchButtonCommands::Unregister();
-}
-
-void FNDisplayLaunchButtonModule::PluginButtonClicked()
-{
-	const UNDisplayLaunchButtonSettings* Settings = GetDefault<UNDisplayLaunchButtonSettings>();
-	if (Settings->LaunchType == ButtonLaunchType_NONE)
-	{
-		GEngine->AddOnScreenDebugMessage(-1, 3, FColor::White, TEXT("The Button is set to do nothing."));
-		return;
-	}
-
-	if(FModuleManager::Get().IsModuleLoaded("SteamVR") || FModuleManager::Get().IsModuleLoaded("OculusHMD"))
-	{
-		FText Title = FText::FromString("VR Plugin enabled.");
-		FMessageDialog::Open(EAppMsgType::Ok, FText::FromString("You have either SteamVR or OculusVR enabled in your project. This prevents NDisplay from working. You can switch them off in the 'Plugin' menu."), &Title);
-		return;
-	}
-
-	if (!UEditorLoadingAndSavingUtils::SaveDirtyPackagesWithDialog(true, true)) return;
-	
-	// minimize the root window to provide max performance for the preview.
-	TSharedPtr<SWindow> RootWindow = FGlobalTabmanager::Get()->GetRootWindow();
-	if (RootWindow.IsValid()) RootWindow->Minimize();
-	
-	if (Settings->LaunchType == ButtonLaunchType_ROLV)
-	{
-		FString EditorExecutable = "UE4Editor.exe";
-		FString Parameters = "\"" + FPaths::GetProjectFilePath() + "\" -game dc_cfg=\"" + Settings->RolvConfig.FilePath + "\"" + ((Settings->ROLVLogToProjectDir) ? (" -log ABSLOG=" + FPaths::ProjectDir() + "\\ROLV_Launch.log") : "");
-
-		FProcHandle VRPN;
-		ProjectorDisplayType ModeFromBefore = DisplayType_Error;
-		if (Settings->StartVRPN) VRPN = FPlatformProcess::CreateProc(*Settings->VRPNPath.FilePath, *FString("-f \"" + Settings->VRPNConfigPath.FilePath + "\" -millisleep 0"), false, false, false, nullptr, 0, nullptr, nullptr);
-		if (Settings->StartDTrack) SendToDTrack(Settings->DTrackIP, Settings->DTrackPort, "dtrack2 tracking start\0");
-		if (Settings->SwitchProjector) ModeFromBefore = SwitchProjectorToState(Settings->ProjectorIP, Settings->ProjectorPort, Settings->ProjectorType);
-
-		FProcHandle Instance = FPlatformProcess::CreateProc(*EditorExecutable, *(Parameters + " " + Settings->ROLVLaunchParameters), true, false, false, nullptr, 0, nullptr, nullptr);
-		FPlatformProcess::WaitForProc(Instance);
-
-		if (Settings->StartVRPN) FPlatformProcess::TerminateProc(VRPN);
-		FPlatformProcess::CloseProc(VRPN);
-		if (Settings->StartDTrack) SendToDTrack(Settings->DTrackIP, Settings->DTrackPort, "dtrack2 tracking stop\0");
-		if (Settings->SwitchProjector && ModeFromBefore != DisplayType_Error) SwitchProjectorToState(Settings->ProjectorIP, Settings->ProjectorPort, ModeFromBefore);
-	}
-
-	if (Settings->LaunchType == ButtonLaunchType_MiniCAVE)
-	{
-		FString Config = IPluginManager::Get().FindPlugin("NDisplayLaunchButton")->GetBaseDir() + "/LaunchConfig/minicave.cfg";
-		FString EditorExecutable = "UE4Editor.exe";
-		FString Parameters = "\"" + FPaths::GetProjectFilePath() + "\" -game dc_cfg=\"" + Config + "\" " + Settings->MiniCAVELaunchParameters;
-
-		const int Num_Nodes = 5;
-		FString Windows_Node_Specific_Commands[Num_Nodes] = {
-			"dc_node=node_floor WinX=720  WinY=300 ResX=480 ResY=480" + FString((Settings->MiniCAVELogMasterWindow) ? " -log" : "") + ((Settings->MiniCAVELogToProjectDirFloor) ? (" ABSLOG=" + FPaths::ProjectDir() + "\\MiniCave_Floor_Master.log") : "") + " " + Settings->MiniCAVEAdditionalLaunchParametersMaster,
-			"dc_node=node_front WinX=720  WinY=0   ResX=480 ResY=300" + ((Settings->MiniCAVELogToProjectDirFront) ? (" ABSLOG=" + FPaths::ProjectDir() + "\\MiniCave_Front.log") : ""),
-			"dc_node=node_left  WinX=420  WinY=300 ResX=300 ResY=480" + ((Settings->MiniCAVELogToProjectDirLeft) ? (" ABSLOG=" + FPaths::ProjectDir() + "\\MiniCave_Left.log") : ""),
-			"dc_node=node_right WinX=1200 WinY=300 ResX=300 ResY=480" + ((Settings->MiniCAVELogToProjectDirRight) ? (" ABSLOG=" + FPaths::ProjectDir() + "\\MiniCave_Right.log") : ""),
-			"dc_node=node_back  WinX=720  WinY=780 ResX=480 ResY=300" + ((Settings->MiniCAVELogToProjectDirBack) ? (" ABSLOG=" + FPaths::ProjectDir() + "\\MiniCave_Back.log") : "")
-		};
-
-		FProcHandle Processes[Num_Nodes];
-		for (int i = 0; i < Num_Nodes; i++)
-		{
-			Processes[i] = FPlatformProcess::CreateProc(*EditorExecutable, *(Parameters + " " + Windows_Node_Specific_Commands[i]), true, false, false, nullptr, 0, nullptr, nullptr);
-		}
-		FPlatformProcess::WaitForProc(Processes[0]); //wait for only one of them
-	}
-
-	if (Settings->LaunchType == ButtonLaunchType_TWO_SCREEN)
-	{
-		FString Config = IPluginManager::Get().FindPlugin("NDisplayLaunchButton")->GetBaseDir() + "/LaunchConfig/twoscreen.cfg";
-		FString EditorExecutable = "UE4Editor.exe";
-		FString Parameters = "\"" + FPaths::GetProjectFilePath() + "\" -game dc_cfg=\"" + Config + "\" " + Settings->TwoScreenLaunchParameters;
-
-		const int Num_Nodes = 2;
-		FString Windows_Node_Specific_Commands[Num_Nodes] = {
-			"dc_node=node_left  WinX=200 WinY=200 ResX=480 ResY=480" + FString((Settings->TwoScreenLogMasterWindow) ? " -log" : "") + ((Settings->TwoScreenLogToProjectDirLeft) ? (" ABSLOG=" + FPaths::ProjectDir() + "\\TwoScreen_Left_Master.log") : "") + " " + Settings->TwoScreenAdditionalLaunchParametersMaster,
-			"dc_node=node_right WinX=682 WinY=200 ResX=480 ResY=480" + ((Settings->TwoScreenLogToProjectDirRight) ? (" ABSLOG = " + FPaths::ProjectDir() + "\\TwoScreen_Right.log") : "")
-		};
-
-		FProcHandle Processes[Num_Nodes];
-		for (int i = 0; i < Num_Nodes; i++)
-		{
-			Processes[i] = FPlatformProcess::CreateProc(*EditorExecutable, *(Parameters + " " + Windows_Node_Specific_Commands[i]), true, false, false, nullptr, 0, nullptr, nullptr);
-		}
-		FPlatformProcess::WaitForProc(Processes[0]); //wait for only one of them
-	}
-
-	if (Settings->LaunchType == ButtonLaunchType_CAVE)
-	{
-		FProcHandle Instance = FPlatformProcess::CreateProc(
-			*Settings->CAVELaunchScriptPath.FilePath,
-			*("\"" + (FPaths::ConvertRelativePathToFull(".") + "/UE4Editor\"")
-				+ " " + FPaths::ConvertRelativePathToFull(FPaths::GetProjectFilePath())
-				+ " " + FString::FromInt(FEngineVersion::Current().GetMajor())
-				+ FString::FromInt(FEngineVersion::Current().GetMinor())),
-			true, false, false, nullptr, 0, nullptr, nullptr);
-		FPlatformProcess::WaitForProc(Instance);
-	}
-
-	if (RootWindow.IsValid()) RootWindow->Maximize();
-}
-
-void FNDisplayLaunchButtonModule::SendToDTrack(FString Address, int Port, FString Message)
-{
-	FSocket* Socket = USocketHelper::OpenSocket(Address, Port, "DTrackSocket");
-	if (!Socket) return;
-	if (USocketHelper::SendSocket(Socket, Message) <= 0) return;
-	FString Response = USocketHelper::ReceiveSocket<100>(Socket);
-	if (Response.Compare("dtrack2 ok") != 0)
-	{
-		UE_LOG(LogTemp, Error, TEXT("DTrack Command Failed. Response: '%s'"), *Response);
-	}
-	Socket->Shutdown(ESocketShutdownMode::ReadWrite);
-	Socket->Close();
-}
-
-//Returns old state
-ProjectorDisplayType FNDisplayLaunchButtonModule::SwitchProjectorToState(FString Address, int Port, ProjectorDisplayType State)
-{
-	ProjectorDisplayType ModeBefore = ProjectorDisplayType::DisplayType_Error;
-	FSocket* Socket = USocketHelper::OpenSocket(Address, Port, "ProjectorSocket");
-	if (!Socket) return ModeBefore;
-
-	//Get mode from before
-	if (USocketHelper::SendSocket(Socket, ":TDSM ?\r") <= 0) return ModeBefore;
-	FString Response = USocketHelper::ReceiveSocket<100>(Socket); //Response looks like: %001 TDSM 000000
-
-	if (!Response.IsEmpty())
-	{
-		int32 Position = 0;
-		Response.FindLastChar(' ', Position);
-		ModeBefore = static_cast<ProjectorDisplayType>(FCString::Atoi(*Response.RightChop(Position)));
-	}
-
-	if (Response.IsEmpty() || USocketHelper::SendSocket(Socket, ":TDSM " + FString::FromInt(State) + "\r") <= 0)
-	{
-		Socket->Shutdown(ESocketShutdownMode::ReadWrite);
-		Socket->Close();
-		return ModeBefore;
-	}
-	Response = USocketHelper::ReceiveSocket<100>(Socket);
-	if (Response.EndsWith(")"))
-	{
-		//Errors are marked like this
-		UE_LOG(LogTemp, Error, TEXT("Projector Type Change Failed. Response: '%s'"), *Response);
-	}
-	Socket->Shutdown(ESocketShutdownMode::ReadWrite);
-	Socket->Close();
-	return ModeBefore;
-}
-
-IMPLEMENT_MODULE(FNDisplayLaunchButtonModule, NDisplayLaunchButton)
+// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
+#include "NDisplayLaunchButton.h"
+
+#include "NDisplayLaunchButtonStyle.h"
+#include "NDisplayLaunchButtonSettings.h"
+#include "NDisplayLaunchButtonCommands.h"
+#include "Misc/MessageDialog.h"
+#include "Framework/MultiBox/MultiBoxBuilder.h"
+#include "Interfaces/IPluginManager.h"
+#include "Misc/EngineVersion.h"
+#include "Networking.h"
+#include "SocketHelper.h"
+#include "LevelEditor.h"
+#include "FileHelpers.h"
+#include "GameProjectGeneration/Public/GameProjectGenerationModule.h"
+#include "Interfaces/IProjectManager.h"
+
+DEFINE_LOG_CATEGORY(LogNDisplayLaunchButton);
+
+void FNDisplayLaunchButtonModule::StartupModule()
+{
+	const UNDisplayLaunchButtonSettings* Settings = GetDefault<UNDisplayLaunchButtonSettings>();
+	FNDisplayLaunchButtonStyle::Initialize();
+	FNDisplayLaunchButtonStyle::ReloadTextures();
+	FNDisplayLaunchButtonCommands::Register();
+
+	TSharedPtr<class FUICommandList> PluginCommands = MakeShareable(new FUICommandList);
+	PluginCommands->MapAction(
+		FNDisplayLaunchButtonCommands::Get().PluginAction,
+		FExecuteAction::CreateRaw(this, &FNDisplayLaunchButtonModule::PluginButtonClicked),
+		FCanExecuteAction());
+
+	FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
+	TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
+	ToolbarExtender->AddToolBarExtension("Game", EExtensionHook::First, PluginCommands, FToolBarExtensionDelegate::CreateLambda([](FToolBarBuilder& Builder)
+	{
+		Builder.AddToolBarButton(FNDisplayLaunchButtonCommands::Get().PluginAction);
+	}));
+	LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);	
+}
+
+void FNDisplayLaunchButtonModule::ShutdownModule()
+{
+	FNDisplayLaunchButtonStyle::Shutdown();
+	FNDisplayLaunchButtonCommands::Unregister();
+}
+
+/**
+ * Since some plugins interfere with nDisplay execution, this function can disable them
+ * @param PluginName - Name of the plugin to enable/disable
+ * @param NewState - The state to switch the plugin to
+ * @param OldState - Here the old state is stored AFTER the change
+ * @return true on Success
+ */
+bool FNDisplayLaunchButtonModule::ChangePluginStateAndStoreConfig(const FString PluginName, const bool NewState, bool& OldState) const
+{
+	const bool PreviousState = IPluginManager::Get().FindPlugin(PluginName)->IsEnabled();
+	
+	FText FailMessage;
+	FGameProjectGenerationModule::Get().TryMakeProjectFileWriteable(FPaths::GetProjectFilePath());
+	if (!IProjectManager::Get().SetPluginEnabled(PluginName, NewState, FailMessage))
+	{
+		FMessageDialog::Open(EAppMsgType::Ok, FailMessage);
+		return false;
+	}else
+	{
+		if (!IProjectManager::Get().SaveCurrentProjectToDisk(FailMessage))
+		{
+			FMessageDialog::Open(EAppMsgType::Ok, FailMessage);
+			return false;
+		}
+	}
+
+	OldState = PreviousState;
+	return true;
+}
+
+/**
+ * Get filename of the editor executable
+ */
+FString FNDisplayLaunchButtonModule::GetEditorExecutableName()
+{
+#if PLATFORM_WINDOWS
+	return "UE4Editor.exe";
+#elif PLATFORM_LINUX
+	return "UE4Editor";
+#endif
+}
+
+/**
+ * Get filename in the root dir of the project
+ */
+FString FNDisplayLaunchButtonModule::GetFilePathInProject(FString FileName)
+{
+	return FPaths::Combine(FPaths::ProjectDir(), FileName);
+}
+
+/**
+ * Get the path to one of the bundled configs
+ * @param ConfigName - Name of the config without extension
+ * @return Path as FString
+ */
+FString FNDisplayLaunchButtonModule::GetConfigPath(FString ConfigName)
+{
+	return FPaths::Combine(IPluginManager::Get().FindPlugin("NDisplayLaunchButton")->GetBaseDir(), TEXT("LaunchConfig"), ConfigName + ".cfg");
+}
+
+/**
+ * Kill an Array of Process-handles after waiting for them for a few seconds
+ * @param Processes - Array of Processes to kill
+ * @param Num_Nodes - Number of Processes in the Array
+ */
+void FNDisplayLaunchButtonModule::KillProcesses(FProcHandle Processes[], const int Num_Nodes)
+{
+	float SecondsToWait = 5;
+	const float CheckInterval = 0.25;
+	FPlatformProcess::ConditionalSleep([Num_Nodes, Processes, CheckInterval, &SecondsToWait]()
+	{
+		SecondsToWait -= CheckInterval;
+		if(SecondsToWait <= 0) return true;
+		for (int i = 0; i < Num_Nodes; i++){
+			if(FPlatformProcess::IsProcRunning(Processes[i])) return false;
+		}
+		return true;
+	}, CheckInterval);
+	for (int i = 0; i < Num_Nodes; i++)	FPlatformProcess::TerminateProc(Processes[i]);
+}
+
+/**
+ * Executed on click of the button in the toolbar
+ */
+void FNDisplayLaunchButtonModule::PluginButtonClicked()
+{
+	const UNDisplayLaunchButtonSettings* Settings = GetDefault<UNDisplayLaunchButtonSettings>();
+	/* Check if we need to do something */
+	if (Settings->LaunchType == ButtonLaunchType_NONE)
+	{
+		GEngine->AddOnScreenDebugMessage(-1, 3, FColor::White, TEXT("The Button is set to do nothing."));
+		return;
+	}
+	
+	FString InsightParameters = "";
+	if(Settings->bEnableInsights)
+	{
+		if (Settings->bStatNamedEvents)	InsightParameters.Append("-statnamedevents");
+		
+		TArray<FString> TraceChannels;
+		if (Settings->bLog) TraceChannels.Add("log");
+		if (Settings->bBookmark) TraceChannels.Add("bookmark");
+		if (Settings->bFrame) TraceChannels.Add("frame");
+		if (Settings->bCPU) TraceChannels.Add("cpu");
+		if (Settings->bGPU) TraceChannels.Add("gpu");
+		if (Settings->bLoadTime) TraceChannels.Add("loadtime");
+		if (Settings->bFile) TraceChannels.Add("file");
+		if (Settings->bNet) TraceChannels.Add("net");
+		if (TraceChannels.Num() > 0) InsightParameters.Append(FString::Printf(TEXT(" -trace=%s"), *FString::Join(TraceChannels, TEXT(","))));
+		
+		if (Settings->TracehostIP.Len() > 0) InsightParameters.Append(FString::Printf(TEXT(" -tracehost=%s"), *Settings->TracehostIP));
+	}
+	
+	/* Disable Plugins temporarily */
+	if(!ChangePluginStateAndStoreConfig("SteamVR", false, SteamVRState)) return;
+	if(!ChangePluginStateAndStoreConfig("OculusVR", false, OculusVRState)) return;
+
+	/* Trigger Editor save. Needed, else old version will be launched every time */
+	if (!UEditorLoadingAndSavingUtils::SaveDirtyPackagesWithDialog(true, true)) return;
+	
+	/* minimize the root window to provide max performance for the previews. */
+	TSharedPtr<SWindow> RootWindow = FGlobalTabmanager::Get()->GetRootWindow();
+	if (RootWindow.IsValid()) RootWindow->Minimize();
+
+	/* Different Launch Types */
+	if (Settings->LaunchType == ButtonLaunchType_ROLV)
+	{
+		FString Parameters = FString::Printf(TEXT("\"%s\" -game dc_cfg=\"%s\" %s"),*FPaths::GetProjectFilePath(), *Settings->RolvConfig.FilePath, *((Settings->ROLVLogToProjectDir) ? ("-log ABSLOG=" + GetFilePathInProject("ROLV_Launch.log")) : ""));
+
+		FProcHandle VRPN;
+		ProjectorDisplayType ModeFromBefore = DisplayType_Error;
+		if (Settings->StartVRPN) VRPN = FPlatformProcess::CreateProc(*Settings->VRPNPath.FilePath, *FString::Printf(TEXT("-f \"%s\" -millisleep 0"), *Settings->VRPNConfigPath.FilePath), false, false, false, nullptr, 0, nullptr, nullptr);
+		if (Settings->StartDTrack) SendToDTrack(Settings->DTrackIP, Settings->DTrackPort, "dtrack2 tracking start\0");
+		if (Settings->SwitchProjector) ModeFromBefore = SwitchProjectorToState(Settings->ProjectorIP, Settings->ProjectorPort, Settings->ProjectorType);
+
+		FProcHandle Instance = FPlatformProcess::CreateProc(*GetEditorExecutableName(), *(Parameters + " " + InsightParameters + " "  + Settings->ROLVLaunchParameters), true, false, false, nullptr, 0, nullptr, nullptr);
+		FPlatformProcess::WaitForProc(Instance);
+
+		if (Settings->StartVRPN) FPlatformProcess::TerminateProc(VRPN);
+		FPlatformProcess::CloseProc(VRPN);
+		if (Settings->StartDTrack) SendToDTrack(Settings->DTrackIP, Settings->DTrackPort, "dtrack2 tracking stop\0");
+		if (Settings->SwitchProjector && ModeFromBefore != DisplayType_Error) SwitchProjectorToState(Settings->ProjectorIP, Settings->ProjectorPort, ModeFromBefore);
+	}
+	else if (Settings->LaunchType == ButtonLaunchType_MiniCAVE)
+	{
+		const FString Parameters = FString::Printf(TEXT("\"%s\" -game dc_cfg=\"%s\" %s"),*FPaths::GetProjectFilePath(), *GetConfigPath("minicave"), *Settings->MiniCAVELaunchParameters);
+
+		const int Num_Nodes = 5;
+		FString Windows_Node_Specific_Commands[Num_Nodes] = {
+			"dc_node=node_floor WinX=720  WinY=300 ResX=480 ResY=480" + FString((Settings->MiniCAVELogMasterWindow) ? " -log" : "") + ((Settings->MiniCAVELogToProjectDirFloor) ? (" ABSLOG=" + GetFilePathInProject("MiniCave_Floor_Master.log")) : "") + " " + Settings->MiniCAVEAdditionalLaunchParametersMaster,
+			"dc_node=node_front WinX=720  WinY=0   ResX=480 ResY=300" + ((Settings->MiniCAVELogToProjectDirFront) ? (" ABSLOG=" + GetFilePathInProject("MiniCave_Front.log")) : ""),
+			"dc_node=node_left  WinX=420  WinY=300 ResX=300 ResY=480" + ((Settings->MiniCAVELogToProjectDirLeft) ?  (" ABSLOG=" + GetFilePathInProject("MiniCave_Left.log" )) : ""),
+			"dc_node=node_right WinX=1200 WinY=300 ResX=300 ResY=480" + ((Settings->MiniCAVELogToProjectDirRight) ? (" ABSLOG=" + GetFilePathInProject("MiniCave_Right.log")) : ""),
+			"dc_node=node_back  WinX=720  WinY=780 ResX=480 ResY=300" + ((Settings->MiniCAVELogToProjectDirBack) ?  (" ABSLOG=" + GetFilePathInProject("MiniCave_Back.log" )) : "")
+		};
+
+		FProcHandle Processes[Num_Nodes];
+		for (int i = 0; i < Num_Nodes; i++)
+		{
+			Processes[i] = FPlatformProcess::CreateProc(*GetEditorExecutableName(), *(Parameters + " " + InsightParameters + " " + Windows_Node_Specific_Commands[i]), true, false, false, nullptr, 0, nullptr, nullptr);
+		}
+		FPlatformProcess::WaitForProc(Processes[0]); /* wait for only one of them */
+
+		KillProcesses(Processes, Num_Nodes); /* Kill potentially crashed processes */
+	}
+	else if (Settings->LaunchType == ButtonLaunchType_TWO_SCREEN)
+	{
+		const FString Parameters = FString::Printf(TEXT("\"%s\" -game dc_cfg=\"%s\" %s"),*FPaths::GetProjectFilePath(), *GetConfigPath("twoscreen"), *Settings->TwoScreenLaunchParameters);
+		
+		const int Num_Nodes = 2;
+		FString Windows_Node_Specific_Commands[Num_Nodes] = {
+			"dc_node=node_left  WinX=200 WinY=200 ResX=480 ResY=480" + FString((Settings->TwoScreenLogMasterWindow) ? " -log" : "") + ((Settings->TwoScreenLogToProjectDirLeft) ? (" ABSLOG=" + GetFilePathInProject("TwoScreen_Left_Master.log")) : "") + " " + Settings->TwoScreenAdditionalLaunchParametersMaster,
+			"dc_node=node_right WinX=682 WinY=200 ResX=480 ResY=480" + ((Settings->TwoScreenLogToProjectDirRight) ? (" ABSLOG = " + GetFilePathInProject("TwoScreen_Right.log")) : "")
+		};
+
+		FProcHandle Processes[Num_Nodes];
+		for (int i = 0; i < Num_Nodes; i++)
+		{
+			Processes[i] = FPlatformProcess::CreateProc(*GetEditorExecutableName(), *(Parameters + " " + InsightParameters + " " + Windows_Node_Specific_Commands[i]), true, false, false, nullptr, 0, nullptr, nullptr);
+		}
+		FPlatformProcess::WaitForProc(Processes[0]); /* wait for only one of them */
+		
+		KillProcesses(Processes, Num_Nodes); /* Kill potentially crashed processes */
+	}
+	else if (Settings->LaunchType == ButtonLaunchType_TDW)
+	{
+		const FString Parameters = FString::Printf(TEXT("\"%s\" -game dc_cfg=\"%s\" %s"),*FPaths::GetProjectFilePath(), *GetConfigPath("tileddisplaywall") ,*Settings->TiledDisplayWallLaunchParameters);
+		
+		const int Num_Nodes = 6;
+		FString Windows_Node_Specific_Commands[Num_Nodes] = {
+			"dc_node=node_tl  WinX=200 WinY=200  ResX=480 ResY=272" + FString((Settings->TiledDisplayWallLogMasterWindow) ? " -log" : "") + ((Settings->TiledDisplayWallLogToProjectDirTL) ? (" ABSLOG=" + GetFilePathInProject("TiledDisplayWall_TL_Master.log")) : "") + " " + Settings->TiledDisplayWallAdditionalLaunchParametersMaster,
+			"dc_node=node_tm  WinX=693 WinY=200  ResX=480 ResY=272" + ((Settings->TiledDisplayWallLogToProjectDirTM) ? (" ABSLOG = " + GetFilePathInProject("TiledDisplayWall_TM.log")) : ""),
+			"dc_node=node_tr  WinX=1186 WinY=200 ResX=480 ResY=272" + ((Settings->TiledDisplayWallLogToProjectDirTR) ? (" ABSLOG = " + GetFilePathInProject("TiledDisplayWall_TR.log")) : ""),
+			"dc_node=node_bl  WinX=200 WinY=483  ResX=480 ResY=272" + ((Settings->TiledDisplayWallLogToProjectDirBL) ? (" ABSLOG = " + GetFilePathInProject("TiledDisplayWall_BL.log")) : ""),
+			"dc_node=node_bm  WinX=693 WinY=483  ResX=480 ResY=272" + ((Settings->TiledDisplayWallLogToProjectDirBM) ? (" ABSLOG = " + GetFilePathInProject("TiledDisplayWall_BM.log")) : ""),
+			"dc_node=node_br  WinX=1186 WinY=483 ResX=480 ResY=272" + ((Settings->TiledDisplayWallLogToProjectDirBR) ? (" ABSLOG = " + GetFilePathInProject("TiledDisplayWall_BR.log")) : "")
+		};
+
+		FProcHandle Processes[Num_Nodes];
+		for (int i = 0; i < Num_Nodes; i++)
+		{
+			Processes[i] = FPlatformProcess::CreateProc(*GetEditorExecutableName(), *(Parameters + " " + InsightParameters + " " + Windows_Node_Specific_Commands[i]), true, false, false, nullptr, 0, nullptr, nullptr);
+		}
+		FPlatformProcess::WaitForProc(Processes[0]); /* wait for only one of them */
+
+		KillProcesses(Processes, Num_Nodes); /* Kill potentially crashed processes */
+	}
+	else if (Settings->LaunchType == ButtonLaunchType_CAVE)
+	{
+		FProcHandle Instance = FPlatformProcess::CreateProc(
+			*Settings->CAVELaunchScriptPath.FilePath,
+			*("\"" + (FPaths::ConvertRelativePathToFull(".") + "/UE4Editor\"")
+				+ " " + FPaths::ConvertRelativePathToFull(FPaths::GetProjectFilePath())
+				+ " " + FString::FromInt(FEngineVersion::Current().GetMajor())
+				+ FString::FromInt(FEngineVersion::Current().GetMinor())
+				+ " " + InsightParameters), // Test this
+			true, false, false, nullptr, 0, nullptr, nullptr);
+		FPlatformProcess::WaitForProc(Instance);
+	}
+
+	/* Re-maximize Editor Window */
+	if (RootWindow.IsValid()) RootWindow->Maximize();
+
+	/* Restore Plugin States */
+	ChangePluginStateAndStoreConfig("SteamVR", SteamVRState, SteamVRState);
+	ChangePluginStateAndStoreConfig("OculusVR", OculusVRState, OculusVRState);
+}
+
+/**
+ * Send a command to the DTrack controller
+ * @param Address - IP address of DTrack controller
+ * @param Port - Port to contact DTrack controller
+ * @param Message - Message to send
+ */
+void FNDisplayLaunchButtonModule::SendToDTrack(FString Address, int Port, FString Message)
+{
+	FSocket* Socket = USocketHelper::OpenSocket(Address, Port, "DTrackSocket");
+	if (!Socket) return;
+	if (USocketHelper::SendSocket(Socket, Message) <= 0) return;
+	FString Response = USocketHelper::ReceiveSocket<100>(Socket);
+	if (Response.Compare("dtrack2 ok") != 0)
+	{
+		UE_LOG(LogTemp, Error, TEXT("DTrack Command Failed. Response: '%s'"), *Response);
+	}
+	Socket->Shutdown(ESocketShutdownMode::ReadWrite);
+	Socket->Close();
+}
+
+/**
+ * Switch the display mode of the projector a 3D display mode or back
+ * @param Address - IP address of projector
+ * @param Port - Port to contact projector
+ * @param State - Switch to this state
+ * @return state of the projector before the change
+ */
+ProjectorDisplayType FNDisplayLaunchButtonModule::SwitchProjectorToState(FString Address, int Port, ProjectorDisplayType State)
+{
+	ProjectorDisplayType ModeBefore = ProjectorDisplayType::DisplayType_Error;
+	FSocket* Socket = USocketHelper::OpenSocket(Address, Port, "ProjectorSocket");
+	if (!Socket) return ModeBefore;
+
+	//Get mode from before
+	if (USocketHelper::SendSocket(Socket, ":TDSM ?\r") <= 0) return ModeBefore;
+	FString Response = USocketHelper::ReceiveSocket<100>(Socket); //Response looks like: %001 TDSM 000000
+
+	if (!Response.IsEmpty())
+	{
+		int32 Position = 0;
+		Response.FindLastChar(' ', Position);
+		ModeBefore = static_cast<ProjectorDisplayType>(FCString::Atoi(*Response.RightChop(Position)));
+	}
+
+	if (Response.IsEmpty() || USocketHelper::SendSocket(Socket, ":TDSM " + FString::FromInt(State) + "\r") <= 0)
+	{
+		Socket->Shutdown(ESocketShutdownMode::ReadWrite);
+		Socket->Close();
+		return ModeBefore;
+	}
+	Response = USocketHelper::ReceiveSocket<100>(Socket);
+	if (Response.EndsWith(")"))
+	{
+		//Errors are marked like this
+		UE_LOG(LogTemp, Error, TEXT("Projector Type Change Failed. Response: '%s'"), *Response);
+	}
+	Socket->Shutdown(ESocketShutdownMode::ReadWrite);
+	Socket->Close();
+	return ModeBefore;
+}
+
+IMPLEMENT_MODULE(FNDisplayLaunchButtonModule, NDisplayLaunchButton)
diff --git a/Source/NDisplayLaunchButton/Public/NDisplayLaunchButton.h b/Source/NDisplayLaunchButton/Public/NDisplayLaunchButton.h
index f23187186584483a8b8659954c52891ecfc35c9f..f36d47e10f9f479cfe56772793acab37a6e99a10 100644
--- a/Source/NDisplayLaunchButton/Public/NDisplayLaunchButton.h
+++ b/Source/NDisplayLaunchButton/Public/NDisplayLaunchButton.h
@@ -1,29 +1,37 @@
-// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
-
-#pragma once
-
-#include "CoreMinimal.h"
-#include "Modules/ModuleManager.h"
-#include "NDisplayLaunchButtonSettings.h"
-#include "Logging/LogMacros.h"
-#include "Framework/MultiBox/MultiBoxBuilder.h"
-
-class FToolBarBuilder;
-class FMenuBuilder;
-
-DECLARE_LOG_CATEGORY_EXTERN(LogNDisplayLaunchButton, Log, All);
-
-class FNDisplayLaunchButtonModule : public IModuleInterface
-{
-public:
-
-	/** IModuleInterface implementation */
-	virtual void StartupModule() override;
-	virtual void ShutdownModule() override;
-
-	/** This function will be bound to Command. */
-	void PluginButtonClicked();
-
-	void SendToDTrack(FString Address, int Port, FString Message);
-	ProjectorDisplayType SwitchProjectorToState(FString Address, int Port, ProjectorDisplayType State);
-};
+// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "Modules/ModuleManager.h"
+#include "NDisplayLaunchButtonSettings.h"
+#include "Logging/LogMacros.h"
+#include "Framework/MultiBox/MultiBoxBuilder.h"
+
+class FToolBarBuilder;
+class FMenuBuilder;
+
+DECLARE_LOG_CATEGORY_EXTERN(LogNDisplayLaunchButton, Log, All);
+
+class FNDisplayLaunchButtonModule : public IModuleInterface
+{
+public:
+
+	/** IModuleInterface implementation */
+	virtual void StartupModule() override;
+	virtual void ShutdownModule() override;
+	bool ChangePluginStateAndStoreConfig(FString PluginName, bool NewState, bool& OldState) const;
+	static FString GetEditorExecutableName();
+	static FString GetFilePathInProject(FString FileName);
+	static FString GetConfigPath(FString ConfigName);
+	static void KillProcesses(FProcHandle Processes[], const int Num_Nodes);
+
+	/** This function will be bound to Command. */
+	void PluginButtonClicked();
+
+	void SendToDTrack(FString Address, int Port, FString Message);
+	ProjectorDisplayType SwitchProjectorToState(FString Address, int Port, ProjectorDisplayType State);
+private:
+	bool SteamVRState = false;
+	bool OculusVRState = false;
+};
diff --git a/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h b/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h
index 9481874d7d8e646bd320d0198be8e217901df196..538bb468f1577f80fa27a28e2c2734bae9908d55 100644
--- a/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h
+++ b/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h
@@ -1,153 +1,160 @@
-#pragma once
-#include "CoreMinimal.h"
-#include "Engine/EngineTypes.h"
-#include "Engine/DeveloperSettings.h"
-#include "NDisplayLaunchButtonSettings.generated.h"
-
-UENUM(BlueprintType)
-enum ProjectorDisplayType
-{
-	DisplayType_Off = 0 UMETA(DisplayName = "Off"),
-	DisplayType_Frame_Sequential = 1 UMETA(DisplayName = "Frame Sequential"),
-	DisplayType_Side_By_Side = 2 UMETA(DisplayName = "Side By Side"),
-	DisplayType_DualHead = 3 UMETA(DisplayName = "Dual Head"),
-	DisplayType_Error = 4 UMETA(Hidden)
-};
-
-UENUM(BlueprintType)
-enum ButtonLaunchType
-{
-	ButtonLaunchType_NONE UMETA(DisplayName = "Nothing"),
-	ButtonLaunchType_MiniCAVE UMETA(DisplayName = "MiniCAVE"),
-	ButtonLaunchType_TWO_SCREEN UMETA(DisplayName = "Two Screen"),
-	ButtonLaunchType_CAVE UMETA(DisplayName = "CAVE"),
-	ButtonLaunchType_ROLV UMETA(DisplayName = "ROLV")
-};
-
-UCLASS(config=Engine, defaultconfig, meta=(DisplayName="nDisplay Launch Button"))
-class UNDisplayLaunchButtonSettings : public UDeveloperSettings
-{
-	GENERATED_BODY()
-
-public:
-	UPROPERTY(EditAnywhere, config, Category = "General", meta = (DisplayName = "Start "))
-	TEnumAsByte<ButtonLaunchType> LaunchType = ButtonLaunchType_MiniCAVE;
-
-	/*
-	 * TwoScreen Options
-	 */
-	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen", meta = (DisplayName = "Launch Parameters"))
-	FString TwoScreenLaunchParameters = "-dc_cluster -dc_dev_mono -windowed -fixedseed -notexturestreaming";
-	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen", meta = (DisplayName = "Additioanl Launch Parameters for Master"))
-	FString TwoScreenAdditionalLaunchParametersMaster = "";
-	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen|Log", meta = (DisplayName = "Open Log Window for Master Node"))
-	bool TwoScreenLogMasterWindow = true;
-	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen|Log", meta = (DisplayName = "Write Log for Floor-Left to Project Directory"))
-	bool TwoScreenLogToProjectDirLeft = true;
-	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen|Log", meta = (DisplayName = "Write Log for Front-Right to Project Directory"))
-	bool TwoScreenLogToProjectDirRight = false;
-
-	/*
-	 * Mini CAVE Options
-	 */
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE", meta = (DisplayName = "Launch Parameters"))
-	FString MiniCAVELaunchParameters = "-dc_cluster -dc_dev_mono -windowed -fixedseed -notexturestreaming";
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE", meta = (DisplayName = "Additioanl Launch Parameters for Master"))
-	FString MiniCAVEAdditionalLaunchParametersMaster = "-log";
-
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Open Log Window for Master Node"))
-	bool MiniCAVELogMasterWindow = true;
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Floor-Node to Project Directory"))
-	bool MiniCAVELogToProjectDirFloor = true;
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Front-Node to Project Directory"))
-	bool MiniCAVELogToProjectDirFront = false;
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Left-Node to Project Directory"))
-	bool MiniCAVELogToProjectDirLeft = false;
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Right-Node to Project Directory"))
-	bool MiniCAVELogToProjectDirRight = false;
-	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Back-Node to Project Directory"))
-	bool MiniCAVELogToProjectDirBack = false;
-
-	/*
-	 * CAVE Options
-	 */
-	UPROPERTY(EditAnywhere, config, Category = "General|CAVE", meta = (DisplayName = "Path to Launch Script"))
-	FFilePath CAVELaunchScriptPath;
-
-	/*
-	 * ROLV Options
-	 */
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV", meta = (DisplayName = "Path to the ROLV nDisplay Config"))
-	FFilePath RolvConfig;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV", meta = (DisplayName = "Launch Parameters"))
-	FString ROLVLaunchParameters = "-dc_cluster -nosplash -fixedseed -dx11 -dc_dev_side_by_side -notexturestreaming -fullscreen dc_node=node_main";
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV", meta = (DisplayName = "Write Log to Project Directory"))
-	bool ROLVLogToProjectDir = true;
-
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Change Projector Mode on Startup"))
-	bool SwitchProjector = true;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Switch to "))
-	TEnumAsByte<ProjectorDisplayType> ProjectorType;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Projector IP"))
-	FString ProjectorIP;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Projector Port"))
-	int ProjectorPort = 1025;
-
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|VRPN", meta = (DisplayName = "Start VRPN in the Background"))
-	bool StartVRPN = true;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|VRPN", meta = (DisplayName = "Path to VRPN Executable"))
-	FFilePath VRPNPath;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|VRPN", meta = (DisplayName = "Path to VRPN Config"))
-	FFilePath VRPNConfigPath;
-
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|DTRACK", meta = (DisplayName = "Start DTrack in the Background"))
-	bool StartDTrack = true;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|DTRACK", meta = (DisplayName = "DTrack IP"))
-	FString DTrackIP;
-	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|DTRACK", meta = (DisplayName = "DTrack Port"))
-	int DTrackPort = 50105;
-
-	//Macro used to shorten code
-#define PROPERTY_CONDITION_CHECK(Variable, Condition) if (InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UNDisplayLaunchButtonSettings, Variable)) return Condition;
-
-	bool CanEditChange(const UProperty* InProperty) const override
-	{
-		const bool ParentVal = Super::CanEditChange(InProperty);
-
-		//TODO: This Code is not executed for all FFilePath Properties. Check if this works in 4.23 with the EditCondition Parser and remove this method
-
-		PROPERTY_CONDITION_CHECK(TwoScreenLaunchParameters, LaunchType == ButtonLaunchType_TWO_SCREEN)
-		PROPERTY_CONDITION_CHECK(TwoScreenAdditionalLaunchParametersMaster, LaunchType == ButtonLaunchType_TWO_SCREEN)
-		PROPERTY_CONDITION_CHECK(TwoScreenLogToProjectDirRight, LaunchType == ButtonLaunchType_TWO_SCREEN)
-		PROPERTY_CONDITION_CHECK(TwoScreenLogToProjectDirLeft, LaunchType == ButtonLaunchType_TWO_SCREEN)
-		PROPERTY_CONDITION_CHECK(TwoScreenLogMasterWindow, LaunchType == ButtonLaunchType_TWO_SCREEN)
-
-		PROPERTY_CONDITION_CHECK(MiniCAVELaunchParameters, LaunchType == ButtonLaunchType_MiniCAVE)
-		PROPERTY_CONDITION_CHECK(MiniCAVEAdditionalLaunchParametersMaster, LaunchType == ButtonLaunchType_MiniCAVE)
-		PROPERTY_CONDITION_CHECK(MiniCAVELogToProjectDirFloor, LaunchType == ButtonLaunchType_MiniCAVE)
-		PROPERTY_CONDITION_CHECK(MiniCAVELogToProjectDirFront, LaunchType == ButtonLaunchType_MiniCAVE)
-		PROPERTY_CONDITION_CHECK(MiniCAVELogToProjectDirLeft, LaunchType == ButtonLaunchType_MiniCAVE)
-		PROPERTY_CONDITION_CHECK(MiniCAVELogToProjectDirRight, LaunchType == ButtonLaunchType_MiniCAVE)
-		PROPERTY_CONDITION_CHECK(MiniCAVELogToProjectDirBack, LaunchType == ButtonLaunchType_MiniCAVE)
-		PROPERTY_CONDITION_CHECK(MiniCAVELogMasterWindow, LaunchType == ButtonLaunchType_MiniCAVE)
-
-		PROPERTY_CONDITION_CHECK(CAVELaunchScriptPath, LaunchType == ButtonLaunchType_CAVE)
-
-		PROPERTY_CONDITION_CHECK(RolvConfig, LaunchType == ButtonLaunchType_ROLV)
-		PROPERTY_CONDITION_CHECK(ROLVLaunchParameters, LaunchType == ButtonLaunchType_ROLV)
-		PROPERTY_CONDITION_CHECK(ROLVLogToProjectDir, LaunchType == ButtonLaunchType_ROLV)
-		PROPERTY_CONDITION_CHECK(SwitchProjector, LaunchType == ButtonLaunchType_ROLV)
-		PROPERTY_CONDITION_CHECK(ProjectorType, LaunchType == ButtonLaunchType_ROLV && SwitchProjector)
-		PROPERTY_CONDITION_CHECK(ProjectorIP, LaunchType == ButtonLaunchType_ROLV && SwitchProjector)
-		PROPERTY_CONDITION_CHECK(ProjectorPort, LaunchType == ButtonLaunchType_ROLV && SwitchProjector)
-		PROPERTY_CONDITION_CHECK(VRPNConfigPath, LaunchType == ButtonLaunchType_ROLV && StartVRPN)
-		PROPERTY_CONDITION_CHECK(StartVRPN, LaunchType == ButtonLaunchType_ROLV)
-		PROPERTY_CONDITION_CHECK(VRPNPath, LaunchType == ButtonLaunchType_ROLV && StartVRPN)
-		PROPERTY_CONDITION_CHECK(VRPNConfigPath, LaunchType == ButtonLaunchType_ROLV && StartVRPN)
-		PROPERTY_CONDITION_CHECK(StartDTrack, LaunchType == ButtonLaunchType_ROLV)
-		PROPERTY_CONDITION_CHECK(DTrackIP, LaunchType == ButtonLaunchType_ROLV && StartDTrack)
-		PROPERTY_CONDITION_CHECK(DTrackPort, LaunchType == ButtonLaunchType_ROLV && StartDTrack)
-
-		return ParentVal;
-	}
-};
+#pragma once
+#include "CoreMinimal.h"
+#include "Engine/EngineTypes.h"
+#include "Engine/DeveloperSettings.h"
+#include "NDisplayLaunchButtonSettings.generated.h"
+
+UENUM(BlueprintType)
+enum ProjectorDisplayType
+{
+	DisplayType_Off = 0 UMETA(DisplayName = "Off"),
+	DisplayType_Frame_Sequential = 1 UMETA(DisplayName = "Frame Sequential"),
+	DisplayType_Side_By_Side = 2 UMETA(DisplayName = "Side By Side"),
+	DisplayType_DualHead = 3 UMETA(DisplayName = "Dual Head"),
+	DisplayType_Error = 4 UMETA(Hidden)
+};
+
+UENUM(BlueprintType)
+enum ButtonLaunchType
+{
+	ButtonLaunchType_NONE UMETA(DisplayName = "Nothing"),
+	ButtonLaunchType_MiniCAVE UMETA(DisplayName = "MiniCAVE"),
+	ButtonLaunchType_TWO_SCREEN UMETA(DisplayName = "Two Screen"),
+	ButtonLaunchType_CAVE UMETA(DisplayName = "CAVE"),
+	ButtonLaunchType_ROLV UMETA(DisplayName = "ROLV"),
+	ButtonLaunchType_TDW UMETA(DisplayName = "Tiled Display Wall")
+};
+
+UCLASS(config=Engine, defaultconfig, meta=(DisplayName="nDisplay Launch Button"))
+class UNDisplayLaunchButtonSettings : public UDeveloperSettings
+{
+	GENERATED_BODY()
+
+public:
+	UPROPERTY(EditAnywhere, config, Category = "General", meta = (DisplayName = "Start "))
+	TEnumAsByte<ButtonLaunchType> LaunchType = ButtonLaunchType_MiniCAVE;
+
+	/*
+	 * TwoScreen Options
+	 */
+	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen", meta = (DisplayName = "Launch Parameters", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TWO_SCREEN"))
+	FString TwoScreenLaunchParameters = "-dc_cluster -dc_dev_mono -windowed -fixedseed -notexturestreaming";
+	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen", meta = (DisplayName = "Additioanl Launch Parameters for Master", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TWO_SCREEN"))
+	FString TwoScreenAdditionalLaunchParametersMaster = "";
+	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen|Log", meta = (DisplayName = "Open Log Window for Master Node", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TWO_SCREEN"))
+	bool TwoScreenLogMasterWindow = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen|Log", meta = (DisplayName = "Write Log for Floor-Left to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TWO_SCREEN"))
+	bool TwoScreenLogToProjectDirLeft = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen|Log", meta = (DisplayName = "Write Log for Front-Right to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TWO_SCREEN"))
+	bool TwoScreenLogToProjectDirRight = false;
+
+	/*
+	 * Mini CAVE Options
+	 */
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE", meta = (DisplayName = "Launch Parameters", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	FString MiniCAVELaunchParameters = "-dc_cluster -dc_dev_mono -windowed -fixedseed -notexturestreaming";
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE", meta = (DisplayName = "Additioanl Launch Parameters for Master", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	FString MiniCAVEAdditionalLaunchParametersMaster = "-log";
+
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Open Log Window for Master Node", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	bool MiniCAVELogMasterWindow = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Floor-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	bool MiniCAVELogToProjectDirFloor = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Front-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	bool MiniCAVELogToProjectDirFront = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Left-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	bool MiniCAVELogToProjectDirLeft = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Right-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	bool MiniCAVELogToProjectDirRight = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|MiniCAVE|Log", meta = (DisplayName = "Write Log for Back-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_MiniCAVE"))
+	bool MiniCAVELogToProjectDirBack = false;
+
+	/*
+	 * CAVE Options
+	 */
+	UPROPERTY(EditAnywhere, config, Category = "General|CAVE", meta = (DisplayName = "Path to Launch Script", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_CAVE"))
+	FFilePath CAVELaunchScriptPath;
+
+	/*
+	 * ROLV Options
+	 */
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV", meta = (DisplayName = "Path to the ROLV nDisplay Config", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV"))
+	FFilePath RolvConfig;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV", meta = (DisplayName = "Launch Parameters", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV"))
+	FString ROLVLaunchParameters = "-dc_cluster -nosplash -fixedseed -dx11 -dc_dev_side_by_side -notexturestreaming -fullscreen dc_node=node_main";
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV", meta = (DisplayName = "Write Log to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV"))
+	bool ROLVLogToProjectDir = true;
+
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Change Projector Mode on Startup", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV"))
+	bool SwitchProjector = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Switch to ", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV && SwitchProjector"))
+	TEnumAsByte<ProjectorDisplayType> ProjectorType;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Projector IP", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV && SwitchProjector"))
+	FString ProjectorIP;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|Projector", meta = (DisplayName = "Projector Port", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV && SwitchProjector"))
+	int ProjectorPort = 1025;
+
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|VRPN", meta = (DisplayName = "Start VRPN in the Background", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV"))
+	bool StartVRPN = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|VRPN", meta = (DisplayName = "Path to VRPN Executable", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV && StartVRPN"))
+	FFilePath VRPNPath;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|VRPN", meta = (DisplayName = "Path to VRPN Config", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV && StartVRPN"))
+	FFilePath VRPNConfigPath;
+
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|DTRACK", meta = (DisplayName = "Start DTrack in the Background", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV"))
+	bool StartDTrack = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|DTRACK", meta = (DisplayName = "DTrack IP", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV && StartDTrack"))
+	FString DTrackIP;
+	UPROPERTY(EditAnywhere, config, Category = "General|ROLV|DTRACK", meta = (DisplayName = "DTrack Port", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_ROLV && StartDTrack"))
+	int DTrackPort = 50105;
+
+	/*
+	* TiledDisplayWall Options
+	*/
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall", meta = (DisplayName = "Launch Parameters", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	FString TiledDisplayWallLaunchParameters = "-dc_cluster -dc_dev_mono -windowed -fixedseed -notexturestreaming";
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall", meta = (DisplayName = "Additional Launch Parameters for Master", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	FString TiledDisplayWallAdditionalLaunchParametersMaster = "";
+	
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall|Log", meta = (DisplayName = "Open Log Window for Master Node", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	bool TiledDisplayWallLogMasterWindow = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall|Log", meta = (DisplayName = "Write Log for TL-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	bool TiledDisplayWallLogToProjectDirTL = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall|Log", meta = (DisplayName = "Write Log for TM-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	bool TiledDisplayWallLogToProjectDirTM = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall|Log", meta = (DisplayName = "Write Log for TR-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	bool TiledDisplayWallLogToProjectDirTR = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall|Log", meta = (DisplayName = "Write Log for BL-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	bool TiledDisplayWallLogToProjectDirBL = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall|Log", meta = (DisplayName = "Write Log for BM-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	bool TiledDisplayWallLogToProjectDirBM = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|TiledDisplayWall|Log", meta = (DisplayName = "Write Log for BR-Node to Project Directory", EditCondition="LaunchType==ButtonLaunchType::ButtonLaunchType_TDW"))
+	bool TiledDisplayWallLogToProjectDirBR = false;
+
+	/*
+	 * Insights Options
+	 */
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights", meta = (DisplayName = "Unreal Insights "))
+	bool bEnableInsights = false;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights", meta = (DisplayName = "Stat Named Events", EditCondition = "bEnableInsights==true"))
+	bool bStatNamedEvents = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights", meta = (DisplayName = "Tracehost IP", EditCondition = "bEnableInsights==true"))
+	FString TracehostIP = "127.0.0.1";
+
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "Log", EditCondition = "bEnableInsights==true"))
+	bool bLog = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "Bookmark", EditCondition = "bEnableInsights==true"))
+	bool bBookmark = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "Frame", EditCondition = "bEnableInsights==true"))
+	bool bFrame = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "CPU", EditCondition = "bEnableInsights==true"))
+	bool bCPU = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "GPU", EditCondition = "bEnableInsights==true"))
+	bool bGPU = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "LoadTime", EditCondition = "bEnableInsights==true"))
+	bool bLoadTime = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "File", EditCondition = "bEnableInsights==true"))
+	bool bFile = true;
+	UPROPERTY(EditAnywhere, config, Category = "General|Insights|Trace Channels", meta = (DisplayName = "Net", EditCondition = "bEnableInsights==true"))
+	bool bNet = true;
+};