Esempio n. 1
0
bool GroundVehicle<T, Type>::IsChainInDepot() const
{
	const T *v = this->First();
	/* Is the front engine stationary in the depot? */
	assert_compile((int)TRANSPORT_RAIL == (int)VEH_TRAIN);
	assert_compile((int)TRANSPORT_ROAD == (int)VEH_ROAD);
	if (!IsDepotTypeTile(v->tile, (TransportType)Type) || v->cur_speed != 0) return false;

	/* Check whether the rest is also already trying to enter the depot. */
	for (; v != NULL; v = v->Next()) {
		if (!v->T::IsInDepot() || v->tile != this->tile) return false;
	}

	return true;
}
Esempio n. 2
0
static SavegameType DetermineOldSavegameType(FILE *f, char *title, const char *last)
{
	assert_compile(TTD_HEADER_SIZE >= TTO_HEADER_SIZE);
	char temp[TTD_HEADER_SIZE];

	SavegameType type = SGT_TTO;

	/* Can't fseek to 0 as in tar files that is not correct */
	long pos = ftell(f);
	if (!CheckOldSavegameType(f, temp, lastof(temp), TTO_HEADER_SIZE)) {
		type = SGT_TTD;
		fseek(f, pos, SEEK_SET);
		if (!CheckOldSavegameType(f, temp, lastof(temp), TTD_HEADER_SIZE)) {
			type = SGT_INVALID;
		}
	}

	if (title != NULL) {
		switch (type) {
			case SGT_TTO: title = strecpy(title, "(TTO) ", last);    break;
			case SGT_TTD: title = strecpy(title, "(TTD) ", last);    break;
			default:      title = strecpy(title, "(broken) ", last); break;
		}
		title = strecpy(title, temp, last);
	}

	return type;
}
Esempio n. 3
0
static void DedicatedHandleKeyInput()
{
	static char input_line[1024] = "";

	if (!InputWaiting()) return;

	if (_exit_game) return;

#if defined(UNIX) || defined(__OS2__) || defined(PSP)
	if (fgets(input_line, lengthof(input_line), stdin) == NULL) return;
#else
	/* Handle console input, and singal console thread, it can accept input again */
	assert_compile(lengthof(_win_console_thread_buffer) <= lengthof(input_line));
	strecpy(input_line, _win_console_thread_buffer, lastof(input_line));
	SetEvent(_hWaitForInputHandling);
#endif

	/* strtok() does not 'forget' \r\n if the string starts with it,
	 * so we have to manually remove that! */
	strtok(input_line, "\r\n");
	for (char *c = input_line; *c != '\0'; c++) {
		if (*c == '\n' || *c == '\r' || c == lastof(input_line)) {
			*c = '\0';
			break;
		}
	}
	str_validate(input_line, lastof(input_line));

	IConsoleCmdExec(input_line); // execute command
}
Esempio n. 4
0
static void DedicatedHandleKeyInput()
{
	static char input_line[1024] = "";

	if (!InputWaiting()) return;

	if (_exit_game) return;

#if defined(UNIX) || defined(__OS2__) || defined(PSP)
	if (fgets(input_line, lengthof(input_line), stdin) == NULL) return;
#else
	/* Handle console input, and signal console thread, it can accept input again */
	assert_compile(lengthof(_win_console_thread_buffer) <= lengthof(input_line));
	strecpy(input_line, _win_console_thread_buffer, lastof(input_line));
	SetEvent(_hWaitForInputHandling);
#endif

	/* Remove trailing \r or \n */
	for (char *c = input_line; *c != '\0'; c++) {
		if (*c == '\n' || *c == '\r' || c == lastof(input_line)) {
			*c = '\0';
			break;
		}
	}
	str_validate(input_line, lastof(input_line));

	IConsoleCmdExec(input_line); // execute command
}
void VJSGlobalClass::_CheckInitStaticValues()
{
	if (sStaticValues.empty())
	{
		assert_compile( sizeof( _StaticValue) == sizeof( JSStaticValue));
		_PushBackStaticValue( 0, 0, 0, 0);
	}
}
Esempio n. 6
0
	/** Default constructor. Preallocate space for items and header, then initialize header. */
	FixedSizeArray()
	{
		/* Ensure the size won't overflow. */
		assert_compile(C < (SIZE_MAX - HeaderSize) / Tsize);

		/* allocate block for header + items (don't construct items) */
		data = (T*)((MallocT<byte>(HeaderSize + C * Tsize)) + HeaderSize);
		SizeRef() = 0; // initial number of items
		RefCnt() = 1; // initial reference counter
	}
void VJSGlobalClass::_CheckInitStaticFunctions()
{
	if (sStaticFunctions.empty())
	{
		assert_compile( sizeof( _StaticFunction) == sizeof( JSStaticFunction));

		//** TODO: Garder ? Mozilla propose dump() avec même comportement.
		_PushBackStaticFunction( "trace", js_callStaticFunction<do_trace>, JS4D::PropertyAttributeNone);

		//_PushBackStaticFunction( "testMe", js_callStaticFunction<do_testMe>, JS4D::PropertyAttributeNone);
		_PushBackStaticFunction( "include", js_callStaticFunction<do_include>, JS4D::PropertyAttributeNone);
//		_PushBackStaticFunction( "Folder", js_callStaticFunction<do_Folder>, JS4D::PropertyAttributeNone); // Folder(string : file URL)
//		_PushBackStaticFunction( "File", js_callStaticFunction<do_File>, JS4D::PropertyAttributeNone); // File(string : file URL | ( Folder : folder , string : filename) )
		_PushBackStaticFunction( "ProgressIndicator", js_callStaticFunction<do_ProgressIndicator>, JS4D::PropertyAttributeNone); // ProgressIndicator( { number : maxvalue, string : sessiontext, bool : caninterrupt = false, string : windowtitle, string : progressInfo })
		_PushBackStaticFunction( "getProgressIndicator", js_callStaticFunction<do_GetProgressIndicator>, JS4D::PropertyAttributeNone); // getProgressIndicator( string : progressInfo })
		_PushBackStaticFunction( "BinaryStream", js_callStaticFunction<do_BinaryStream>, JS4D::PropertyAttributeNone); // BinaryStream : BinaryStream( File | stringURL, bool | "Write" "Read");
//		_PushBackStaticFunction( "TextStream", js_callStaticFunction<do_TextStream>, JS4D::PropertyAttributeNone); // TextStream : TextStream( File | stringURL, bool | "Write" "Read", {number:charset});
		_PushBackStaticFunction( "displayNotification", js_callStaticFunction<do_displayNotification>, JS4D::PropertyAttributeNone);
		_PushBackStaticFunction( "XmlToJSON", js_callStaticFunction<do_XmlToJSON>, JS4D::PropertyAttributeNone); // string : XmlToJSON( string : XML text, "simpleJson" "fullJson");
		_PushBackStaticFunction( "JSONToXml", js_callStaticFunction<do_JSONToXml>, JS4D::PropertyAttributeNone); // string : JSONToXml( string : JSON text, "simpleJson" "fullJson");
		_PushBackStaticFunction( "loadImage", js_callStaticFunction<do_loadImage>, JS4D::PropertyAttributeNone); // Picture : LoadImage(File)
		_PushBackStaticFunction( "garbageCollect", js_callStaticFunction<do_garbageCollect>, JS4D::PropertyAttributeNone); 
		_PushBackStaticFunction( "isoToDate", js_callStaticFunction<do_isoToDate>, JS4D::PropertyAttributeNone); 
		_PushBackStaticFunction( "dateToIso", js_callStaticFunction<do_dateToIso>, JS4D::PropertyAttributeNone); 
		_PushBackStaticFunction( "Mutex", js_callStaticFunction<do_AtomicSection>, JS4D::PropertyAttributeNone); 
		_PushBackStaticFunction( "SyncEvent", js_callStaticFunction<do_SyncEvent>, JS4D::PropertyAttributeNone); // object : System ( string : commandLine );
		_PushBackStaticFunction( "loadText", js_callStaticFunction<do_LoadText>, JS4D::PropertyAttributeNone); // string : loadText(File, {number:charset})
		_PushBackStaticFunction( "saveText", js_callStaticFunction<do_SaveText>, JS4D::PropertyAttributeNone); // saveText(text: string, File, {number:charset})
		_PushBackStaticFunction( "getURLPath", js_callStaticFunction<do_GetURLPath>, JS4D::PropertyAttributeNone); // array of string : getURLPath(string:url)
		_PushBackStaticFunction( "getURLQuery", js_callStaticFunction<do_GetURLQuery>, JS4D::PropertyAttributeNone); // object : getURLQuery(string:url)
		
		_PushBackStaticFunction( "generateUUID", js_callStaticFunction<do_GenerateUUID>, JS4D::PropertyAttributeNone); // string : generateUUID();
		_PushBackStaticFunction( "requireNative", js_callStaticFunction<do_Require>, JS4D::PropertyAttributeNone);			// object : require(string:className);

		_PushBackStaticFunction("setTimeout", js_callStaticFunction<VJSTimer::SetTimeout>, JS4D::PropertyAttributeNone);
		_PushBackStaticFunction("clearTimeout", js_callStaticFunction<VJSTimer::ClearTimeout>, JS4D::PropertyAttributeNone);
		_PushBackStaticFunction("setInterval", js_callStaticFunction<VJSTimer::SetInterval>, JS4D::PropertyAttributeNone);
		_PushBackStaticFunction("clearInterval", js_callStaticFunction<VJSTimer::ClearInterval>, JS4D::PropertyAttributeNone);

		_PushBackStaticFunction("close", js_callStaticFunction<VJSWorker::Close>, JS4D::PropertyAttributeNone);
		_PushBackStaticFunction("wait", js_callStaticFunction<VJSWorker::Wait>, JS4D::PropertyAttributeNone);
		_PushBackStaticFunction("exitWait", js_callStaticFunction<VJSWorker::ExitWait>, JS4D::PropertyAttributeNone);

		//_PushBackStaticFunction("SetCurrentUser", js_callStaticFunction<do_SetCurrentUser>, JS4D::PropertyAttributeNone);

		_PushBackStaticFunction( 0, 0, 0);
	}
}
Esempio n. 8
0
bool VProcess::_Init_CheckSystemVersion()
{
	SystemVersion minimalSystemVersion;

#if VERSIONWIN
	minimalSystemVersion = WIN_XP;
#elif VERSIONMAC
	minimalSystemVersion = MAC_OSX_10_6;
#elif VERSION_LINUX
    return true;	// Postponed Linux Implementation !
#else
	assert_compile( false);
#endif

	return DoCheckSystemVersion( minimalSystemVersion);
}
Esempio n. 9
0
/**
 * Returns whether the command is allowed while the game is paused.
 * @param cmd The command to check.
 * @return True if the command is allowed while paused, false otherwise.
 */
bool IsCommandAllowedWhilePaused(uint32 cmd)
{
	/* Lookup table for the command types that are allowed for a given pause level setting. */
	static const int command_type_lookup[] = {
		CMDPL_ALL_ACTIONS,     ///< CMDT_LANDSCAPE_CONSTRUCTION
		CMDPL_NO_LANDSCAPING,  ///< CMDT_VEHICLE_CONSTRUCTION
		CMDPL_NO_LANDSCAPING,  ///< CMDT_MONEY_MANAGEMENT
		CMDPL_NO_CONSTRUCTION, ///< CMDT_VEHICLE_MANAGEMENT
		CMDPL_NO_CONSTRUCTION, ///< CMDT_ROUTE_MANAGEMENT
		CMDPL_NO_CONSTRUCTION, ///< CMDT_OTHER_MANAGEMENT
		CMDPL_NO_CONSTRUCTION, ///< CMDT_COMPANY_SETTING
		CMDPL_NO_ACTIONS,      ///< CMDT_SERVER_SETTING
		CMDPL_NO_ACTIONS,      ///< CMDT_CHEAT
	};
	assert_compile(lengthof(command_type_lookup) == CMDT_END);

	assert(IsValidCommand(cmd));
	return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd & CMD_ID_MASK].type] <= _settings_game.construction.command_pause_level;
}
Esempio n. 10
0
/**
 * Checks whether the MD5 checksums of the files are correct.
 *
 * @note Also checks sample.cat and other required non-NewGRF GRFs for corruption.
 */
void CheckExternalFiles()
{
	if (BaseGraphics::GetUsedSet() == NULL || BaseSounds::GetUsedSet() == NULL) return;

	const GraphicsSet *used_set = BaseGraphics::GetUsedSet();

	DEBUG(grf, 1, "Using the %s base graphics set", used_set->name);

	static const size_t ERROR_MESSAGE_LENGTH = 256;
	static const size_t MISSING_FILE_MESSAGE_LENGTH = 128;

	/* Allocate for a message for each missing file and for one error
	 * message per set.
	 */
	char error_msg[MISSING_FILE_MESSAGE_LENGTH * (GraphicsSet::NUM_FILES + SoundsSet::NUM_FILES) + 2 * ERROR_MESSAGE_LENGTH];
	error_msg[0] = '\0';
	char *add_pos = error_msg;
	const char *last = lastof(error_msg);

	if (used_set->GetNumInvalid() != 0) {
		/* Not all files were loaded successfully, see which ones */
		add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of readme.txt.\n\nThe following files are corrupted or missing:\n", used_set->name);
		for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) {
			MD5File::ChecksumResult res = used_set->files[i].CheckMD5(BASESET_DIR);
			if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning);
		}
		add_pos += seprintf(add_pos, last, "\n");
	}

	const SoundsSet *sounds_set = BaseSounds::GetUsedSet();
	if (sounds_set->GetNumInvalid() != 0) {
		add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of readme.txt.\n\nThe following files are corrupted or missing:\n", sounds_set->name);

		assert_compile(SoundsSet::NUM_FILES == 1);
		/* No need to loop each file, as long as there is only a single
		 * sound file. */
		add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", sounds_set->files->filename, sounds_set->files->CheckMD5(BASESET_DIR) == MD5File::CR_MISMATCH ? "corrupt" : "missing", sounds_set->files->missing_warning);
	}

	if (add_pos != error_msg) ShowInfoF("%s", error_msg);
}
Esempio n. 11
0
/**
 * Engine drawing loop
 * @param type Type of vehicle (VEH_*)
 * @param l The left most location of the list
 * @param r The right most location of the list
 * @param y The top most location of the list
 * @param eng_list What engines to draw
 * @param min where to start in the list
 * @param max where in the list to end
 * @param selected_id what engine to highlight as selected, if any
 * @param show_count Whether to show the amount of engines or not
 * @param selected_group the group to list the engines of
 */
void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group)
{
	static const int sprite_widths[]  = { 60, 60, 76, 67 };
	static const int sprite_y_offsets[] = { -1, -1, -2, -2 };

	/* Obligatory sanity checks! */
	assert((uint)type < lengthof(sprite_widths));
	assert_compile(lengthof(sprite_y_offsets) == lengthof(sprite_widths));
	assert(max <= eng_list->Length());

	bool rtl = _current_text_dir == TD_RTL;
	int step_size = GetEngineListHeight(type);
	int sprite_width = sprite_widths[type];

	int sprite_x        = (rtl ? r - sprite_width / 2 : l + sprite_width / 2) - 1;
	int sprite_y_offset = sprite_y_offsets[type] + step_size / 2;

	int text_left  = l + (rtl ? WD_FRAMERECT_LEFT : sprite_width);
	int text_right = r - (rtl ? sprite_width : WD_FRAMERECT_RIGHT);

	int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2;
	int small_text_y_offset  = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1;

	for (; min < max; min++, y += step_size) {
		const EngineID engine = (*eng_list)[min];
		/* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_company here. */
		const uint num_engines = GetGroupNumEngines(_local_company, selected_group, engine);

		SetDParam(0, engine);
		DrawString(text_left, text_right, y + normal_text_y_offset, STR_ENGINE_NAME, engine == selected_id ? TC_WHITE : TC_BLACK);
		DrawVehicleEngine(l, r, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE);
		if (show_count) {
			SetDParam(0, num_engines);
			DrawString(text_left, text_right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT);
		}
	}
}
Esempio n. 12
0
static FORCEINLINE T *AlignPtr(T *x, uint n)
{
	assert_compile(sizeof(size_t) == sizeof(void *));
	return (T *)Align((size_t)x, n);
}
Esempio n. 13
0
uint32 Station::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
{
	switch (variable) {
		case 0x48: { // Accepted cargo types
			CargoID cargo_type;
			uint32 value = 0;

			for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
				if (HasBit(this->goods[cargo_type].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(value, cargo_type);
			}
			return value;
		}

		case 0x8A: return this->had_vehicle_of_type;
		case 0xF1: return (this->airport.tile != INVALID_TILE) ? this->airport.GetSpec()->ttd_airport_type : ATP_TTDP_LARGE;
		case 0xF2: return (this->truck_stops != NULL) ? this->truck_stops->status : 0;
		case 0xF3: return (this->bus_stops != NULL)   ? this->bus_stops->status   : 0;
		case 0xF6: return this->airport.flags;
		case 0xF7: return GB(this->airport.flags, 8, 8);
	}

	/* Handle cargo variables with parameter, 0x60 to 0x65 and 0x69 */
	if ((variable >= 0x60 && variable <= 0x65) || variable == 0x69) {
		CargoID c = GetCargoTranslation(parameter, object.grffile);

		if (c == CT_INVALID) {
			switch (variable) {
				case 0x62: return 0xFFFFFFFF;
				case 0x64: return 0xFF00;
				default:   return 0;
			}
		}
		const GoodsEntry *ge = &this->goods[c];

		switch (variable) {
			case 0x60: return min(ge->cargo.TotalCount(), 4095);
			case 0x61: return ge->HasVehicleEverTriedLoading() ? ge->time_since_pickup : 0;
			case 0x62: return ge->HasRating() ? ge->rating : 0xFFFFFFFF;
			case 0x63: return ge->cargo.DaysInTransit();
			case 0x64: return ge->HasVehicleEverTriedLoading() ? ge->last_speed | (ge->last_age << 8) : 0xFF00;
			case 0x65: return GB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1) << 3;
			case 0x69: {
				assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 1 == (int)GoodsEntry::GES_LAST_MONTH);
				assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 2 == (int)GoodsEntry::GES_CURRENT_MONTH);
				assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 3 == (int)GoodsEntry::GES_ACCEPTED_BIGTICK);
				return GB(ge->status, GoodsEntry::GES_EVER_ACCEPTED, 4);
			}
		}
	}

	/* Handle cargo variables (deprecated) */
	if (variable >= 0x8C && variable <= 0xEC) {
		const GoodsEntry *g = &this->goods[GB(variable - 0x8C, 3, 4)];
		switch (GB(variable - 0x8C, 0, 3)) {
			case 0: return g->cargo.TotalCount();
			case 1: return GB(min(g->cargo.TotalCount(), 4095), 0, 4) | (GB(g->status, GoodsEntry::GES_ACCEPTANCE, 1) << 7);
			case 2: return g->time_since_pickup;
			case 3: return g->rating;
			case 4: return g->cargo.Source();
			case 5: return g->cargo.DaysInTransit();
			case 6: return g->last_speed;
			case 7: return g->last_age;
		}
	}

	DEBUG(grf, 1, "Unhandled station variable 0x%X", variable);

	*available = false;
	return UINT_MAX;
}
Esempio n. 14
0
static inline T *AlignPtr(T *x, uint n)
{
	assert_compile(sizeof(size_t) == sizeof(void *));
	return (T *)Align((size_t)x, n);
}
Esempio n. 15
0
/**
 * Get the amplitude associated with the currently selected
 * smoothness and maximum height level.
 * @param frequency The frequency to get the amplitudes for
 * @return The amplitudes to apply to the map.
 */
static amplitude_t GetAmplitude(int frequency)
{
	/* Base noise amplitudes (multiplied by 1024) and indexed by "smoothness setting" and log2(frequency).
	 * Used for maps that have their smallest side smaller than 512. */
	static const amplitude_t amplitudes_small[][10] = {
		/* lowest frequency ...... highest (every corner) */
		{60000, 2273, 4142, 2253, 421, 213, 137, 177, 37,  16}, ///< Very smooth
		{50000, 2273, 4142, 2253, 421, 213, 137, 177, 37,  61}, ///< Smooth
		{40000, 2273, 4142, 2253, 421, 213, 137, 177, 37,  91}, ///< Rough
		{30000, 2273, 4142, 2253, 421, 213, 137, 177, 37, 161}, ///< Very rough
	};

	/* Base noise amplitudes (multiplied by 1024) and indexed by "smoothness setting" and log2(frequency).
	 * Used for maps that have their smallest side equal to 512. */
	static const amplitude_t amplitudes_middle[][10] = {
		{55000, 2273, 5142, 253, 2421, 213, 137, 177, 37,  16}, ///< Very smooth
		{45000, 2273, 5142, 253, 2421, 213, 137, 177, 37,  61}, ///< Smooth
		{35000, 2273, 5142, 253, 2421, 213, 137, 177, 37,  91}, ///< Rough
		{25000, 2273, 5142, 253, 2421, 213, 137, 177, 37, 161}, ///< Very rough
	};

	/* Base noise amplitudes (multiplied by 1024) and indexed by "smoothness setting" and log2(frequency).
	 * Used for maps that have their smallest side bigger than 512. */
	static const amplitude_t amplitudes_large[][10] = {
		/* lowest frequency ...... highest (every corner) */
		{55000, 2273, 5142, 253, 421, 2213, 137, 177, 37,  16}, ///< Very smooth
		{45000, 2273, 5142, 253, 421, 2213, 137, 177, 37,  61}, ///< Smooth
		{35000, 2273, 5142, 253, 421, 2213, 137, 177, 37,  91}, ///< Rough
		{25000, 2273, 5142, 253, 421, 2213, 137, 177, 37, 161}, ///< Very rough
	};

	/* Make sure arrays cover all smoothness settings. */
	assert_compile(lengthof(amplitudes_small)  == TGEN_SMOOTHNESS_END);
	assert_compile(lengthof(amplitudes_middle) == TGEN_SMOOTHNESS_END);
	assert_compile(lengthof(amplitudes_large)  == TGEN_SMOOTHNESS_END);

	/* Extrapolation factors for ranges before the table.
	 * The extrapolation is needed to account for the higher map heights. They need larger
	 * areas with a particular gradient so that we are able to create maps without too
	 * many steep slopes up to the wanted height level. It's definitely not perfect since
	 * it will bring larger rectangles with similar slopes which makes the rectangular
	 * behaviour of TGP more noticable. However, these height differentiations cannot
	 * happen over much smaller areas; we basically double the "range" to give a similar
	 * slope for every doubling of map height.
	 */
	static const double extrapolation_factors[] = { 3.3, 2.8, 2.3, 1.8 };

	int smoothness = _settings_game.game_creation.tgen_smoothness;
	int smallest_size = min(_settings_game.game_creation.map_x, _settings_game.game_creation.map_y);

	int index;
	amplitude_t amplitude;
	if (smallest_size < 9) { // Smallest map side is less than 2^9 == 512.
		index = frequency - MAX_TGP_FREQUENCIES + lengthof(amplitudes_small[0]);
		amplitude = amplitudes_small[smoothness][max(0, index)];
	} else if (smallest_size == 9) {
		index = frequency - MAX_TGP_FREQUENCIES + lengthof(amplitudes_middle[0]);
		amplitude = amplitudes_middle[smoothness][max(0, index)];
	} else {
		index = frequency - MAX_TGP_FREQUENCIES + lengthof(amplitudes_large[0]);
		amplitude = amplitudes_large[smoothness][max(0, index)];
	}
	if (index >= 0) return amplitude;

	/* We need to extrapolate the amplitude. */
	double extrapolation_factor = extrapolation_factors[smoothness];
	int height_range = I2H(16);
	do {
		amplitude = (amplitude_t)(extrapolation_factor * (double)amplitude);
		height_range <<= 1;
		index++;
	} while (index < 0);

	return Clamp((TGPGetMaxHeight() - height_range) / height_range, 0, 1) * amplitude;
}
Esempio n. 16
0
/**
 * Actual game loop for the client.
 * @return Whether everything went okay, or not.
 */
/* static */ bool ClientNetworkGameSocketHandler::GameLoop()
{
	_frame_counter++;

	NetworkExecuteLocalCommandQueue();

	extern void StateGameLoop();
	StateGameLoop();

	/* Check if we are in sync! */
	if (_sync_frame != 0) {
		if (_sync_frame == _frame_counter) {
#ifdef NETWORK_SEND_DOUBLE_SEED
			if (_sync_seed_1 != _random.state[0] || _sync_seed_2 != _random.state[1]) {
#else
			if (_sync_seed_1 != _random.state[0]) {
#endif
				NetworkError(STR_NETWORK_ERROR_DESYNC);
				DEBUG(desync, 1, "sync_err: %08x; %02x", _date, _date_fract);
				DEBUG(net, 0, "Sync error detected!");
				my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
				return false;
			}

			/* If this is the first time we have a sync-frame, we
			 *   need to let the server know that we are ready and at the same
			 *   frame as he is.. so we can start playing! */
			if (_network_first_time) {
				_network_first_time = false;
				SendAck();
			}

			_sync_frame = 0;
		} else if (_sync_frame < _frame_counter) {
			DEBUG(net, 1, "Missed frame for sync-test (%d / %d)", _sync_frame, _frame_counter);
			_sync_frame = 0;
		}
	}

	return true;
}


/** Our client's connection. */
ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = NULL;

static uint32 last_ack_frame;

/** One bit of 'entropy' used to generate a salt for the company passwords. */
static uint32 _password_game_seed;
/** The other bit of 'entropy' used to generate a salt for the company passwords. */
static char _password_server_id[NETWORK_SERVER_ID_LENGTH];

/** Maximum number of companies of the currently joined server. */
static uint8 _network_server_max_companies;
/** Maximum number of spectators of the currently joined server. */
static uint8 _network_server_max_spectators;

/** Who would we like to join as. */
CompanyID _network_join_as;

/** Login password from -p argument */
const char *_network_join_server_password = NULL;
/** Company password from -P argument */
const char *_network_join_company_password = NULL;

/** Make sure the server ID length is the same as a md5 hash. */
assert_compile(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);

/***********
 * Sending functions
 *   DEF_CLIENT_SEND_COMMAND has no parameters
 ************/

NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyInformationQuery()
{
	my_client->status = STATUS_COMPANY_INFO;
	_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);

	Packet *p = new Packet(PACKET_CLIENT_COMPANY_INFO);
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}

NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
{
	my_client->status = STATUS_JOIN;
	_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);

	Packet *p = new Packet(PACKET_CLIENT_JOIN);
	p->Send_string(_openttd_revision);
	p->Send_string(_settings_client.network.client_name); // Client name
	p->Send_uint8 (_network_join_as);     // PlayAs
	p->Send_uint8 (NETLANG_ANY);          // Language
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}

NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk()
{
	Packet *p = new Packet(PACKET_CLIENT_NEWGRFS_CHECKED);
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}

NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *password)
{
	Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD);
	p->Send_string(password);
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}