Files @ r13257:4c5b8120be59
Branch filter:

Location: cpp/openttd-patchpack/source/src/settings_internal.h

rubidium
(svn r17776) -Codechange: [SDL] make "update the video card"-process asynchronious. Profiling with gprof etc. hasn't shown us that DrawSurfaceToScreen takes a significant amount of CPU; only using TIC/TOC it became apparant that it was a heavy CPU-cycle user or that it was waiting for something.
The benefit of making this function asynchronious ranges from 2%-25% (real time) during fast forward on dual core/hyperthreading-enabled CPUs; 8bpp improvements are, in my test cases, significantly smaller than 32bpp improvements.
On single core non-hyperthreading-enabled CPUs the extra locking/scheduling costs up to 1% extra realtime in fast forward. You can use -v sdl:no_threads to disable threading and undo this loss.
During normal non-fast-forwarded games the benefit/costs are negligable except when the gameloop takes more than about 90% of the time of a tick.
Note that allegro's performance does not improve with this system, likely due to their way of getting data to the video card. It is not implemented for the OS X/Windows video backends, unless (ofcourse) SDL is used there.
Funny is that the performance of the 32bpp(-anim) blitter is, at least in some test cases, significantly faster (more than 10%) than the 8bpp(-optimized) blitter when looking at real time in fast forward on a dual core CPU; it was slower.
The idea comes from a paper/report by Idar Borlaug and Knut Imar Hagen.
/* $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 settings_internal.h Functions and types used internally for the settings configurations. */

#ifndef SETTINGS_INTERNAL_H
#define SETTINGS_INTERNAL_H

#include "saveload/saveload.h"
#include "settings_type.h"

/** Convention/Type of settings. This is then further specified if necessary
 * with the SLE_ (SLE_VAR/SLE_FILE) enums in saveload.h
 * @see VarTypes
 * @see SettingDescBase */
enum SettingDescTypeLong {
	/* 4 bytes allocated a maximum of 16 types for GenericType */
	SDT_BEGIN       = 0,
	SDT_NUMX        = 0, ///< any number-type
	SDT_BOOLX       = 1, ///< a boolean number
	SDT_ONEOFMANY   = 2, ///< bitmasked number where only ONE bit may be set
	SDT_MANYOFMANY  = 3, ///< bitmasked number where MULTIPLE bits may be set
	SDT_INTLIST     = 4, ///< list of integers seperated by a comma ','
	SDT_STRING      = 5, ///< string with a pre-allocated buffer
	SDT_END,
	/* 10 more possible primitives */
};
typedef SimpleTinyEnumT<SettingDescTypeLong, byte> SettingDescType;


enum SettingGuiFlagLong {
	/* 1 byte allocated for a maximum of 8 flags
	 * Flags directing saving/loading of a variable */
	SGF_NONE = 0,
	SGF_0ISDISABLED  = 1 << 0, ///< a value of zero means the feature is disabled
	SGF_NOCOMMA      = 1 << 1, ///< number without any thousand seperators (no formatting)
	SGF_MULTISTRING  = 1 << 2, ///< the value represents a limited number of string-options (internally integer)
	SGF_NETWORK_ONLY = 1 << 3, ///< this setting only applies to network games
	SGF_CURRENCY     = 1 << 4, ///< the number represents money, so when reading value multiply by exchange rate
	SGF_NO_NETWORK   = 1 << 5, ///< this setting does not apply to network games; it may not be changed during the game
	SGF_NEWGAME_ONLY = 1 << 6, ///< this setting cannot be changed in a game
	SGF_SCENEDIT_TOO = 1 << 7, ///< this setting can be changed in the scenario editor (only makes sense when SGF_NEWGAME_ONLY is set)
	SGF_PER_COMPANY  = 1 << 8, ///< this setting can be different for each company (saved in company struct)
};
DECLARE_ENUM_AS_BIT_SET(SettingGuiFlagLong);
typedef SimpleTinyEnumT<SettingGuiFlagLong, uint16> SettingGuiFlag;


typedef bool OnChange(int32 var);           ///< callback prototype on data modification
typedef int32 OnConvert(const char *value); ///< callback prototype for convertion error

struct SettingDescBase {
	const char *name;       ///< name of the setting. Used in configuration file and for console
	const void *def;        ///< default value given when none is present
	SettingDescType cmd;    ///< various flags for the variable
	SettingGuiFlag flags;   ///< handles how a setting would show up in the GUI (text/currency, etc.)
	int32 min;              ///< minimum values
	uint32 max;             ///< maximum values
	int32 interval;         ///< the interval to use between settings in the 'settings' window. If interval is '0' the interval is dynamically determined
	const char *many;       ///< ONE/MANY_OF_MANY: string of possible values for this type
	StringID str;           ///< (translated) string with descriptive text; gui and console
	OnChange *proc;         ///< callback procedure for when the value is changed
	OnConvert *proc_cnvt;   ///< callback procedure when loading value mechanism fails
};

struct SettingDesc {
	SettingDescBase desc;   ///< Settings structure (going to configuration file)
	SaveLoad save;          ///< Internal structure (going to savegame, parts to config)
};

/* NOTE: The only difference between SettingDesc and SettingDescGlob is
 * that one uses global variables as a source and the other offsets
 * in a struct which are bound to a certain variable during runtime.
 * The only way to differentiate between these two is to check if an object
 * has been passed to the function or not. If not, then it is a global variable
 * and save->variable has its address, otherwise save->variable only holds the
 * offset in a certain struct */
typedef SettingDesc SettingDescGlobVarList;

const SettingDesc *GetSettingFromName(const char *name, uint *i);
bool SetSettingValue(uint index, int32 value);
bool SetSettingValue(uint index, const char *value);
void SetCompanySetting(uint index, int32 value);

extern VehicleDefaultSettings _old_vds;

#endif /* SETTINGS_H */