1 //  Copyright (C) 2007 Ole Laursen
2 //  Copyright (C) 2007, 2008, 2009, 2010, 2014, 2017, 2020 Ben Asselstine
3 //
4 //  This program is free software; you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation; either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU Library General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 //  02110-1301, USA.
18 
19 #include <memory>
20 #include <iostream>
21 #include <assert.h>
22 #include <glib.h>
23 #include <gtkmm.h>
24 #include <sigc++/trackable.h>
25 #include <sigc++/functors/mem_fun.h>
26 #include <time.h>
27 #include "rnd.h"
28 
29 #include "recently-played-game-list.h"
30 #include "citysetlist.h"
31 #include "tilesetlist.h"
32 #include "shieldsetlist.h"
33 #include "armysetlist.h"
34 #include "profilelist.h"
35 #include "gamelist.h"
36 #include "file-compat.h"
37 #include "gui/builder-cache.h"
38 
39 #include "main.h"
40 
41 #include "driver.h"
42 #include "defs.h"
43 #include "File.h"
44 #include "Configuration.h"
45 #include "timing.h"
46 #include "fight-window.h"
47 
48 
49 struct Main::Impl: public sigc::trackable
50 {
51     Gtk::Main* gtk_main;
52     Driver* driver;
53 
54     sigc::connection on_timer_registered(Timing::timer_slot s,
55 					 int msecs_interval);
56 };
57 
58 
59 static Main *singleton;
60 
Main(int & argc,char ** & argv)61 Main::Main(int &argc, char **&argv)
62     : impl(new Impl)
63 {
64   impl->driver = NULL;
65     singleton = this;
66 
67     start_test_scenario = false;
68     start_net_test_scenario = false;
69     speedy = false;
70     own_all_on_round_two = false;
71     start_stress_test = false;
72     start_editor = false;
73     start_robots = 0;
74     start_headless_server = false;
75     load_filename = "";
76     turn_filename = "";
77     random_number_seed = 0;
78     port = 0;
79     cacheSize = 0;
80 
81     Glib::thread_init();
82     try
83     {
84 	impl->gtk_main = new Gtk::Main(argc, argv);
85 
86 	g_set_application_name("LordsAWar!");
87 
88 	Timing::instance().timer_registered.connect(
89 	    sigc::mem_fun(*impl, &Main::Impl::on_timer_registered));
90     }
91     catch (const Glib::Error &ex) {
92 	std::cerr << ex.what() << std::endl;
93     }
94 }
95 
~Main()96 Main::~Main()
97 {
98     delete impl->driver;
99     delete impl->gtk_main;
100     delete impl;
101     singleton = 0;
102 }
103 
instance()104 Main &Main::instance()
105 {
106     assert(singleton != 0);
107     return *singleton;
108 }
109 
start_main_loop()110 void Main::start_main_loop()
111 {
112   if (random_number_seed)
113     Rnd::set_seed(random_number_seed);
114   else
115     {
116       random_number_seed = time (NULL);
117       Rnd::set_seed(random_number_seed);
118     }
119 
120   try
121     {
122       if (impl->driver != NULL)
123         {
124           delete impl->driver;
125           impl->driver = NULL;
126         }
127       if (speedy)
128         {
129           FightWindow::s_quick_all = true;
130           Configuration::s_displaySpeedDelay = 0;
131         }
132       impl->driver = new Driver(start_editor, load_filename);
133       impl->gtk_main->run();
134     }
135   catch (const Glib::Error &ex) {
136     std::cerr << ex.what() << std::endl;
137   }
138 }
139 
stop_main_loop()140 void Main::stop_main_loop()
141 {
142     try
143     {
144 	impl->gtk_main->quit();
145     }
146     catch (const Glib::Error &ex) {
147 	std::cerr << ex.what() << std::endl;
148     }
149 }
150 
on_timer_registered(Timing::timer_slot s,int msecs_interval)151 sigc::connection Main::Impl::on_timer_registered(Timing::timer_slot s,
152 						 int msecs_interval)
153 {
154     return Glib::signal_timeout().connect(s, msecs_interval);
155 }
156 
initialize()157 void Main::initialize ()
158 {
159   if (configuration_file_path != "")
160     Configuration::s_configuration_file_path = configuration_file_path;
161   if (save_path != "")
162     Configuration::s_savePath = save_path;
163   initialize_configuration();
164   if (cacheSize)
165     Configuration::s_cacheSize = cacheSize;
166   Profilelist::support_backward_compatibility();
167   RecentlyPlayedGameList::support_backward_compatibility();
168   Gamelist::support_backward_compatibility();
169   FileCompat::support_backward_compatibility_for_common_files();
170   FileCompat::getInstance()->initialize();
171   Vector<int>::setMaximumWidth(1000);
172   RecentlyPlayedGameList::getInstance()->load();
173 
174   Gtk::Settings::get_default()->property_gtk_application_prefer_dark_theme() = true;
175   if (Configuration::s_font_size_override > 0)
176     override_font_size ();
177 
178   // Check if armysets are in the path (otherwise exit)
179   Armysetlist::scan(Armyset::file_extension);
180   Tilesetlist::scan(Tileset::file_extension);
181   Shieldsetlist::scan(Shieldset::file_extension);
182   Citysetlist::scan(Cityset::file_extension);
183   BuilderCache::getInstance();
184 
185 }
186 
override_font_size()187 void Main::override_font_size ()
188 {
189   Glib::ustring fname = Gtk::Settings::get_default()->property_gtk_font_name ();
190   //printf ("'%s'\n", fname.c_str());
191   char *f = strdup (fname.c_str ());
192   char *space = strrchr (f, ' ');
193   if (space)
194     {
195       *space = 0;
196       Glib::ustring newfname =
197         Glib::ustring::compose ("%1 %2", Glib::ustring (f),
198                                 Configuration::s_font_size_override);
199       Gtk::Settings::get_default()->property_gtk_font_name () = newfname;
200     }
201   free (f);
202   return;
203 }
204