]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/mainmenu.lua
30cff823e5b99a5335e13a12f32fac300b947d56
[dragonfireclient.git] / builtin / mainmenu.lua
1 os.setlocale("C", "numeric")
2
3 local scriptpath = engine.get_scriptdir()
4
5 dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
6 dofile(scriptpath .. DIR_DELIM .. "modstore.lua")
7 dofile(scriptpath .. DIR_DELIM .. "gamemgr.lua")
8
9 local menu = {}
10 local tabbuilder = {}
11 local menubar = {}
12
13 --------------------------------------------------------------------------------
14 function render_favourite(spec)
15         local text = ""
16         
17         if spec.name ~= nil then
18                 text = text .. spec.name:trim()
19                 
20                 if spec.description ~= nil then
21                         --TODO make sure there's no invalid chat in spec.description
22                         text = text .. " (" .. fs_escape_string(spec.description) .. ")"
23                 end
24         else
25                 if spec.address ~= nil then
26                         text = text .. spec.address:trim()
27                 end
28         end
29         
30         local details = ""
31         if spec.password == true then
32                 details = " *"
33         else
34                 details = "  "
35         end
36         
37         if spec.creative then
38                 details = details .. "C"
39         else
40                 details = details .. " "
41         end
42         
43         if spec.damage then
44                 details = details .. "D"
45         else
46                 details = details .. " "
47         end
48         
49         if spec.pvp then
50                 details = details .. "P"
51         else
52                 details = details .. " "
53         end
54         
55         if spec.port ~= nil then
56                 text = text .. ":" .. spec.port:trim()
57         else
58                 text = text .. ":??"
59         end
60         
61         return text
62 end
63
64 --------------------------------------------------------------------------------
65 os.tempfolder = function()
66         local filetocheck = os.tmpname()
67         os.remove(filetocheck)
68         
69         local randname = "MTTempModFolder_" .. math.random(0,10000)
70         if DIR_DELIM == "\\" then
71                 local tempfolder = os.getenv("TEMP")
72                 return tempfolder .. filetocheck
73         else
74                 local backstring = filetocheck:reverse()
75                 return filetocheck:sub(0,filetocheck:len()-backstring:find(DIR_DELIM)+1) ..randname
76         end
77
78 end
79
80 --------------------------------------------------------------------------------
81 function cleanup_path(temppath)
82         
83         local parts = temppath:split("-")
84         temppath = ""   
85         for i=1,#parts,1 do
86                 if temppath ~= "" then
87                         temppath = temppath .. "_"
88                 end
89                 temppath = temppath .. parts[i]
90         end
91         
92         parts = temppath:split(".")
93         temppath = ""   
94         for i=1,#parts,1 do
95                 if temppath ~= "" then
96                         temppath = temppath .. "_"
97                 end
98                 temppath = temppath .. parts[i]
99         end
100         
101         parts = temppath:split("'")
102         temppath = ""   
103         for i=1,#parts,1 do
104                 if temppath ~= "" then
105                         temppath = temppath .. ""
106                 end
107                 temppath = temppath .. parts[i]
108         end
109         
110         parts = temppath:split(" ")
111         temppath = ""   
112         for i=1,#parts,1 do
113                 if temppath ~= "" then
114                         temppath = temppath
115                 end
116                 temppath = temppath .. parts[i]
117         end
118         
119         return temppath
120 end
121
122 function menu.set_texture(identifier,gamedetails)
123         local texture_set = false
124         if menu.texturepack ~= nil then
125                 local path = menu.basetexturedir .. 
126                                                 gamedetails.id .. "_menu_" .. identifier .. ".png"
127                 
128                 if engine.set_background(identifier,path) then
129                         texture_set = true
130                 end
131         end
132         
133         if not texture_set then
134                 local path = gamedetails.path .. DIR_DELIM .."menu" .. 
135                                                                          DIR_DELIM .. identifier .. ".png"
136                 if engine.set_background(identifier,path) then
137                         texture_set = true
138                 end
139         end
140         
141         if not texture_set then
142                 local path = menu.basetexturedir .. DIR_DELIM .."menu_" .. 
143                                                                                 identifier .. ".png"
144                 if engine.set_background(identifier,path) then
145                         texture_set = true
146                 end
147         end
148         
149         if not texture_set then
150                 local path = menu.defaulttexturedir .. DIR_DELIM .."menu_" .. 
151                                                                                 identifier .. ".png"
152                 engine.set_background(identifier,path)
153         end
154 end
155
156 --------------------------------------------------------------------------------
157 function menu.update_gametype()
158         if (menu.game_last_check == nil or
159                 menu.game_last_check ~= menu.last_game) and
160                 tabbuilder.current_tab == "singleplayer" then
161                 
162                 local gamedetails = menu.lastgame()
163                 engine.set_topleft_text(gamedetails.name)
164                 
165                 --background
166                 local background_set = false
167                 if menu.texturepack ~= nil then
168                         local path_background_texture = menu.basetexturedir .. 
169                                                                                 gamedetails.id .. "_menu_background.png"
170                         
171                         if engine.set_background("background",path_background_texture) then
172                                 background_set = true
173                                 engine.set_clouds(false)
174                         end
175                 end
176                 
177                 if not background_set then
178                         local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" .. 
179                                                                                  DIR_DELIM .. "background.png"
180                         if engine.set_background("background",path_background_texture) then
181                                 background_set = true
182                                 engine.set_clouds(false)
183                         end
184                 end
185                 
186                 if not background_set then
187                         engine.set_clouds(true)
188                 end
189                 
190                 menu.set_texture("overlay",gamedetails)
191                 menu.set_texture("header",gamedetails)
192                 menu.set_texture("footer",gamedetails)
193                 
194                 menu.game_last_check = menu.last_game
195         else
196                 if menu.game_last_check ~= menu.last_game then
197                         menu.game_last_check = menu.last_game
198                         menu.reset_gametype()
199                 end
200         end
201 end
202
203 --------------------------------------------------------------------------------
204 function menu.reset_gametype()
205         menu.game_last_check = nil
206         engine.set_clouds(true)
207         engine.set_background("background","")
208         engine.set_background("overlay",menu.basetexturedir .. "menu_overlay.png")
209         engine.set_background("header",menu.basetexturedir .. "menu_header.png")
210         engine.set_background("footer",menu.basetexturedir .. "menu_footer.png")
211         engine.set_topleft_text("")
212 end
213
214 --------------------------------------------------------------------------------
215 function get_last_folder(text,count)
216         local parts = text:split(DIR_DELIM)
217         
218         if count == nil then
219                 return parts[#parts]
220         end
221         
222         local retval = ""
223         for i=1,count,1 do
224                 retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM
225         end
226         
227         return retval
228 end
229
230 --------------------------------------------------------------------------------
231 function init_globals()
232         --init gamedata
233         gamedata.worldindex = 0
234 end
235
236 --------------------------------------------------------------------------------
237 function identify_filetype(name)
238
239         if name:sub(-3):lower() == "zip" then
240                 return {
241                                 name = name,
242                                 type = "zip"
243                                 }
244         end
245         
246         if name:sub(-6):lower() == "tar.gz" or
247                 name:sub(-3):lower() == "tgz"then
248                 return {
249                                 name = name,
250                                 type = "tgz"
251                                 }
252         end
253         
254         if name:sub(-6):lower() == "tar.bz2" then
255                 return {
256                                 name = name,
257                                 type = "tbz"
258                                 }
259         end
260         
261         if name:sub(-2):lower() == "7z" then
262                 return {
263                                 name = name,
264                                 type = "7z"
265                                 }
266         end
267
268         return {
269                 name = name,
270                 type = "ukn"
271         }
272 end
273
274 --------------------------------------------------------------------------------
275 function update_menu()
276
277         local formspec = "size[12,5.2]"
278         
279         -- handle errors
280         if gamedata.errormessage ~= nil then
281                 formspec = formspec ..
282                         "field[1,2;10,2;;ERROR: " ..
283                         gamedata.errormessage .. 
284                         ";]"..
285                         "button[4.5,4.2;3,0.5;btn_error_confirm;Ok]"
286         else
287                 formspec = formspec .. tabbuilder.gettab()
288         end
289
290         engine.update_formspec(formspec)
291 end
292
293 --------------------------------------------------------------------------------
294 function menu.filtered_game_list()
295         local retval = ""
296
297         local current_game = menu.lastgame()
298         
299         for i=1,#menu.worldlist,1 do
300                 if menu.worldlist[i].gameid == current_game.id then
301                         if retval ~= "" then
302                                 retval = retval ..","
303                         end
304                         
305                         retval = retval .. menu.worldlist[i].name .. 
306                                                 " \\[" .. menu.worldlist[i].gameid .. "\\]"
307                 end
308         end
309         
310         return retval
311 end
312
313 --------------------------------------------------------------------------------
314 function menu.filtered_game_list_raw()
315         local retval =  {}
316
317         local current_game = menu.lastgame()
318         
319         for i=1,#menu.worldlist,1 do
320                 if menu.worldlist[i].gameid == current_game.id then
321                         table.insert(retval,menu.worldlist[i])
322                 end
323         end
324         
325         return retval
326 end
327
328 --------------------------------------------------------------------------------
329 function menu.filtered_index_to_plain(filtered_index)
330
331         local current_game = menu.lastgame()
332         
333         local temp_idx = 0
334         
335         if menu.worldlist == nil then
336                 return -1
337         end
338         
339         for i=1,#menu.worldlist,1 do
340                 if menu.worldlist[i].gameid == current_game.id then
341                         temp_idx = temp_idx +1
342                 end
343                 
344                 if temp_idx == filtered_index then
345                         return i
346                 end
347         end
348         return -1
349 end
350
351 --------------------------------------------------------------------------------
352 function menu.init()
353         --init menu data
354         gamemgr.update_gamelist()
355
356         menu.worldlist = engine.get_worlds()
357         
358         menu.last_world = tonumber(engine.setting_get("main_menu_last_world_idx"))
359         menu.last_game  = tonumber(engine.setting_get("main_menu_last_game_idx"))
360         
361         if type(menu.last_world) ~= "number" then
362                 menu.last_world = 1
363         end
364         
365         if type(menu.last_game) ~= "number" then
366                 menu.last_game = 1
367         end
368
369         if engine.setting_getbool("public_serverlist") then
370                 menu.favorites = engine.get_favorites("online")
371         else
372                 menu.favorites = engine.get_favorites("local")
373         end
374         
375         
376         menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
377                                                 DIR_DELIM .. "textures" .. DIR_DELIM .. "base" .. 
378                                                 DIR_DELIM .. "pack" .. DIR_DELIM
379         menu.basetexturedir = menu.defaulttexturedir
380         
381         menu.texturepack = engine.setting_get("texture_path")
382         
383         if menu.texturepack ~= nil then
384                 menu.basetexturedir = menu.texturepack .. DIR_DELIM
385         end
386 end
387
388 --------------------------------------------------------------------------------
389 function menu.lastgame()
390         if menu.last_game > 0 and menu.last_game <= #gamemgr.games then
391                 return gamemgr.games[menu.last_game]
392         end
393         
394         if #gamemgr.games >= 1 then
395                 menu.last_game = 1
396                 return gamemgr.games[menu.last_game]
397         end
398         
399         --error case!!
400         return nil
401 end
402
403 --------------------------------------------------------------------------------
404 function menu.lastworld()
405         if menu.last_world ~= nil and 
406                 menu.last_world > 0 and 
407                 menu.last_world <= #menu.worldlist then
408                 return menu.worldlist[menu.last_world]
409         end
410         
411         if #menu.worldlist >= 1 then
412                 menu.last_world = 1
413                 return menu.worldlist[menu.last_world]
414         end
415         
416         --error case!!
417         return nil
418 end
419
420 --------------------------------------------------------------------------------
421 function menu.update_last_game(world_idx)
422         if gamedata.selected_world <= #menu.worldlist then
423                 local world = menu.worldlist[gamedata.selected_world]
424                 
425                 if world == nil then
426                         return
427                 end
428                 
429                 for i=1,#gamemgr.games,1 do             
430                         if gamemgr.games[i].id == world.gameid then
431                                 menu.last_game = i
432                                 engine.setting_set("main_menu_last_game_idx",menu.last_game)
433                                 break
434                         end
435                 end
436         end
437 end
438
439 --------------------------------------------------------------------------------
440 function menubar.handle_buttons(fields)
441         for i=1,#menubar.buttons,1 do
442                 if fields[menubar.buttons[i].btn_name] ~= nil then
443                         menu.last_game = menubar.buttons[i].index
444                         engine.setting_set("main_menu_last_game_idx",menu.last_game)
445                         menu.update_gametype()
446                 end
447         end
448 end
449
450 --------------------------------------------------------------------------------
451 function menubar.refresh()
452         menubar.formspec = "box[-0.3,5.625;12.4,1.3;000000]" ..
453                                            "box[-0.3,5.6;12.4,0.05;FFFFFF]"
454         menubar.buttons = {}
455
456         local button_base = -0.25
457         
458         local maxbuttons = #gamemgr.games
459         
460         if maxbuttons > 10 then
461                 maxbuttons = 10
462         end
463         
464         for i=1,maxbuttons,1 do
465
466                 local btn_name = "menubar_btn_" .. gamemgr.games[i].id
467                 local buttonpos = button_base + (i-1) * 1.245
468                 if gamemgr.games[i].menuicon_path ~= nil and
469                         gamemgr.games[i].menuicon_path ~= "" then
470
471                         menubar.formspec = menubar.formspec ..
472                                 "image_button[" .. buttonpos ..  ",5.7;1.3,1.3;"  ..
473                                 gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
474                 else
475                 
476                         local part1 = gamemgr.games[i].id:sub(1,5)
477                         local part2 = gamemgr.games[i].id:sub(6,10)
478                         local part3 = gamemgr.games[i].id:sub(11)
479                         
480                         local text = part1 .. "\n" .. part2
481                         if part3 ~= nil and
482                                 part3 ~= "" then
483                                 text = text .. "\n" .. part3
484                         end
485                         menubar.formspec = menubar.formspec ..
486                                 "image_button[" .. buttonpos ..  ",5.7;1.3,1.3;;" ..btn_name ..
487                                 ";" .. text .. ";true;true]"
488                 end
489                 
490                 local toadd = {
491                         btn_name = btn_name,
492                         index = i,
493                 }
494                 
495                 table.insert(menubar.buttons,toadd)
496         end
497 end
498
499 --------------------------------------------------------------------------------
500 function tabbuilder.dialog_create_world()
501         local mapgens = {"v6", "v7", "indev", "singlenode", "math"}
502
503         local current_mg = engine.setting_get("mg_name")
504
505         local mglist = ""
506         local selindex = 1
507         local i = 1
508         for k,v in pairs(mapgens) do
509                 if current_mg == v then
510                         selindex = i
511                 end
512                 i = i + 1
513                 mglist = mglist .. v .. ","
514         end
515         mglist = mglist:sub(1, -2)
516
517         local retval = 
518                 "label[2,0;World name]"..
519                 "label[2,1;Mapgen]"..
520                 "field[4.5,0.4;6,0.5;te_world_name;;]" ..
521                 "label[2,2;Game]"..
522                 "button[5,4.5;2.6,0.5;world_create_confirm;Create]" ..
523                 "button[7.5,4.5;2.8,0.5;world_create_cancel;Cancel]" ..
524                 "dropdown[4.2,1;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
525                 "textlist[4.2,1.9;5.8,2.3;games;" ..
526                 gamemgr.gamelist() ..
527                 ";" .. menu.last_game .. ";true]"
528
529         return retval
530 end
531
532 --------------------------------------------------------------------------------
533 function tabbuilder.dialog_delete_world()
534         return  "label[2,2;Delete World \"" .. menu.lastworld().name .. "\"?]"..
535                         "button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" ..
536                         "button[6,4.2;2.8,0.5;world_delete_cancel;No]"
537 end
538
539 --------------------------------------------------------------------------------
540 function tabbuilder.gettab()
541         local retval = ""
542         
543         if tabbuilder.show_buttons then
544                 retval = retval .. tabbuilder.tab_header()
545         end
546
547         if tabbuilder.current_tab == "singleplayer" then
548                 retval = retval .. tabbuilder.tab_singleplayer()
549         end
550         
551         if tabbuilder.current_tab == "multiplayer" then
552                 retval = retval .. tabbuilder.tab_multiplayer()
553         end
554
555         if tabbuilder.current_tab == "server" then
556                 retval = retval .. tabbuilder.tab_server()
557         end
558         
559         if tabbuilder.current_tab == "settings" then
560                 retval = retval .. tabbuilder.tab_settings()
561         end
562         
563         if tabbuilder.current_tab == "credits" then
564                 retval = retval .. tabbuilder.tab_credits()
565         end
566         
567         if tabbuilder.current_tab == "dialog_create_world" then
568                 retval = retval .. tabbuilder.dialog_create_world()
569         end
570         
571         if tabbuilder.current_tab == "dialog_delete_world" then
572                 retval = retval .. tabbuilder.dialog_delete_world()
573         end
574         
575         retval = retval .. modmgr.gettab(tabbuilder.current_tab)
576         retval = retval .. gamemgr.gettab(tabbuilder.current_tab)
577         retval = retval .. modstore.gettab(tabbuilder.current_tab)
578
579         return retval
580 end
581
582 --------------------------------------------------------------------------------
583 function tabbuilder.handle_create_world_buttons(fields)
584         
585         if fields["world_create_confirm"] or
586                 fields["key_enter"] then
587                 
588                 local worldname = fields["te_world_name"]
589                 local gameindex = engine.get_textlist_index("games")
590                 
591                 if gameindex > 0 and
592                         worldname ~= "" then
593                         menu.worldlist = engine.get_worlds()
594                         
595                         local found = false
596                         for i=1,#menu.worldlist,1 do
597                                 if menu.worldlist[i].name == worldname then
598                                         found = true
599                                         break
600                                 end
601                         end
602                         
603                         local message = nil
604                         
605                         if not found then
606                                 engine.setting_set("mg_name",fields["dd_mapgen"])
607                                 message = engine.create_world(worldname,gameindex)
608                         else
609                                 message = "A world named \"" .. worldname .. "\" already exists"
610                         end
611                         
612                         if message ~= nil then
613                                 gamedata.errormessage = message
614                         else
615                                 menu.last_game = gameindex
616                                 engine.setting_set("main_menu_last_game_idx",gameindex)
617                                 menu.worldlist = engine.get_worlds()
618                                 
619                                 local worldlist = menu.worldlist
620                                 
621                                 if tabbuilder.current_tab == "singleplayer" then
622                                         worldlist = menu.filtered_game_list_raw()
623                                 end
624                                 
625                                 local index = 0
626                                 
627                                 for i=1,#worldlist,1 do
628                                         if worldlist[i].name == worldname then
629                                                 index = i
630                                                 break
631                                         end
632                                 end
633
634                                 engine.setting_set("main_menu_singleplayer_world_idx", index)
635                                 menu.last_world = index
636                         end
637                 else
638                         gamedata.errormessage = "No worldname given or no game selected"
639                 end
640         end
641         
642         if fields["games"] then
643                 tabbuilder.skipformupdate = true
644                 return
645         end
646         
647         tabbuilder.is_dialog = false
648         tabbuilder.show_buttons = true
649         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
650 end
651
652 --------------------------------------------------------------------------------
653 function tabbuilder.handle_delete_world_buttons(fields)
654         
655         if fields["world_delete_confirm"] then
656                 if menu.last_world > 0 and 
657                         menu.last_world <= #menu.worldlist then
658                         engine.delete_world(menu.last_world)
659                         menu.worldlist = engine.get_worlds()
660                         menu.last_world = 1
661                 end
662         end
663         
664         tabbuilder.is_dialog = false
665         tabbuilder.show_buttons = true
666         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
667 end
668
669 --------------------------------------------------------------------------------
670 function tabbuilder.handle_multiplayer_buttons(fields)
671         
672         if fields["te_name"] ~= nil then
673                 gamedata.playername = fields["te_name"]
674                 engine.setting_set("name", fields["te_name"])
675         end
676         
677         if fields["favourites"] ~= nil then
678                 local event = explode_textlist_event(fields["favourites"])
679                 if event.typ == "DCL" then
680                         --gamedata.address = menu.favorites[event.index].name
681                         if gamedata.address == nil then
682                                 gamedata.address = menu.favorites[event.index].address
683                         end
684                         gamedata.port = menu.favorites[event.index].port
685                         gamedata.playername             = fields["te_name"]
686                         if fields["te_pwd"] ~= nil then
687                                 gamedata.password               = fields["te_pwd"]
688                         end
689                         gamedata.selected_world = 0
690                         
691                         if gamedata.address ~= nil and
692                                 gamedata.port ~= nil then
693                                 
694                                 engine.start()
695                         end
696                 end
697                 
698                 if event.typ == "CHG" then
699                         local address = menu.favorites[event.index].name
700                         if address == nil then
701                                 address = menu.favorites[event.index].address
702                         end
703                         local port = menu.favorites[event.index].port
704                         
705                         if address ~= nil and
706                                 port ~= nil then
707                                 engine.setting_set("address",address)
708                                 engine.setting_set("port",port)
709                         end
710                         
711                         menu.fav_selected = event.index
712                 end
713                 return
714         end
715         
716         if fields["key_up"] ~= nil or
717                 fields["key_down"] ~= nil then
718                 
719                 local fav_idx = engine.get_textlist_index("favourites")
720                 
721                 if fields["key_up"] ~= nil and fav_idx > 1 then
722                         fav_idx = fav_idx -1
723                 else if fields["key_down"] and fav_idx < #menu.favorites then
724                         fav_idx = fav_idx +1
725                 end end
726                 
727                 local address = menu.favorites[fav_idx].name
728                 if address == nil then
729                         address = menu.favorites[fav_idx].address
730                 end
731                 local port = menu.favorites[fav_idx].port
732                 
733                 if address ~= nil and
734                         port ~= nil then
735                         engine.setting_set("address",address)
736                         engine.setting_set("port",port)
737                 end
738                 
739                 menu.fav_selected = fav_idx
740                 return
741         end
742         
743         if fields["cb_public_serverlist"] ~= nil then
744                 engine.setting_setbool("public_serverlist",
745                         tabbuilder.tobool(fields["cb_public_serverlist"]))
746                         
747                 if engine.setting_getbool("public_serverlist") then
748                         menu.favorites = engine.get_favorites("online")
749                 else
750                         menu.favorites = engine.get_favorites("local")
751                 end
752                 
753                 return
754         end
755
756         if fields["btn_delete_favorite"] ~= nil then
757                 local current_favourite = engine.get_textlist_index("favourites")
758                 engine.delete_favorite(current_favourite)
759                 menu.favorites = engine.get_favorites()
760                 
761                 engine.setting_set("address","")
762                 engine.setting_get("port","")
763                 
764                 return
765         end
766
767         if fields["btn_mp_connect"] ~= nil or
768                 fields["key_enter"] then
769                 
770                 gamedata.playername             = fields["te_name"]
771                 gamedata.password               = fields["te_pwd"]
772                 gamedata.address                = fields["te_address"]
773                 gamedata.port                   = fields["te_port"]
774                 gamedata.selected_world = 0
775                 
776                 engine.start()
777                 return
778         end
779 end
780
781 --------------------------------------------------------------------------------
782 function tabbuilder.handle_server_buttons(fields)
783
784         local world_doubleclick = false
785
786         if fields["srv_worlds"] ~= nil then
787                 local event = explode_textlist_event(fields["srv_worlds"])
788                 
789                 if event.typ == "DCL" then
790                         world_doubleclick = true
791                 end
792                 if event.typ == "CHG" then
793                         engine.setting_set("main_menu_last_world_idx",engine.get_textlist_index("srv_worlds"))
794                 end
795         end
796         
797                 if fields["key_up"] then
798                 local oldidx = engine.get_textlist_index("srv_worlds")
799                 
800                 if oldidx > 1 then
801                         local newidx = oldidx -1
802                         engine.setting_set("main_menu_last_world_idx",newidx)
803                 end
804         end
805         
806         if fields["key_down"] then
807                 local oldidx = engine.get_textlist_index("srv_worlds")
808                 
809                 if oldidx < #menu.worldlist then
810                         local newidx = oldidx + 1
811                         engine.setting_set("main_menu_last_world_idx",newidx)
812                 end
813         end
814         
815         if fields["cb_creative_mode"] then
816                 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
817         end
818         
819         if fields["cb_enable_damage"] then
820                 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
821         end
822         
823         
824         if fields["start_server"] ~= nil or
825                 world_doubleclick or
826                 fields["key_enter"] then
827                 local selected = engine.get_textlist_index("srv_worlds")
828                 if selected > 0 then
829                         
830                         gamedata.playername             = fields["te_playername"]
831                         gamedata.password               = fields["te_passwd"]
832                         gamedata.port                   = fields["te_serverport"]
833                         gamedata.address                = ""
834                         gamedata.selected_world = selected
835                         
836                         engine.setting_set("main_menu_tab",tabbuilder.current_tab)
837                         engine.setting_set("main_menu_last_world_idx",gamedata.selected_world)
838                         
839                         menu.update_last_game(gamedata.selected_world)
840                         engine.start()
841                 end
842         end
843         
844         if fields["world_create"] ~= nil then
845                 tabbuilder.current_tab = "dialog_create_world"
846                 tabbuilder.is_dialog = true
847                 tabbuilder.show_buttons = false
848         end
849         
850         if fields["world_delete"] ~= nil then
851                 local selected = engine.get_textlist_index("srv_worlds")
852                 if selected > 0 then
853                         menu.last_world = engine.get_textlist_index("srv_worlds")
854                         if menu.lastworld() ~= nil and
855                                 menu.lastworld().name ~= nil and
856                                 menu.lastworld().name ~= "" then
857                                 tabbuilder.current_tab = "dialog_delete_world"
858                                 tabbuilder.is_dialog = true
859                                 tabbuilder.show_buttons = false
860                         else
861                                 menu.last_world = 0
862                         end
863                 end
864         end
865         
866         if fields["world_configure"] ~= nil then
867                 selected = engine.get_textlist_index("srv_worlds")
868                 if selected > 0 then
869                         modmgr.world_config_selected_world = selected
870                         if modmgr.init_worldconfig() then
871                                 tabbuilder.current_tab = "dialog_configure_world"
872                                 tabbuilder.is_dialog = true
873                                 tabbuilder.show_buttons = false
874                         end
875                 end
876         end
877 end
878
879 --------------------------------------------------------------------------------
880 function tabbuilder.tobool(text)
881         if text == "true" then
882                 return true
883         else
884                 return false
885         end
886 end
887
888 --------------------------------------------------------------------------------
889 function tabbuilder.handle_settings_buttons(fields)
890         if fields["cb_fancy_trees"] then
891                 engine.setting_setbool("new_style_leaves",tabbuilder.tobool(fields["cb_fancy_trees"]))
892         end
893                 
894         if fields["cb_smooth_lighting"] then
895                 engine.setting_setbool("smooth_lighting",tabbuilder.tobool(fields["cb_smooth_lighting"]))
896         end
897         if fields["cb_3d_clouds"] then
898                 engine.setting_setbool("enable_3d_clouds",tabbuilder.tobool(fields["cb_3d_clouds"]))
899         end
900         if fields["cb_opaque_water"] then
901                 engine.setting_setbool("opaque_water",tabbuilder.tobool(fields["cb_opaque_water"]))
902         end
903                         
904         if fields["cb_mipmapping"] then
905                 engine.setting_setbool("mip_map",tabbuilder.tobool(fields["cb_mipmapping"]))
906         end
907         if fields["cb_anisotrophic"] then
908                 engine.setting_setbool("anisotropic_filter",tabbuilder.tobool(fields["cb_anisotrophic"]))
909         end
910         if fields["cb_bilinear"] then
911                 engine.setting_setbool("bilinear_filter",tabbuilder.tobool(fields["cb_bilinear"]))
912         end
913         if fields["cb_trilinear"] then
914                 engine.setting_setbool("trilinear_filter",tabbuilder.tobool(fields["cb_trilinear"]))
915         end
916                         
917         if fields["cb_shaders"] then
918                 engine.setting_setbool("enable_shaders",tabbuilder.tobool(fields["cb_shaders"]))
919         end
920         if fields["cb_pre_ivis"] then
921                 engine.setting_setbool("preload_item_visuals",tabbuilder.tobool(fields["cb_pre_ivis"]))
922         end
923         if fields["cb_particles"] then
924                 engine.setting_setbool("enable_particles",tabbuilder.tobool(fields["cb_particles"]))
925         end
926         if fields["cb_finite_liquid"] then
927                 engine.setting_setbool("liquid_finite",tabbuilder.tobool(fields["cb_finite_liquid"]))
928         end
929
930         if fields["btn_change_keys"] ~= nil then
931                 engine.show_keys_menu()
932         end
933 end
934
935 --------------------------------------------------------------------------------
936 function tabbuilder.handle_singleplayer_buttons(fields)
937
938         local world_doubleclick = false
939
940         if fields["sp_worlds"] ~= nil then
941                 local event = explode_textlist_event(fields["sp_worlds"])
942                 
943                 if event.typ == "DCL" then
944                         world_doubleclick = true
945                 end
946                 
947                 if event.typ == "CHG" then
948                         engine.setting_set("main_menu_singleplayer_world_idx",engine.get_textlist_index("sp_worlds"))
949                 end
950         end
951         
952         if fields["key_up"] then
953                 local oldidx = engine.get_textlist_index("sp_worlds")
954                 
955                 if oldidx > 1 then
956                         local newidx = oldidx -1
957                         engine.setting_set("main_menu_singleplayer_world_idx",newidx)
958                 end
959         end
960         
961         if fields["key_down"] then
962                 local oldidx = engine.get_textlist_index("sp_worlds")
963                 
964                 if oldidx < #menu.filtered_game_list_raw() then
965                         local newidx = oldidx + 1
966                         engine.setting_set("main_menu_singleplayer_world_idx",newidx)
967                 end
968         end
969         
970         if fields["cb_creative_mode"] then
971                 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
972         end
973         
974         if fields["cb_enable_damage"] then
975                 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
976         end
977
978         if fields["play"] ~= nil or
979                 world_doubleclick or
980                 fields["key_enter"] then
981                 local selected = engine.get_textlist_index("sp_worlds")
982                 if selected > 0 then
983                         gamedata.selected_world = menu.filtered_index_to_plain(selected)
984                         gamedata.singleplayer   = true
985
986                         engine.setting_set("main_menu_tab",tabbuilder.current_tab)
987                         engine.setting_set("main_menu_singleplayer_world_idx",selected)
988                         
989                         menu.update_last_game(gamedata.selected_world)
990                         
991                         engine.start()
992                 end
993         end
994         
995         if fields["world_create"] ~= nil then
996                 tabbuilder.current_tab = "dialog_create_world"
997                 tabbuilder.is_dialog = true
998                 tabbuilder.show_buttons = false
999         end
1000         
1001         if fields["world_delete"] ~= nil then
1002                 local selected = engine.get_textlist_index("sp_worlds")
1003                 if selected > 0 then
1004                         menu.last_world = menu.filtered_index_to_plain(selected)
1005                         if menu.lastworld() ~= nil and
1006                                 menu.lastworld().name ~= nil and
1007                                 menu.lastworld().name ~= "" then
1008                                 tabbuilder.current_tab = "dialog_delete_world"
1009                                 tabbuilder.is_dialog = true
1010                                 tabbuilder.show_buttons = false
1011                         else
1012                                 menu.last_world = 0
1013                         end
1014                 end
1015         end
1016         
1017         if fields["world_configure"] ~= nil then
1018                 selected = engine.get_textlist_index("sp_worlds")
1019                 if selected > 0 then
1020                         modmgr.world_config_selected_world = menu.filtered_index_to_plain(selected)
1021                         if modmgr.init_worldconfig() then
1022                                 tabbuilder.current_tab = "dialog_configure_world"
1023                                 tabbuilder.is_dialog = true
1024                                 tabbuilder.show_buttons = false
1025                         end
1026                 end
1027         end
1028 end
1029
1030 --------------------------------------------------------------------------------
1031 function tabbuilder.tab_header()
1032
1033         if tabbuilder.last_tab_index == nil then
1034                 tabbuilder.last_tab_index = 1
1035         end
1036         
1037         local toadd = ""
1038         
1039         for i=1,#tabbuilder.current_buttons,1 do
1040                 
1041                 if toadd ~= "" then
1042                         toadd = toadd .. ","
1043                 end
1044                 
1045                 toadd = toadd .. tabbuilder.current_buttons[i].caption
1046         end
1047         return "tabheader[-0.3,-0.99;main_tab;" .. toadd ..";" .. tabbuilder.last_tab_index .. ";true;false]"
1048 end
1049
1050 --------------------------------------------------------------------------------
1051 function tabbuilder.handle_tab_buttons(fields)
1052
1053         if fields["main_tab"] then
1054                 local index = tonumber(fields["main_tab"])
1055                 tabbuilder.last_tab_index = index
1056                 tabbuilder.current_tab = tabbuilder.current_buttons[index].name
1057                 
1058                 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1059         end
1060         
1061         --handle tab changes
1062         if tabbuilder.current_tab ~= tabbuilder.old_tab then
1063                 if tabbuilder.current_tab ~= "singleplayer" then
1064                         menu.reset_gametype()
1065                 end
1066         end
1067         
1068         if tabbuilder.current_tab == "singleplayer" then
1069                 menu.update_gametype()
1070         end
1071         
1072         tabbuilder.old_tab = tabbuilder.current_tab
1073 end
1074
1075 --------------------------------------------------------------------------------
1076 function tabbuilder.init()
1077         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1078         
1079         if tabbuilder.current_tab == nil or
1080                 tabbuilder.current_tab == "" then
1081                 tabbuilder.current_tab = "singleplayer"
1082                 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1083         end
1084         
1085         
1086         --initialize tab buttons
1087         tabbuilder.last_tab = nil
1088         tabbuilder.show_buttons = true
1089         
1090         tabbuilder.current_buttons = {}
1091         table.insert(tabbuilder.current_buttons,{name="singleplayer", caption="Singleplayer"})
1092         table.insert(tabbuilder.current_buttons,{name="multiplayer", caption="Client"})
1093         table.insert(tabbuilder.current_buttons,{name="server", caption="Server"})
1094         table.insert(tabbuilder.current_buttons,{name="settings", caption="Settings"})
1095         
1096         if engine.setting_getbool("main_menu_game_mgr") then
1097                 table.insert(tabbuilder.current_buttons,{name="game_mgr", caption="Games"})
1098         end
1099         
1100         if engine.setting_getbool("main_menu_mod_mgr") then
1101                 table.insert(tabbuilder.current_buttons,{name="mod_mgr", caption="Mods"})
1102         end
1103         table.insert(tabbuilder.current_buttons,{name="credits", caption="Credits"})
1104         
1105         
1106         for i=1,#tabbuilder.current_buttons,1 do
1107                 if tabbuilder.current_buttons[i].name == tabbuilder.current_tab then
1108                         tabbuilder.last_tab_index = i
1109                 end
1110         end
1111         
1112         menu.update_gametype()
1113 end
1114
1115 --------------------------------------------------------------------------------
1116 function tabbuilder.tab_multiplayer()
1117
1118         local retval =
1119                 "vertlabel[0,-0.25;CLIENT]" ..
1120                 "label[1,-0.25;Favorites:]"..
1121                 "label[1,4.25;Address/Port]"..
1122                 "label[9,0;Name/Password]" ..
1123                 "field[1.25,5.25;5.5,0.5;te_address;;" ..engine.setting_get("address") .."]" ..
1124                 "field[6.75,5.25;2.25,0.5;te_port;;" ..engine.setting_get("port") .."]" ..
1125                 "button[6.45,3.95;2.25,0.5;btn_delete_favorite;Delete]" ..
1126                 "button[9,4.95;2.5,0.5;btn_mp_connect;Connect]" ..
1127                 "field[9.25,1;2.5,0.5;te_name;;" ..engine.setting_get("name") .."]" ..
1128                 "pwdfield[9.25,1.75;2.5,0.5;te_pwd;]" ..
1129                 "checkbox[1,3.6;cb_public_serverlist;Public Serverlist;" ..
1130                 dump(engine.setting_getbool("public_serverlist")) .. "]" ..
1131                 "textlist[1,0.35;7.5,3.35;favourites;"
1132
1133         if #menu.favorites > 0 then
1134                 retval = retval .. render_favourite(menu.favorites[1])
1135                 
1136                 for i=2,#menu.favorites,1 do
1137                         retval = retval .. "," .. render_favourite(menu.favorites[i])
1138                 end
1139         end
1140         
1141         print("cfav: " .. dump(menu.fav_selected))
1142         if menu.fav_selected ~= nil then
1143                 retval = retval .. ";" .. menu.fav_selected .. "]"
1144         else
1145                 retval = retval .. ";0]"
1146         end
1147
1148         return retval
1149 end
1150
1151 --------------------------------------------------------------------------------
1152 function tabbuilder.tab_server()
1153         local index = engine.setting_get("main_menu_last_world_idx")
1154         
1155         if index == nil then
1156                 index = 0
1157         end
1158         
1159         local retval = 
1160                 "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1161                 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1162                 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1163                 "button[8.5,4.9;3.25,0.5;start_server;Start Game]" ..
1164                 "label[4,-0.25;Select World:]"..
1165                 "vertlabel[0,-0.25;START SERVER]" ..
1166                 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1167                 dump(engine.setting_getbool("creative_mode")) .. "]"..
1168                 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1169                 dump(engine.setting_getbool("enable_damage")) .. "]"..
1170                 "field[0.8,2.2;3,0.5;te_playername;Name;" ..
1171                 engine.setting_get("name") .. "]" ..
1172                 "pwdfield[0.8,3.2;3,0.5;te_passwd;Password]" ..
1173                 "field[0.8,5.2;3,0.5;te_serverport;Server Port;30000]" ..
1174                 "textlist[4,0.25;7.5,3.7;srv_worlds;"
1175         
1176         if #menu.worldlist > 0 then
1177                 retval = retval .. menu.worldlist[1].name .. 
1178                                                 " \\[" .. menu.worldlist[1].gameid .. "\\]"
1179                                 
1180                 for i=2,#menu.worldlist,1 do
1181                         retval = retval .. "," .. menu.worldlist[i].name .. 
1182                                                 " \\[" .. menu.worldlist[i].gameid .. "\\]"
1183                 end
1184         end
1185                                 
1186         retval = retval .. ";" .. index .. "]"
1187                 
1188         return retval
1189 end
1190
1191 --------------------------------------------------------------------------------
1192 function tabbuilder.tab_settings()
1193         return  "vertlabel[0,0;SETTINGS]" ..
1194                         "checkbox[1,0.75;cb_fancy_trees;Fancy trees;"           .. dump(engine.setting_getbool("new_style_leaves"))     .. "]"..
1195                         "checkbox[1,1.25;cb_smooth_lighting;Smooth Lighting;".. dump(engine.setting_getbool("smooth_lighting")) .. "]"..
1196                         "checkbox[1,1.75;cb_3d_clouds;3D Clouds;"                       .. dump(engine.setting_getbool("enable_3d_clouds"))     .. "]"..
1197                         "checkbox[1,2.25;cb_opaque_water;Opaque Water;"                 .. dump(engine.setting_getbool("opaque_water"))         .. "]"..
1198                         
1199                         "checkbox[4,0.75;cb_mipmapping;Mip-Mapping;"            .. dump(engine.setting_getbool("mip_map"))                      .. "]"..
1200                         "checkbox[4,1.25;cb_anisotrophic;Anisotropic Filtering;".. dump(engine.setting_getbool("anisotropic_filter"))   .. "]"..
1201                         "checkbox[4,1.75;cb_bilinear;Bi-Linear Filtering;"      .. dump(engine.setting_getbool("bilinear_filter"))      .. "]"..
1202                         "checkbox[4,2.25;cb_trilinear;Tri-Linear Filtering;"    .. dump(engine.setting_getbool("trilinear_filter"))     .. "]"..
1203                         
1204                         "checkbox[7.5,0.75;cb_shaders;Shaders;"                         .. dump(engine.setting_getbool("enable_shaders"))               .. "]"..
1205                         "checkbox[7.5,1.25;cb_pre_ivis;Preload item visuals;".. dump(engine.setting_getbool("preload_item_visuals"))    .. "]"..
1206                         "checkbox[7.5,1.75;cb_particles;Enable Particles;"      .. dump(engine.setting_getbool("enable_particles"))     .. "]"..
1207                         "checkbox[7.5,2.25;cb_finite_liquid;Finite Liquid;"     .. dump(engine.setting_getbool("liquid_finite"))                .. "]"..
1208                         
1209                         "button[1,3.75;2.25,0.5;btn_change_keys;Change keys]"
1210 end
1211
1212 --------------------------------------------------------------------------------
1213 function tabbuilder.tab_singleplayer()
1214         local index = engine.setting_get("main_menu_singleplayer_world_idx")
1215
1216         if index == nil then
1217                 index = 0
1218         end
1219
1220         return  "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1221                         "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1222                         "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1223                         "button[8.5,4.95;3.25,0.5;play;Play]" ..
1224                         "label[4,-0.25;Select World:]"..
1225                         "vertlabel[0,-0.25;SINGLE PLAYER]" ..
1226                         "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1227                         dump(engine.setting_getbool("creative_mode")) .. "]"..
1228                         "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1229                         dump(engine.setting_getbool("enable_damage")) .. "]"..
1230                         "textlist[4,0.25;7.5,3.7;sp_worlds;" ..
1231                         menu.filtered_game_list() ..
1232                         ";" .. index .. "]" ..
1233                         menubar.formspec
1234 end
1235
1236 --------------------------------------------------------------------------------
1237 function tabbuilder.tab_credits()
1238         return  "vertlabel[0,-0.5;CREDITS]" ..
1239                         "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
1240                         "label[0.5,3.3;http://minetest.net]" .. 
1241                         "image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
1242                         "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
1243                         "#FFFF00Core Developers," ..
1244                         "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
1245                         "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
1246                         "PilzAdam <pilzadam@minetest.net>," ..
1247                         "IIya Zhuravlev (thexyz) <xyz@minetest.net>,"..
1248                         "Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
1249                         "Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
1250                         "proller <proler@gmail.com>,"..
1251                         "sfan5 <sfan5@live.de>,"..
1252                         "kahrl <kahrl@gmx.net>,"..
1253                         ","..
1254                         "#FFFF00Active Contributors," ..
1255                         "sapier,"..
1256                         "Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
1257                         "Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
1258                         "Jeija <jeija@mesecons.net>,"..
1259                         "MirceaKitsune <mirceakitsune@gmail.com>,"..
1260                         "ShadowNinja,"..
1261                         "dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
1262                         "0gb.us <0gb.us@0gb.us>,"..
1263                         "," ..
1264                         "#FFFF00Previous Contributors," ..
1265                         "Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
1266                         "Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
1267                         "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
1268                         "Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
1269                         "matttpt <matttpt@gmail.com>,"..
1270                         "JacobF <queatz@gmail.com>,"..
1271                         ";0;true]"
1272 end
1273
1274 --------------------------------------------------------------------------------
1275 function tabbuilder.checkretval(retval)
1276
1277         if retval ~= nil then
1278                 if retval.current_tab ~= nil then
1279                         tabbuilder.current_tab = retval.current_tab
1280                 end
1281                 
1282                 if retval.is_dialog ~= nil then
1283                         tabbuilder.is_dialog = retval.is_dialog
1284                 end
1285                 
1286                 if retval.show_buttons ~= nil then
1287                         tabbuilder.show_buttons = retval.show_buttons
1288                 end
1289                 
1290                 if retval.skipformupdate ~= nil then
1291                         tabbuilder.skipformupdate = retval.skipformupdate
1292                 end
1293         end
1294 end
1295
1296 --------------------------------------------------------------------------------
1297 --------------------------------------------------------------------------------
1298 -- initialize callbacks
1299 --------------------------------------------------------------------------------
1300 --------------------------------------------------------------------------------
1301 engine.button_handler = function(fields)
1302         --print("Buttonhandler: tab: " .. tabbuilder.current_tab .. " fields: " .. dump(fields))
1303         
1304         if fields["btn_error_confirm"] then
1305                 gamedata.errormessage = nil
1306         end
1307         
1308         local retval = modmgr.handle_buttons(tabbuilder.current_tab,fields)
1309         tabbuilder.checkretval(retval)
1310         
1311         retval = gamemgr.handle_buttons(tabbuilder.current_tab,fields)
1312         tabbuilder.checkretval(retval)
1313         
1314         retval = modstore.handle_buttons(tabbuilder.current_tab,fields)
1315         tabbuilder.checkretval(retval)
1316         
1317         if tabbuilder.current_tab == "dialog_create_world" then
1318                 tabbuilder.handle_create_world_buttons(fields)
1319         end
1320         
1321         if tabbuilder.current_tab == "dialog_delete_world" then
1322                 tabbuilder.handle_delete_world_buttons(fields)
1323         end
1324         
1325         if tabbuilder.current_tab == "singleplayer" then
1326                 tabbuilder.handle_singleplayer_buttons(fields)
1327         end
1328         
1329         if tabbuilder.current_tab == "multiplayer" then
1330                 tabbuilder.handle_multiplayer_buttons(fields)
1331         end
1332         
1333         if tabbuilder.current_tab == "settings" then
1334                 tabbuilder.handle_settings_buttons(fields)
1335         end
1336         
1337         if tabbuilder.current_tab == "server" then
1338                 tabbuilder.handle_server_buttons(fields)
1339         end
1340         
1341         --tab buttons
1342         tabbuilder.handle_tab_buttons(fields)
1343         
1344         --menubar buttons
1345         menubar.handle_buttons(fields)
1346         
1347         if not tabbuilder.skipformupdate then
1348                 --update menu
1349                 update_menu()
1350         else
1351                 tabbuilder.skipformupdate = false
1352         end
1353 end
1354
1355 --------------------------------------------------------------------------------
1356 engine.event_handler = function(event)
1357         if event == "MenuQuit" then
1358                 if tabbuilder.is_dialog then
1359                         tabbuilder.is_dialog = false
1360                         tabbuilder.show_buttons = true
1361                         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1362                         update_menu()
1363                 else
1364                         engine.close()
1365                 end
1366         end
1367 end
1368
1369 --------------------------------------------------------------------------------
1370 --------------------------------------------------------------------------------
1371 -- menu startup
1372 --------------------------------------------------------------------------------
1373 --------------------------------------------------------------------------------
1374 init_globals()
1375 menu.init()
1376 tabbuilder.init()
1377 menubar.refresh()
1378 modstore.init()
1379 update_menu()