Changeset - r17968:93e4c2154cdf
[Not reviewed]
master
0 3 0
rubidium - 13 years ago 2011-08-21 12:47:45
rubidium@openttd.org
(svn r22787) -Codechange: rename genworld redraw constant
3 files changed with 4 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/genworld.h
Show inline comments
 
/* $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 genworld.h Functions related to world/map generation. */
 

	
 
#ifndef GENWORLD_H
 
#define GENWORLD_H
 

	
 
#include "company_type.h"
 

	
 
/** Constants related to world generation */
 
enum LandscapeGenerator {
 
	/* Order of these enums has to be the same as in lang/english.txt
 
	 * Otherwise you will get inconsistent behaviour. */
 
	LG_ORIGINAL     = 0,  ///< The original landscape generator
 
	LG_TERRAGENESIS = 1,  ///< TerraGenesis Perlin landscape generator
 
};
 

	
 
static const uint GENERATE_NEW_SEED       = UINT_MAX; ///< Create a new random seed
 
static const uint GENWORLD_REDRAW_TIMEOUT = 200;      ///< Timeout between redraws
 
static const uint MODAL_PROGRESS_REDRAW_TIMEOUT = 200; ///< Timeout between redraws
 

	
 
/** Modes for GenerateWorld */
 
enum GenWorldMode {
 
	GWM_NEWGAME   = 0, ///< Generate a map for a new game
 
	GWM_EMPTY     = 1, ///< Generate an empty map (sea-level)
 
	GWM_RANDOM    = 2, ///< Generate a random map for SE
 
	GWM_HEIGHTMAP = 3, ///< Generate a newgame from a heightmap
 
};
 

	
 
static const uint CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY = 4; ///< Value for custom sea level in difficulty settings.
 
static const uint CUSTOM_SEA_LEVEL_MIN_PERCENTAGE = 1;    ///< Minimum percentage a user can specify for custom sea level.
 
static const uint CUSTOM_SEA_LEVEL_MAX_PERCENTAGE = 90;   ///< Maximum percentage a user can specify for custom sea level.
 

	
 
typedef void GWDoneProc();  ///< Procedure called when the genworld process finishes
 
typedef void GWAbortProc(); ///< Called when genworld is aborted
 

	
 
/** Properties of current genworld process */
 
struct GenWorldInfo {
 
	bool active;           ///< Is generating world active
 
	bool abort;            ///< Whether to abort the thread ASAP
 
	bool quit_thread;      ///< Do we want to quit the active thread
 
	bool threaded;         ///< Whether we run _GenerateWorld threaded
 
	GenWorldMode mode;     ///< What mode are we making a world in
 
	CompanyID lc;          ///< The local_company before generating
 
	uint size_x;           ///< X-size of the map
 
	uint size_y;           ///< Y-size of the map
 
	GWDoneProc *proc;      ///< Proc that is called when done (can be NULL)
 
	GWAbortProc *abortp;   ///< Proc that is called when aborting (can be NULL)
 
	class ThreadObject *thread; ///< The thread we are in (can be NULL)
 
};
 

	
 
/** Current stage of world generation process */
 
enum GenWorldProgress {
 
	GWP_MAP_INIT,    ///< Initialize/allocate the map, start economy
 
	GWP_LANDSCAPE,   ///< Create the landscape
 
	GWP_RIVER,       ///< Create the rivers
 
	GWP_ROUGH_ROCKY, ///< Make rough and rocky areas
 
	GWP_TOWN,        ///< Generate towns
 
	GWP_INDUSTRY,    ///< Generate industries
 
	GWP_OBJECT,      ///< Generate objects (radio tower, light houses)
 
	GWP_TREE,        ///< Generate trees
 
	GWP_GAME_INIT,   ///< Initialize the game
 
	GWP_RUNTILELOOP, ///< Runs the tile loop 1280 times to make snow etc
 
	GWP_GAME_START,  ///< Really prepare to start the game
 
	GWP_CLASS_COUNT
 
};
 

	
 
/**
src/genworld_gui.cpp
Show inline comments
 
@@ -1320,97 +1320,97 @@ struct GenerateProgressWindow : public W
 
		}
 
	}
 
};
 

	
 
/**
 
 * Initializes the progress counters to the starting point.
 
 */
 
void PrepareGenerateWorldProgress()
 
{
 
	_gws.cls     = STR_GENERATION_WORLD_GENERATION;
 
	_gws.current = 0;
 
	_gws.total   = 0;
 
	_gws.percent = 0;
 
	_gws.timer   = 0; // Forces to paint the progress window immediately
 
}
 

	
 
/**
 
 * Show the window where a user can follow the process of the map generation.
 
 */
 
void ShowGenerateWorldProgress()
 
{
 
	if (BringWindowToFrontById(WC_GENERATE_PROGRESS_WINDOW, 0)) return;
 
	new GenerateProgressWindow();
 
}
 

	
 
static void _SetGeneratingWorldProgress(GenWorldProgress cls, uint progress, uint total)
 
{
 
	static const int percent_table[] = {0, 5, 14, 17, 20, 40, 60, 65, 80, 85, 99, 100 };
 
	assert_compile(lengthof(percent_table) == GWP_CLASS_COUNT + 1);
 
	assert(cls < GWP_CLASS_COUNT);
 

	
 
	/* Do not run this function if we aren't in a thread */
 
	if (!IsGenerateWorldThreaded() && !_network_dedicated) return;
 

	
 
	if (IsGeneratingWorldAborted()) HandleGeneratingWorldAbortion();
 

	
 
	if (total == 0) {
 
		assert(_gws.cls == _generation_class_table[cls]);
 
		_gws.current += progress;
 
		assert(_gws.current <= _gws.total);
 
	} else {
 
		_gws.cls     = _generation_class_table[cls];
 
		_gws.current = progress;
 
		_gws.total   = total;
 
		_gws.percent = percent_table[cls];
 
	}
 

	
 
	/* Don't update the screen too often. So update it once in every once in a while... */
 
	if (!_network_dedicated && _gws.timer != 0 && _realtime_tick - _gws.timer < GENWORLD_REDRAW_TIMEOUT) return;
 
	if (!_network_dedicated && _gws.timer != 0 && _realtime_tick - _gws.timer < MODAL_PROGRESS_REDRAW_TIMEOUT) return;
 

	
 
	/* Percentage is about the number of completed tasks, so 'current - 1' */
 
	_gws.percent = percent_table[cls] + (percent_table[cls + 1] - percent_table[cls]) * (_gws.current == 0 ? 0 : _gws.current - 1) / _gws.total;
 

	
 
	if (_network_dedicated) {
 
		static uint last_percent = 0;
 

	
 
		/* Never display 0% */
 
		if (_gws.percent == 0) return;
 
		/* Reset if percent is lower than the last recorded */
 
		if (_gws.percent < last_percent) last_percent = 0;
 
		/* Display every 5%, but 6% is also very valid.. just not smaller steps than 5% */
 
		if (_gws.percent % 5 != 0 && _gws.percent <= last_percent + 5) return;
 
		/* Never show steps smaller than 2%, even if it is a mod 5% */
 
		if (_gws.percent <= last_percent + 2) return;
 

	
 
		DEBUG(net, 1, "Map generation percentage complete: %d", _gws.percent);
 
		last_percent = _gws.percent;
 

	
 
		/* Don't continue as dedicated never has a thread running */
 
		return;
 
	}
 

	
 
	SetWindowDirty(WC_GENERATE_PROGRESS_WINDOW, 0);
 
	MarkWholeScreenDirty();
 

	
 
	/* Release the rights to the map generator, and acquire the rights to the
 
	 * paint thread. The 'other' thread already has the paint thread rights so
 
	 * this ensures us that we are waiting until the paint thread is done
 
	 * before we reacquire the mapgen rights */
 
	_modal_progress_work_mutex->EndCritical();
 
	_modal_progress_paint_mutex->BeginCritical();
 
	_modal_progress_work_mutex->BeginCritical();
 
	_modal_progress_paint_mutex->EndCritical();
 

	
 
	_gws.timer = _realtime_tick;
 
}
 

	
 
/**
 
 * Set the total of a stage of the world generation.
 
 * @param cls the current class we are in.
 
 * @param total Set the total expected items for this class.
 
 *
 
 * Warning: this function isn't clever. Don't go from class 4 to 3. Go upwards, always.
 
 *  Also, progress works if total is zero, total works if progress is zero.
 
 */
 
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
 
{
src/gfx.cpp
Show inline comments
 
@@ -1516,98 +1516,98 @@ void DrawMouseCursor()
 

	
 
	_video_driver->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
 

	
 
	_cursor.visible = true;
 
	_cursor.dirty = false;
 
}
 

	
 
void RedrawScreenRect(int left, int top, int right, int bottom)
 
{
 
	assert(right <= _screen.width && bottom <= _screen.height);
 
	if (_cursor.visible) {
 
		if (right > _cursor.draw_pos.x &&
 
				left < _cursor.draw_pos.x + _cursor.draw_size.x &&
 
				bottom > _cursor.draw_pos.y &&
 
				top < _cursor.draw_pos.y + _cursor.draw_size.y) {
 
			UndrawMouseCursor();
 
		}
 
	}
 

	
 
#ifdef ENABLE_NETWORK
 
	if (_networking) NetworkUndrawChatMessage();
 
#endif /* ENABLE_NETWORK */
 

	
 
	DrawOverlappedWindowForAll(left, top, right, bottom);
 

	
 
	_video_driver->MakeDirty(left, top, right - left, bottom - top);
 
}
 

	
 
/**
 
 * Repaints the rectangle blocks which are marked as 'dirty'.
 
 *
 
 * @see SetDirtyBlocks
 
 */
 
void DrawDirtyBlocks()
 
{
 
	byte *b = _dirty_blocks;
 
	const int w = Align(_screen.width,  DIRTY_BLOCK_WIDTH);
 
	const int h = Align(_screen.height, DIRTY_BLOCK_HEIGHT);
 
	int x;
 
	int y;
 

	
 
	if (HasModalProgress()) {
 
		/* We are generating the world, so release our rights to the map and
 
		 * painting while we are waiting a bit. */
 
		_modal_progress_paint_mutex->EndCritical();
 
		_modal_progress_work_mutex->EndCritical();
 

	
 
		/* Wait a while and update _realtime_tick so we are given the rights */
 
		CSleep(GENWORLD_REDRAW_TIMEOUT);
 
		_realtime_tick += GENWORLD_REDRAW_TIMEOUT;
 
		CSleep(MODAL_PROGRESS_REDRAW_TIMEOUT);
 
		_realtime_tick += MODAL_PROGRESS_REDRAW_TIMEOUT;
 
		_modal_progress_paint_mutex->BeginCritical();
 
		_modal_progress_work_mutex->BeginCritical();
 
	}
 

	
 
	y = 0;
 
	do {
 
		x = 0;
 
		do {
 
			if (*b != 0) {
 
				int left;
 
				int top;
 
				int right = x + DIRTY_BLOCK_WIDTH;
 
				int bottom = y;
 
				byte *p = b;
 
				int h2;
 

	
 
				/* First try coalescing downwards */
 
				do {
 
					*p = 0;
 
					p += _dirty_bytes_per_line;
 
					bottom += DIRTY_BLOCK_HEIGHT;
 
				} while (bottom != h && *p != 0);
 

	
 
				/* Try coalescing to the right too. */
 
				h2 = (bottom - y) / DIRTY_BLOCK_HEIGHT;
 
				assert(h2 > 0);
 
				p = b;
 

	
 
				while (right != w) {
 
					byte *p2 = ++p;
 
					int h = h2;
 
					/* Check if a full line of dirty flags is set. */
 
					do {
 
						if (!*p2) goto no_more_coalesc;
 
						p2 += _dirty_bytes_per_line;
 
					} while (--h != 0);
 

	
 
					/* Wohoo, can combine it one step to the right!
 
					 * Do that, and clear the bits. */
 
					right += DIRTY_BLOCK_WIDTH;
 

	
 
					h = h2;
 
					p2 = p;
 
					do {
 
						*p2 = 0;
 
						p2 += _dirty_bytes_per_line;
 
					} while (--h != 0);
 
				}
0 comments (0 inline, 0 general)