Changeset - r18398:d59db4740015
[Not reviewed]
master
0 10 1
rubidium - 13 years ago 2011-11-17 21:17:17
rubidium@openttd.org
(svn r23244) -Feature: if the installation is ananas, try to get the b without b installed
11 files changed with 314 insertions and 9 deletions:
0 comments (0 inline, 0 general)
projects/openttd_vs100.vcxproj
Show inline comments
 
@@ -635,6 +635,7 @@
 
    <ClCompile Include="..\src\aircraft_gui.cpp" />
 
    <ClCompile Include="..\src\airport_gui.cpp" />
 
    <ClCompile Include="..\src\autoreplace_gui.cpp" />
 
    <ClCompile Include="..\src\bootstrap_gui.cpp" />
 
    <ClCompile Include="..\src\bridge_gui.cpp" />
 
    <ClCompile Include="..\src\build_vehicle_gui.cpp" />
 
    <ClCompile Include="..\src\cheat_gui.cpp" />
projects/openttd_vs100.vcxproj.filters
Show inline comments
 
@@ -1125,6 +1125,9 @@
 
    <ClCompile Include="..\src\autoreplace_gui.cpp">
 
      <Filter>GUI Source Code</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\bootstrap_gui.cpp">
 
      <Filter>GUI Source Code</Filter>
 
    </ClCompile>
 
    <ClCompile Include="..\src\bridge_gui.cpp">
 
      <Filter>GUI Source Code</Filter>
 
    </ClCompile>
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -1823,6 +1823,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\bootstrap_gui.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\bridge_gui.cpp"
 
				>
 
			</File>
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -1820,6 +1820,10 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\bootstrap_gui.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\bridge_gui.cpp"
 
				>
 
			</File>
source.list
Show inline comments
 
@@ -387,6 +387,7 @@ core/string_compare_type.hpp
 
aircraft_gui.cpp
 
airport_gui.cpp
 
autoreplace_gui.cpp
 
bootstrap_gui.cpp
 
bridge_gui.cpp
 
build_vehicle_gui.cpp
 
cheat_gui.cpp
src/bootstrap_gui.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * 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.
 
 * 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.
 
 * 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/>.
 
 */
 

	
 
/** @file bootstrap_gui.cpp Barely used user interface for bootstrapping OpenTTD, i.e. downloading the required content. */
 

	
 
#include "stdafx.h"
 
#include "base_media_base.h"
 
#include "blitter/factory.hpp"
 
#include "core/geometry_func.hpp"
 
#include "fileio_func.h"
 
#include "fontcache.h"
 
#include "gfx_func.h"
 
#include "network/network.h"
 
#include "network/network_content_gui.h"
 
#include "openttd.h"
 
#include "strings_func.h"
 
#include "video/video_driver.hpp"
 
#include "window_func.h"
 
#include "window_gui.h"
 

	
 
#include "table/strings.h"
 

	
 
/** Widgets for the background window to prevent smearing. */
 
static const struct NWidgetPart _background_widgets[] = {
 
	NWidget(WWT_PANEL, COLOUR_DARK_BLUE, 0), SetResize(1, 1),
 
};
 

	
 
/**
 
 * Window description for the background window to prevent smearing.
 
 */
 
static const WindowDesc _background_desc(
 
	WDP_MANUAL, 0, 0,
 
	WC_BOOTSTRAP, WC_NONE,
 
	0,
 
	_background_widgets, lengthof(_background_widgets)
 
);
 

	
 
/** The background for the game. */
 
class BootstrapBackground : public Window {
 
public:
 
	BootstrapBackground() : Window()
 
	{
 
		this->InitNested(&_background_desc, 0);
 
		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
 
		ResizeWindow(this, _screen.width, _screen.height);
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		GfxFillRect(r.left, r.top, r.right, r.bottom, 4, FILLRECT_OPAQUE);
 
		GfxFillRect(r.left, r.top, r.right, r.bottom, 0, FILLRECT_CHECKER);
 
	}
 
};
 

	
 
/** Nested widgets for the download window. */
 
static const NWidgetPart _nested_boostrap_download_status_window_widgets[] = {
 
	NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
	NWidget(WWT_PANEL, COLOUR_GREY, NCDSWW_BACKGROUND),
 
		NWidget(NWID_SPACER), SetMinimalSize(350, 0), SetMinimalTextLines(3, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 30),
 
	EndContainer(),
 
};
 

	
 
/** Window description for the download window */
 
static const WindowDesc _bootstrap_download_status_window_desc(
 
	WDP_CENTER, 0, 0,
 
	WC_NETWORK_STATUS_WINDOW, WC_NONE,
 
	WDF_MODAL,
 
	_nested_boostrap_download_status_window_widgets, lengthof(_nested_boostrap_download_status_window_widgets)
 
);
 

	
 

	
 
/** Window for showing the download status of content */
 
struct BootstrapContentDownloadStatusWindow : public BaseNetworkContentDownloadStatusWindow {
 
public:
 
	/** Simple call the constructor of the superclass. */
 
	BootstrapContentDownloadStatusWindow() : BaseNetworkContentDownloadStatusWindow(&_bootstrap_download_status_window_desc)
 
	{
 
	}
 

	
 
	virtual void OnDownloadComplete(ContentID cid)
 
	{
 
		/* We have completed downloading. We can trigger finding the right set now. */
 
		BaseGraphics::FindSets();
 

	
 
		/* And continue going into the menu. */
 
		_game_mode = GM_MENU;
 

	
 
		/* _exit_game is used to break out of the outer video driver's MainLoop. */
 
		_exit_game = true;
 
		delete this;
 
	}
 
};
 

	
 
/** Widgets in the query window. */
 
enum BootstrapAskForDownloadWidgets {
 
	BAFDW_QUESTION, ///< The question whether to download.
 
	BAFDW_YES,      ///< An affirmative answer to the question.
 
	BAFDW_NO,       ///< An negative answer to the question.
 
};
 

	
 
/** The widgets for the query. It has no close box as that sprite does not exist yet. */
 
static const NWidgetPart _bootstrap_query_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_MISSING_GRAPHICS_SET_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_GREY),
 
		NWidget(WWT_PANEL, COLOUR_GREY, BAFDW_QUESTION), EndContainer(),
 
		NWidget(NWID_HORIZONTAL),
 
			NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, BAFDW_YES), SetDataTip(STR_MISSING_GRAPHICS_YES_DOWNLOAD, STR_NULL),
 
			NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, BAFDW_NO), SetDataTip(STR_MISSING_GRAPHICS_NO_QUIT, STR_NULL),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
/** The window description for the query. */
 
static const WindowDesc _bootstrap_query_desc(
 
	WDP_CENTER, 0, 0,
 
	WC_CONFIRM_POPUP_QUERY, WC_NONE,
 
	WDF_UNCLICK_BUTTONS,
 
	_bootstrap_query_widgets, lengthof(_bootstrap_query_widgets)
 
);
 

	
 
/** The window for the query. It can't use the generic query window as that uses sprites that don't exist yet. */
 
class BootstrapAskForDownloadWindow : public Window, ContentCallback {
 
	Dimension button_size; ///< The dimension of the button
 

	
 
public:
 
	/** Start listening to the content client events. */
 
	BootstrapAskForDownloadWindow() : Window()
 
	{
 
		this->InitNested(&_bootstrap_query_desc);
 
		_network_content_client.AddCallback(this);
 
	}
 

	
 
	/** Stop listening to the content client events. */
 
	~BootstrapAskForDownloadWindow()
 
	{
 
		_network_content_client.RemoveCallback(this);
 
	}
 

	
 
	virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
 
	{
 
		/* We cache the button size. This is safe as no reinit can happen here. */
 
		if (this->button_size.width == 0) {
 
			this->button_size = maxdim(GetStringBoundingBox(STR_MISSING_GRAPHICS_YES_DOWNLOAD), GetStringBoundingBox(STR_MISSING_GRAPHICS_NO_QUIT));
 
			this->button_size.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
 
			this->button_size.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
 
		}
 

	
 
		switch (widget) {
 
			case BAFDW_QUESTION:
 
				/* The question is twice as wide as the buttons, and determine the height based on the width. */
 
				size->width = this->button_size.width * 2;
 
				size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP;
 
				break;
 

	
 
			case BAFDW_YES:
 
			case BAFDW_NO:
 
				*size = this->button_size;
 
				break;
 
		}
 
	}
 

	
 
	virtual void DrawWidget(const Rect &r, int widget) const
 
	{
 
		if (widget != 0) return;
 

	
 
		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);
 
	}
 

	
 
	virtual void OnClick(Point pt, int widget, int click_count)
 
	{
 
		switch (widget) {
 
			case BAFDW_YES:
 
				/* We got permission to connect! Yay! */
 
				_network_content_client.Connect();
 
				break;
 

	
 
			case BAFDW_NO:
 
				_exit_game = true;
 
				break;
 

	
 
			default:
 
				break;
 
		}
 
	}
 

	
 
	virtual void OnConnect(bool success)
 
	{
 
		/* Once connected, request the metadata. */
 
		_network_content_client.RequestContentList(CONTENT_TYPE_BASE_GRAPHICS);
 
	}
 

	
 
	virtual void OnReceiveContentInfo(const ContentInfo *ci)
 
	{
 
		/* And once the meta data is received, start downloading it. */
 
		_network_content_client.Select(ci->id);
 
		new BootstrapContentDownloadStatusWindow();
 
		delete this;
 
	}
 
};
 

	
 
/**
 
 * Handle all procedures for bootstrapping OpenTTD without a base grapics set.
 
 * This requires all kinds of trickery that is needed to avoid the use of
 
 * sprites from the base graphics set which are pretty interwoven.
 
 * @return True if a base set exists, otherwise false.
 
 */
 
bool HandleBootstrap()
 
{
 
	if (BaseGraphics::GetUsedSet() != NULL) return true;
 

	
 
	/* No user interface, bail out with an error. */
 
	if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure;
 

	
 
	/* If there is no network or no freetype, then there is nothing we can do. Go straight to failure. */
 
#if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) && !defined(__APPLE__)
 
	if (!_network_available) goto failure;
 

	
 
	/* First tell the game we're bootstrapping. */
 
	_game_mode = GM_BOOTSTRAP;
 

	
 
	/* Initialise the freetype font code. */
 
	InitializeUnicodeGlyphMap();
 
	/* Next "force" finding a suitable freetype font as the local font is missing. */
 
	CheckForMissingGlyphsInLoadedLanguagePack(false);
 

	
 
	/* Initialise the palette. The biggest step is 'faking' some recolour sprites.
 
	 * This way the mauve and gray colours work and we can show the user interface. */
 
	GfxInitPalettes();
 
	static const int offsets[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0x04, 0x08 };
 
	for (uint i = 0; i != 16; i++) {
 
		for (int j = 0; j < 8; j++) {
 
			_colour_gradient[i][j] = offsets[i] + j;
 
		}
 
	}
 

	
 
	/* Finally ask the question. */
 
	new BootstrapBackground();
 
	new BootstrapAskForDownloadWindow();
 

	
 
	/* Process the user events. */
 
	_video_driver->MainLoop();
 

	
 
	/* _exit_game is used to get out of the video driver's main loop.
 
	 * In case GM_BOOTSTRAP is still set we did not exit it via the
 
	 * "download complete" event, so it was a manual exit. Obey it. */
 
	_exit_game = _game_mode == GM_BOOTSTRAP;
 
	if (_exit_game) return false;
 

	
 
	/* Try to probe the graphics. Should work this time. */
 
	if (!BaseGraphics::SetSet(NULL)) goto failure;
 

	
 
	/* Finally we can continue heading for the menu. */
 
	_game_mode = GM_MENU;
 
	return true;
 
#endif
 

	
 
	/* Failure to get enough working to get a graphics set. */
 
failure:
 
	usererror("Failed to find a graphics set. Please acquire a graphics set for OpenTTD. See section 4.1 of readme.txt.");
 
	return false;
 
}
src/lang/english.txt
Show inline comments
 
@@ -1875,6 +1875,11 @@ STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_CON
 
STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE          :{WHITE}... file not writable
 
STR_CONTENT_ERROR_COULD_NOT_EXTRACT                             :{WHITE}Could not decompress the downloaded file
 

	
 
STR_MISSING_GRAPHICS_SET_CAPTION                                :{WHITE}Missing graphics
 
STR_MISSING_GRAPHICS_SET_MESSAGE                                :{BLACK}OpenTTD requires graphics to function but none could be found. Do you allow OpenTTD to download and install these graphics?
 
STR_MISSING_GRAPHICS_YES_DOWNLOAD                               :{BLACK}Yes, download the graphics
 
STR_MISSING_GRAPHICS_NO_QUIT                                    :{BLACK}No, quit OpenTTD
 

	
 
# Transparency settings window
 
STR_TRANSPARENCY_CAPTION                                        :{WHITE}Transparency Options
 
STR_TRANSPARENT_SIGNS_TOOLTIP                                   :{BLACK}Toggle transparency for station signs. Ctrl+Click to lock
src/openttd.cpp
Show inline comments
 
@@ -79,6 +79,7 @@ void DoPaletteAnimations();
 
void MusicLoop();
 
void ResetMusic();
 
void CallWindowTickEvent();
 
bool HandleBootstrap();
 

	
 
extern void SetDifficultyLevel(int mode, DifficultySettings *gm_opt);
 
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
 
@@ -297,7 +298,8 @@ static void ShutdownGame()
 

	
 
	PoolBase::Clean(PT_ALL);
 

	
 
	ResetNewGRFData();
 
	/* No NewGRFs were loaded when it was still bootstrapping. */
 
	if (_game_mode != GM_BOOTSTRAP) ResetNewGRFData();
 

	
 
	/* Close all and any open filehandles */
 
	FioCloseAll();
 
@@ -717,10 +719,8 @@ int ttd_main(int argc, char *argv[])
 
	free(sounds_set);
 

	
 
	if (graphics_set == NULL && BaseGraphics::ini_set != NULL) graphics_set = strdup(BaseGraphics::ini_set);
 
	if (!BaseGraphics::SetSet(graphics_set)) {
 
		StrEmpty(graphics_set) ?
 
			usererror("Failed to find a graphics set. Please acquire a graphics set for OpenTTD. See section 4.1 of readme.txt.") :
 
			usererror("Failed to select requested graphics set '%s'", graphics_set);
 
	if (!BaseGraphics::SetSet(graphics_set) && !StrEmpty(graphics_set)) {
 
		usererror("Failed to select requested graphics set '%s'", graphics_set);
 
	}
 
	free(graphics_set);
 

	
 
@@ -739,7 +739,7 @@ int ttd_main(int argc, char *argv[])
 
	if (blitter == NULL && _ini_blitter != NULL) blitter = strdup(_ini_blitter);
 
	_blitter_autodetected = StrEmpty(blitter);
 
	/* If we have a 32 bpp base set, try to select the 32 bpp blitter first, but only if we autoprobe the blitter. */
 
	if (!_blitter_autodetected || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP || BlitterFactoryBase::SelectBlitter("32bpp-anim") == NULL) {
 
	if (!_blitter_autodetected || BaseGraphics::GetUsedSet() == NULL || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP || BlitterFactoryBase::SelectBlitter("32bpp-anim") == NULL) {
 
		if (BlitterFactoryBase::SelectBlitter(blitter) == NULL) {
 
			StrEmpty(blitter) ?
 
				usererror("Failed to autoprobe blitter") :
 
@@ -780,12 +780,14 @@ int ttd_main(int argc, char *argv[])
 
	/* Initialize the zoom level of the screen to normal */
 
	_screen.zoom = ZOOM_LVL_NORMAL;
 

	
 
	NetworkStartUp(); // initialize network-core
 

	
 
	if (!HandleBootstrap()) goto exit;
 

	
 
	/* restore saved music volume */
 
	_music_driver->SetVolume(_settings_client.music.music_vol);
 
	_video_driver->ClaimMousePointer();
 

	
 
	NetworkStartUp(); // initialize network-core
 

	
 
#if defined(ENABLE_NETWORK)
 
	if (debuglog_conn != NULL && _network_available) {
 
		const char *not_used = NULL;
 
@@ -825,6 +827,7 @@ int ttd_main(int argc, char *argv[])
 
		SaveToHighScore();
 
	}
 

	
 
exit:
 
	/* Reset windowing system, stop drivers, free used memory, ... */
 
	ShutdownGame();
 

	
 
@@ -841,7 +844,7 @@ int ttd_main(int argc, char *argv[])
 

	
 
void HandleExitGameRequest()
 
{
 
	if (_game_mode == GM_MENU) { // do not ask to quit on the main screen
 
	if (_game_mode == GM_MENU || _game_mode == GM_BOOTSTRAP) { // do not ask to quit on the main screen
 
		_exit_game = true;
 
	} else if (_settings_client.gui.autosave_on_exit) {
 
		DoExitSave();
 
@@ -1317,6 +1320,15 @@ static void DoAutosave()
 

	
 
void GameLoop()
 
{
 
	if (_game_mode == GM_BOOTSTRAP) {
 
#ifdef ENABLE_NETWORK
 
		/* Check for UDP stuff */
 
		if (_network_available) NetworkUDPGameLoop();
 
#endif
 
		InputLoop();
 
		return;
 
	}
 

	
 
	ProcessAsyncSaveFinish();
 

	
 
	/* autosave game? */
src/openttd.h
Show inline comments
 
@@ -19,6 +19,7 @@ enum GameMode {
 
	GM_MENU,
 
	GM_NORMAL,
 
	GM_EDITOR,
 
	GM_BOOTSTRAP
 
};
 

	
 
/** Mode which defines what mode we're switching to. */
src/window.cpp
Show inline comments
 
@@ -2786,6 +2786,10 @@ void RelocateAllWindows(int neww, int ne
 
		/* XXX - this probably needs something more sane. For example specifying
 
		 * in a 'backup'-desc that the window should always be centered. */
 
		switch (w->window_class) {
 
			case WC_BOOTSTRAP:
 
				ResizeWindow(w, neww, newh);
 
				continue;
 

	
 
			case WC_MAIN_TOOLBAR:
 
				ResizeWindow(w, min(neww, *_preferred_toolbar_size) - w->width, 0);
 

	
src/window_type.h
Show inline comments
 
@@ -84,6 +84,7 @@ enum WindowClass {
 
	WC_CHEATS,
 
	WC_PERFORMANCE_DETAIL,
 
	WC_CONSOLE,
 
	WC_BOOTSTRAP,
 
	WC_EXTRA_VIEW_PORT,
 
	WC_CLIENT_LIST,
 
	WC_NETWORK_STATUS_WINDOW,
0 comments (0 inline, 0 general)