]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote branch 'origin/master' into samual/crosshair_ring_updates
authorSamual <samual@xonotic.org>
Tue, 22 Feb 2011 06:03:51 +0000 (01:03 -0500)
committerSamual <samual@xonotic.org>
Tue, 22 Feb 2011 06:03:51 +0000 (01:03 -0500)
20 files changed:
balanceSamual.cfg
defaultXonotic.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_xhair_minimal.cfg
hud_nexuiz.cfg
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/menu/item/button.c
qcsrc/menu/item/slider.c
qcsrc/menu/xonotic/dialog_multiplayer_join.c
qcsrc/menu/xonotic/dialog_multiplayer_playersetup.c
qcsrc/menu/xonotic/serverlist.c
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/sv_main.qc
qcsrc/server/t_items.qc
qcsrc/server/t_quake3.qc
quake.rc

index 02f16775fc3dde1c8e4ecad142e402a025658c68..83a1db0a7cab6a242bc5760f354b19cb0710e4f2 100644 (file)
@@ -17,7 +17,7 @@ set g_start_weapon_sniperrifle -1 "0 = never provide the weapon, 1 = always prov
 set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
 set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
 set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
-set g_balance_health_start 150
+set g_balance_health_start 100
 set g_balance_armor_start 0
 set g_start_ammo_shells 15
 set g_start_ammo_nails 0
@@ -487,7 +487,7 @@ set g_balance_nex_secondary_damagefalloff_forcehalflife 0
 
 set g_balance_nex_charge 1
 set g_balance_nex_charge_mindmg 40
-set g_balance_nex_charge_start 0
+set g_balance_nex_charge_start 0.5
 set g_balance_nex_charge_rate 0.3
 set g_balance_nex_charge_animlimit 0.5
 set g_balance_nex_charge_limit 1
@@ -534,13 +534,13 @@ set g_balance_rocketlauncher_speed 1500
 set g_balance_rocketlauncher_speedaccel 1500
 set g_balance_rocketlauncher_speedstart 800
 set g_balance_rocketlauncher_lifetime 30
-set g_balance_rocketlauncher_refire 1.2
+set g_balance_rocketlauncher_refire 1.1
 set g_balance_rocketlauncher_animtime 0.3
 set g_balance_rocketlauncher_ammo 3
 set g_balance_rocketlauncher_health 30 // 5 hitpoints above maximum laser value -- this way lasers can't blow it up, but grenadelauncher still can most the time.
 set g_balance_rocketlauncher_damageforcescale 4
 set g_balance_rocketlauncher_detonatedelay 0.05 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
-set g_balance_rocketlauncher_guiderate 140 // max degrees per second
+set g_balance_rocketlauncher_guiderate 130 // max degrees per second
 set g_balance_rocketlauncher_guideratedelay 0.01 // immediate
 set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
 set g_balance_rocketlauncher_guidedelay 0.15 // delay before guiding kicks in
index 9f0c44d3a36d245bd677bfe896133fa47932f450..95adfb723c0b06a4f0ab9111cd5d2e120d80ed5a 100644 (file)
@@ -2110,7 +2110,6 @@ exec ctfscoring-ai.cfg
 exec effects-normal.cfg
 exec physicsX0.cfg
 exec turrets.cfg
-exec font-xolonium.cfg
 
 // hud cvar descriptions
 exec _hud_descriptions.cfg
index a3f3ed39e51f0dd8961f77f80094f1f600986fd6..ca8ea38de05476976feaf3a64b31755697d7cd44 100644 (file)
@@ -108,6 +108,7 @@ seta hud_panel_notify_bg_alpha ""
 seta hud_panel_notify_bg_border ""
 seta hud_panel_notify_bg_padding ""
 seta hud_panel_notify_flip "0"
+seta hud_panel_notify_fontsize "0.8"
 seta hud_panel_notify_print "1"
 
 seta hud_panel_timer 1
@@ -120,7 +121,7 @@ seta hud_panel_timer_bg_alpha ""
 seta hud_panel_timer_bg_border ""
 seta hud_panel_timer_bg_padding "0"
 
-seta hud_panel_radar 1
+seta hud_panel_radar 2 // enabled for keepaway and to make the HUD consistent throughout game modes
 seta hud_panel_radar_pos "0.030000 0.020000"
 seta hud_panel_radar_size "0.170000 0.220000"
 seta hud_panel_radar_bg ""
index 8e39416314bdf665e1ad59b1cfaf26119ee926a5..fef69f23fd52f73104af2e0f42558d132c931852 100644 (file)
@@ -108,6 +108,7 @@ seta hud_panel_notify_bg_alpha ""
 seta hud_panel_notify_bg_border ""
 seta hud_panel_notify_bg_padding ""
 seta hud_panel_notify_flip "1"
+seta hud_panel_notify_fontsize "0.8"
 seta hud_panel_notify_print "0"
 
 seta hud_panel_timer 1
index 10f7afd149822e08d9b99e94521e17373d04dbf3..80fe445e48cb85ecce0e558606e43ac2b74dc14e 100644 (file)
@@ -107,6 +107,7 @@ seta hud_panel_notify_bg_alpha ""
 seta hud_panel_notify_bg_border ""
 seta hud_panel_notify_bg_padding ""
 seta hud_panel_notify_flip "1"
+seta hud_panel_notify_fontsize "0.8"
 seta hud_panel_notify_print "0"
 
 seta hud_panel_timer 1
index 681b7378e01fa3ce213ba3b552b2cca169f6913c..cfa50af89acb4dd8add91079c3c9cfcc7a886954 100644 (file)
@@ -108,6 +108,7 @@ seta hud_panel_notify_bg_alpha "0"
 seta hud_panel_notify_bg_border ""
 seta hud_panel_notify_bg_padding ""
 seta hud_panel_notify_flip "0"
+seta hud_panel_notify_fontsize "1"
 seta hud_panel_notify_print "1"
 
 seta hud_panel_timer 1
index 01bcce10edbb478da3d1be84bbad3dc4e2921c86..867859c571de307787db1182970cb8a201619f30 100644 (file)
@@ -215,6 +215,7 @@ float autocvar_hud_panel_modicons;
 float autocvar_hud_panel_notify;
 float autocvar_hud_panel_notify_fadetime;
 float autocvar_hud_panel_notify_flip;
+float autocvar_hud_panel_notify_fontsize;
 float autocvar_hud_panel_notify_print;
 float autocvar_hud_panel_notify_time;
 float autocvar_hud_panel_powerups;
index e8309ef4e92a75cfcb633108c2471e9462b6c281..d55cfd86612c76b69034738b7bf0a7d714fe398f 100644 (file)
@@ -3142,7 +3142,8 @@ void HUD_Notify (void)
        height = mySize_y/entries;
        
        vector fontsize;
-       fontsize = '0.5 0.5 0' * height;
+       float fontheight = height * autocvar_hud_panel_notify_fontsize;
+       fontsize = '0.5 0.5 0' * fontheight;
 
        float a;
        float when;
@@ -3316,7 +3317,7 @@ void HUD_Notify (void)
                        }
                        
                        attacker = textShortenToWidth(killnotify_attackers[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
-                       pos_attacker = pos + eX * (0.52 * mySize_x + height) + eY * (0.5 * fontsize_y + i * height);
+                       pos_attacker = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
                        weap_pos = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
 
                        if(s != "")
@@ -3402,8 +3403,8 @@ void HUD_Notify (void)
                        victim = textShortenToWidth(killnotify_victims[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
 :hud_config_notifyprint
                        width_attacker = stringwidth(attacker, TRUE, fontsize);
-                       pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * (0.5 * fontsize_y + i * height);
-                       pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * (0.5 * fontsize_y + i * height);
+                       pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
+                       pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
                        weap_pos = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
 
                        if(s != "")
index 871685f53797cfa38e11603e1297a15c3eb96a62..527672d254f41acb6795a336f05da00d3ffb7e45 100644 (file)
@@ -8,6 +8,7 @@ CLASS(Button) EXTENDS(Label)
        METHOD(Button, mousePress, float(entity, vector))
        METHOD(Button, mouseDrag, float(entity, vector))
        METHOD(Button, mouseRelease, float(entity, vector))
+       METHOD(Button, focusEnter, void(entity))
        ATTRIB(Button, onClick, void(entity, entity), SUB_Null)
        ATTRIB(Button, onClickEntity, entity, NULL)
        ATTRIB(Button, src, string, string_null)
@@ -69,12 +70,12 @@ float Button_mouseDrag(entity me, vector pos)
 float Button_mousePress(entity me, vector pos)
 {
        me.mouseDrag(me, pos); // verify coordinates
-       if(cvar("menu_sounds"))
-               localsound("sound/misc/menu2.wav");
        return 1;
 }
 float Button_mouseRelease(entity me, vector pos)
 {
+       if(cvar("menu_sounds"))
+               localsound("sound/misc/menu2.wav");
        me.mouseDrag(me, pos); // verify coordinates
        if(me.pressed)
        {
@@ -88,7 +89,12 @@ void Button_showNotify(entity me)
 {
        me.focusable = !me.disabled;
 }
-.float playedfocus;
+void Button_focusEnter(entity me)
+{
+       if(cvar("menu_sounds") > 1)
+               localsound("sound/misc/menu1.wav");
+       SUPER(Button).focusEnter(me);
+}
 void Button_draw(entity me)
 {
        vector bOrigin, bSize;
@@ -159,14 +165,5 @@ void Button_draw(entity me)
                        me.onClick(me, me.onClickEntity);
        }
        me.clickTime -= frametime;
-
-       if(cvar("menu_sounds") > 1)
-               if(me.focused && !me.playedfocus)
-               {
-                       localsound("sound/misc/menu1.wav");
-                       me.playedfocus = 1;
-               }
-               else if(!me.focused && me.playedfocus)
-                       me.playedfocus = 0;
 }
 #endif
index 9a8a35fdcbc699d03ba12742342bb45f0e7fe0f4..927e07f67423b67f77a470b46621bdb81e05da20 100644 (file)
@@ -10,6 +10,7 @@ CLASS(Slider) EXTENDS(Label)
        METHOD(Slider, mousePress, float(entity, vector))
        METHOD(Slider, mouseDrag, float(entity, vector))
        METHOD(Slider, mouseRelease, float(entity, vector))
+       METHOD(Slider, focusEnter, void(entity))
        METHOD(Slider, valueToText, string(entity, float))
        METHOD(Slider, toString, string(entity))
        METHOD(Slider, setValue, void(entity, float))
@@ -235,12 +236,12 @@ float Slider_mousePress(entity me, vector pos)
                        //me.mouseDrag(me, pos);
                }
        }
-       if(cvar("menu_sounds"))
-               localsound("sound/misc/menu2.wav");
        return 1;
 }
 float Slider_mouseRelease(entity me, vector pos)
 {
+       if(cvar("menu_sounds"))
+               localsound("sound/misc/menu2.wav");
        me.pressed = 0;
        if(me.disabled)
                return 0;
@@ -250,6 +251,12 @@ void Slider_showNotify(entity me)
 {
        me.focusable = !me.disabled;
 }
+void Slider_focusEnter(entity me)
+{
+       if(cvar("menu_sounds") > 1)
+               localsound("sound/misc/menu1.wav");
+       SUPER(Slider).focusEnter(me);
+}
 void Slider_draw(entity me)
 {
        float controlLeft;
index fe9f860c314a3c93592c9e191626fb1cc70554d8..ee451744fb8899942380f76248d7ff8bfa638f51 100644 (file)
@@ -57,6 +57,8 @@ void XonoticServerListTab_fill(entity me)
                me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null));
                        e.onEnter = ServerList_Connect_Click;
                        e.onEnterEntity = slist;
+                       e.onChange = ServerList_Update_favoriteButton;
+                       e.onChangeEntity = slist;
                        slist.ipAddressBox = e;
                me.TD(me, 1, 1.5, e = makeXonoticButton("", '0 0 0'));
                        e.onClick = ServerList_Favorite_Click;
index fe47fe50f662c7c9c256a965166785702039f4f3..2b7b9a38464ab62cfe8c4285a6464ee2e3ceec6f 100644 (file)
@@ -136,13 +136,13 @@ void XonoticPlayerSettingsTab_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair color:"));
-               me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "crosshair_color_per_weapon", _("Per weapon")));
-               me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "crosshair_color_by_health", _("By health")));
-               setDependent(e, "crosshair_color_per_weapon", 0, 0);
+               me.TD(me, 1, 0.9, e = makeXonoticRadioButton(4, "crosshair_color_per_weapon", string_null, _("Per weapon")));
+               me.TD(me, 1, 0.9, e = makeXonoticRadioButton(4, "crosshair_color_by_health", string_null, _("By health")));
        me.TR(me);
-               me.TDempty(me, 0.4);
-               me.TD(me, 2, 2.6, e = makeXonoticColorpickerString("crosshair_color", "crosshair_color"));
-               setDependentAND(e, "crosshair_color_per_weapon", 0, 0, "crosshair_color_by_health", 0, 0);
+               me.TDempty(me, 0.3);
+               me.TD(me, 1, 0.9, e = makeXonoticRadioButton(4, string_null, string_null, _("Custom")));
+               me.TD(me, 2, 1.8, e = makeXonoticColorpickerString("crosshair_color", "crosshair_color"));
+                       setDependentAND(e, "crosshair_color_per_weapon", 0, 0, "crosshair_color_by_health", 0, 0);
        me.TR(me);
        me.TR(me);
                me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_dot", _("Enable center dot")));
@@ -164,14 +164,11 @@ void XonoticPlayerSettingsTab_fill(entity me)
                me.TD(me, 1, 2.2, e = makeXonoticButton(_("Waypoints setup..."), '0 0 0'));
                        e.onClick = DialogOpenButton_Click;
                        e.onClickEntity = main.waypointDialog;
-               me.TDempty(me, 0.5);
        me.TR(me);
                me.TDempty(me, 0.4);
                me.TD(me, 1, 2.2, e = makeXonoticButton(_("Enter HUD editor"), '0 0 0'));
                        e.onClick = HUDSetup_Join_Click;
                        e.onClickEntity = me;
-               me.TDempty(me, 0.5);
-       me.TR(me);
        me.TR(me);
        #ifdef ALLOW_FORCEMODELS
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Force models:")));
index a3d747dabb9b2a1a3a26db9145b2785e82ae9bc3..0e4760e3ff3522af46781e235cc1a8cbfdcd1190 100644 (file)
@@ -63,6 +63,7 @@ void ServerList_ShowFull_Click(entity box, entity me);
 void ServerList_Filter_Change(entity box, entity me);
 void ServerList_Favorite_Click(entity btn, entity me);
 void ServerList_Info_Click(entity btn, entity me);
+void ServerList_Update_favoriteButton(entity btn, entity me);
 #endif
 
 #ifdef IMPLEMENTATION
@@ -178,6 +179,14 @@ void ToggleFavorite(string srv)
        resorthostcache();
 }
 
+void ServerList_Update_favoriteButton(entity btn, entity me)
+{
+       if(IsFavorite(me.ipAddressBox.text))
+               me.favoriteButton.setText(me.favoriteButton, _("Remove"));
+       else
+               me.favoriteButton.setText(me.favoriteButton, _("Bookmark"));
+}
+
 entity makeXonoticServerList()
 {
        entity me;
@@ -356,12 +365,7 @@ void XonoticServerList_draw(entity me)
        if(me.ipAddressBoxFocused != me.ipAddressBox.focused)
        {
                if(me.ipAddressBox.focused || me.ipAddressBoxFocused < 0)
-               {
-                       if(IsFavorite(me.ipAddressBox.text))
-                               me.favoriteButton.setText(me.favoriteButton, _("Remove"));
-                       else
-                               me.favoriteButton.setText(me.favoriteButton, _("Bookmark"));
-               }
+                       ServerList_Update_favoriteButton(NULL, me);
                me.ipAddressBoxFocused = me.ipAddressBox.focused;
        }
 
index ee961d6664d06cd8cd84b6892d18fb446fb40fe4..d008f15d9530d5abf8f45375dae48eafd48ce9fc 100644 (file)
@@ -84,8 +84,6 @@ float maxclients;
 .vector        pos1, pos2;
 .vector        mangle;
 
-.float cvar_cl_hitsound;
-
 .float pain_finished;                  //Added by Supajoe
 .float pain_frame;                     //"
 .float statdraintime;                  // record the one-second intervals between draining health and armour when they're over 100
@@ -402,10 +400,6 @@ float assault_attacker_team;
 .float speedrunning;
 
 // Q3 support
-.float notteam;
-.float notsingle;
-.float notfree;
-.float notq3a;
 float q3acompat_machineshotgunswap;
 
 // database
index 51c98ec46274982be1335595a14fdcf58718d0ee..374f17c7bbe3d334f27f2e83c3a99dda6a4e24f7 100644 (file)
@@ -2844,14 +2844,14 @@ void EndFrame()
                {
                        if(self.enemy.typehitsound)
                                self.typehit_time = time;
-                       else if(self.enemy.hitsound && self.cvar_cl_hitsound)
+                       else if(self.enemy.hitsound)
                                self.hit_time = time;
                }
                else
                {
                        if(self.typehitsound)
                                self.typehit_time = time;
-                       else if(self.hitsound && self.cvar_cl_hitsound)
+                       else if(self.hitsound)
                                self.hit_time = time;
                }
        }
index c04c477cdf778cc0b32be50b5e628999342ad3f4..364c925991a893ccb2a75749cb57d9bd8a573104 100644 (file)
@@ -603,7 +603,6 @@ void GetCvars(float f)
        GetCvars_handleFloat(s, f, cvar_cl_noantilag, "cl_noantilag");
        GetCvars_handleFloat(s, f, cvar_cl_voice_directional, "cl_voice_directional");
        GetCvars_handleFloat(s, f, cvar_cl_voice_directional_taunt_attenuation, "cl_voice_directional_taunt_attenuation");
-       GetCvars_handleFloat(s, f, cvar_cl_hitsound, "cl_hitsound");
        GetCvars_handleFloat(s, f, cvar_cl_accuracy_data_share, "cl_accuracy_data_share");
        GetCvars_handleFloat(s, f, cvar_cl_accuracy_data_receive, "cl_accuracy_data_receive");
 
index a40e8144d6656904d11f7843bcc4d81e7b68431d..68a86e9c479e7f68a9908fc12230831f2bb50803 100644 (file)
@@ -232,6 +232,7 @@ void StartFrame (void)
 .float anglejitter;
 .string gametypefilter;
 .string cvarfilter;
+float DoesQ3ARemoveThisEntity();
 void SV_OnEntityPreSpawnFunction()
 {
        if(self.gametypefilter != "")
@@ -350,6 +351,12 @@ void SV_OnEntityPreSpawnFunction()
                }
        }
 
+       if(DoesQ3ARemoveThisEntity())
+       {
+               remove(self);
+               return;
+       }
+
        // support special -1 and -2 angle from radiant
        if (self.angles == '0 -1 0')
                self.angles = '-90 0 0';
index 143b3be4879d79cc2993a685f275e0a1cc2e0bee..5cd714b652a64f832e7c03633e40567596f6111f 100644 (file)
@@ -735,36 +735,6 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                        waypoint_spawnforitem(self);
                }
 
-               if(teams_matter)
-               {
-                       if(self.notteam)
-                       {
-                               print("removed non-teamplay ", self.classname, "\n");
-                               startitem_failed = TRUE;
-                               remove (self);
-                               return;
-                       }
-               }
-               else
-               {
-                       if(self.notfree)
-                       {
-                               print("removed non-FFA ", self.classname, "\n");
-                               startitem_failed = TRUE;
-                               remove (self);
-                               return;
-                       }
-               }
-
-               if(self.notq3a)
-               {
-                       // We aren't TA or something like that, so we keep the Q3A entities
-                       print("removed non-Q3A ", self.classname, "\n");
-                       startitem_failed = TRUE;
-                       remove (self);
-                       return;
-               }
-
                /*
                 * can't do it that way, as it would break maps
                 * TODO make a target_give like entity another way, that perhaps has
index 11bf880e60bf102b1d992c25698e8ff471973fbd..8cc7e479791b6a3fc8bec91c48383355953f2563 100644 (file)
@@ -130,3 +130,54 @@ void spawnfunc_team_CTF_redspawn()   { spawnfunc_info_player_team1();  }
 void spawnfunc_team_CTF_bluespawn()  { spawnfunc_info_player_team2();  }
 
 void spawnfunc_item_flight()         { spawnfunc_item_jetpack();       }
+
+.float notteam;
+.float notsingle;
+.float notfree;
+.float notq3a;
+.float notta;
+.string gametype;
+float DoesQ3ARemoveThisEntity()
+{
+       // Q3 style filters (DO NOT USE, THIS IS COMPAT ONLY)
+
+       if(self.notq3a)
+               if(!teams_matter || g_tdm || g_ctf)
+                       return 1;
+
+       if(self.notta)
+               if not(!teams_matter || g_tdm || g_ctf)
+                       return 1;
+
+       if(self.notsingle)
+               if(maxclients == 1)
+                       return 1;
+
+       if(self.notteam)
+               if(teams_matter)
+                       return 1;
+
+       if(self.notfree)
+               if(!teams_matter)
+                       return 1;
+
+       if(self.gametype)
+       {
+               string gametypename;
+               // static char *gametypeNames[] = {"ffa", "tournament", "single", "team", "ctf", "oneflag", "obelisk", "harvester", "teamtournament"};
+               gametypename = "ffa";
+               if(teams_matter)
+                       gametypename = "team";
+               if(g_arena)
+                       gametypename = "tournament";
+               if(g_ctf)
+                       gametypename = "ctf";
+               if(maxclients == 1)
+                       gametypename = "single";
+               // we do not have the other types (oneflag, obelisk, harvester, teamtournament)
+               if(strstrofs(self.gametype, gametypename, 0) < 0)
+                       return 1;
+       }
+
+       return 0;
+}
index a85fbab69b2c430a37a44b7c9bb3e6c885cf4e05..2c0f409ea23841e6dc4d41c39eda608da611b9cf 100644 (file)
--- a/quake.rc
+++ b/quake.rc
@@ -3,6 +3,7 @@ exec config.cfg
 maxplayers $menu_maxplayers
 exec data/campaign.cfg
 exec config_update.cfg
+exec font-xolonium.cfg
 exec autoexec.cfg
 stuffcmds
 //startdemos demos/demo1 demos/demo2 demos/demo3