OpenTTD
bootstrap_gui.cpp
Go to the documentation of this file.
1 /* $Id: bootstrap_gui.cpp 26538 2014-04-28 21:06:51Z rubidium $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #include "stdafx.h"
13 #include "base_media_base.h"
14 #include "blitter/factory.hpp"
15 
16 #if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE)
17 
18 #include "core/geometry_func.hpp"
19 #include "fontcache.h"
20 #include "gfx_func.h"
21 #include "network/network.h"
23 #include "openttd.h"
24 #include "strings_func.h"
25 #include "video/video_driver.hpp"
26 #include "window_func.h"
27 
29 
30 #include "table/strings.h"
31 
32 #include "safeguards.h"
33 
35 static const struct NWidgetPart _background_widgets[] = {
36  NWidget(WWT_PANEL, COLOUR_DARK_BLUE, WID_BB_BACKGROUND), SetResize(1, 1),
37 };
38 
43  WDP_MANUAL, NULL, 0, 0,
45  0,
46  _background_widgets, lengthof(_background_widgets)
47 );
48 
50 class BootstrapBackground : public Window {
51 public:
53  {
54  this->InitNested(0);
56  ResizeWindow(this, _screen.width, _screen.height);
57  }
58 
59  virtual void DrawWidget(const Rect &r, int widget) const
60  {
61  GfxFillRect(r.left, r.top, r.right, r.bottom, 4, FILLRECT_OPAQUE);
62  GfxFillRect(r.left, r.top, r.right, r.bottom, 0, FILLRECT_CHECKER);
63  }
64 };
65 
68  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
69  NWidget(WWT_PANEL, COLOUR_GREY, WID_NCDS_BACKGROUND),
71  EndContainer(),
72 };
73 
76  WDP_CENTER, NULL, 0, 0,
78  WDF_MODAL,
79  _nested_boostrap_download_status_window_widgets, lengthof(_nested_boostrap_download_status_window_widgets)
80 );
81 
82 
85 public:
88  {
89  }
90 
91  virtual void OnDownloadComplete(ContentID cid)
92  {
93  /* We have completed downloading. We can trigger finding the right set now. */
95 
96  /* And continue going into the menu. */
97  _game_mode = GM_MENU;
98 
99  /* _exit_game is used to break out of the outer video driver's MainLoop. */
100  _exit_game = true;
101  delete this;
102  }
103 };
104 
108  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_MISSING_GRAPHICS_SET_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
109  EndContainer(),
110  NWidget(WWT_PANEL, COLOUR_GREY),
113  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BAFD_YES), SetDataTip(STR_MISSING_GRAPHICS_YES_DOWNLOAD, STR_NULL),
114  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_BAFD_NO), SetDataTip(STR_MISSING_GRAPHICS_NO_QUIT, STR_NULL),
115  EndContainer(),
116  EndContainer(),
117 };
118 
121  WDP_CENTER, NULL, 0, 0,
123  0,
124  _bootstrap_query_widgets, lengthof(_bootstrap_query_widgets)
125 );
126 
130 
131 public:
134  {
137  }
138 
141  {
143  }
144 
145  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
146  {
147  /* We cache the button size. This is safe as no reinit can happen here. */
148  if (this->button_size.width == 0) {
149  this->button_size = maxdim(GetStringBoundingBox(STR_MISSING_GRAPHICS_YES_DOWNLOAD), GetStringBoundingBox(STR_MISSING_GRAPHICS_NO_QUIT));
152  }
153 
154  switch (widget) {
155  case WID_BAFD_QUESTION:
156  /* The question is twice as wide as the buttons, and determine the height based on the width. */
157  size->width = this->button_size.width * 2;
158  size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP;
159  break;
160 
161  case WID_BAFD_YES:
162  case WID_BAFD_NO:
163  *size = this->button_size;
164  break;
165  }
166  }
167 
168  virtual void DrawWidget(const Rect &r, int widget) const
169  {
170  if (widget != 0) return;
171 
172  DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER);
173  }
174 
175  virtual void OnClick(Point pt, int widget, int click_count)
176  {
177  switch (widget) {
178  case WID_BAFD_YES:
179  /* We got permission to connect! Yay! */
181  break;
182 
183  case WID_BAFD_NO:
184  _exit_game = true;
185  break;
186 
187  default:
188  break;
189  }
190  }
191 
192  virtual void OnConnect(bool success)
193  {
194  /* Once connected, request the metadata. */
196  }
197 
198  virtual void OnReceiveContentInfo(const ContentInfo *ci)
199  {
200  /* And once the meta data is received, start downloading it. */
203  delete this;
204  }
205 };
206 
207 #endif /* defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) */
208 
216 {
217  if (BaseGraphics::GetUsedSet() != NULL) return true;
218 
219  /* No user interface, bail out with an error. */
220  if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure;
221 
222  /* If there is no network or no freetype, then there is nothing we can do. Go straight to failure. */
223 #if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(WIN32) || defined(__APPLE__))
224  if (!_network_available) goto failure;
225 
226  /* First tell the game we're bootstrapping. */
227  _game_mode = GM_BOOTSTRAP;
228 
229  /* Initialise the freetype font code. */
231  /* Next "force" finding a suitable freetype font as the local font is missing. */
232  CheckForMissingGlyphs(false);
233 
234  /* Initialise the palette. The biggest step is 'faking' some recolour sprites.
235  * This way the mauve and gray colours work and we can show the user interface. */
236  GfxInitPalettes();
237  static const int offsets[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0x04, 0x08 };
238  for (uint i = 0; i != 16; i++) {
239  for (int j = 0; j < 8; j++) {
240  _colour_gradient[i][j] = offsets[i] + j;
241  }
242  }
243 
244  /* Finally ask the question. */
245  new BootstrapBackground();
247 
248  /* Process the user events. */
250 
251  /* _exit_game is used to get out of the video driver's main loop.
252  * In case GM_BOOTSTRAP is still set we did not exit it via the
253  * "download complete" event, so it was a manual exit. Obey it. */
254  _exit_game = _game_mode == GM_BOOTSTRAP;
255  if (_exit_game) return false;
256 
257  /* Try to probe the graphics. Should work this time. */
258  if (!BaseGraphics::SetSet(NULL)) goto failure;
259 
260  /* Finally we can continue heading for the menu. */
261  _game_mode = GM_MENU;
262  return true;
263 #endif
264 
265  /* Failure to get enough working to get a graphics set. */
266 failure:
267  usererror("Failed to find a graphics set. Please acquire a graphics set for OpenTTD. See section 4.1 of readme.txt.");
268  return false;
269 }