File diff r27883:ddbd33508a8a → r27884:803962be0328
src/timer/timer_game_calendar.h
Show inline comments
 
@@ -33,6 +33,29 @@
 
 */
 
class TimerGameCalendar {
 
public:
 
	/** The type to store our dates in. */
 
	using Date = StrongType::Typedef<int32_t, struct DateTag, StrongType::Compare, StrongType::Integer>;
 

	
 
	/** The fraction of a date we're in, i.e. the number of ticks since the last date changeover. */
 
	using DateFract = uint16_t;
 

	
 
	/** Type for the year, note: 0 based, i.e. starts at the year 0. */
 
	using Year = StrongType::Typedef<int32_t, struct YearTag, StrongType::Compare, StrongType::Integer>;
 
	/** Type for the month, note: 0 based, i.e. 0 = January, 11 = December. */
 
	using Month = uint8_t;
 
	/** Type for the day of the month, note: 1 based, first day of a month is 1. */
 
	using Day = uint8_t;
 

	
 
	/**
 
	 * Data structure to convert between Date and triplet (year, month, and day).
 
	 * @see TimerGameCalendar::ConvertDateToYMD(), TimerGameCalendar::ConvertYMDToDate()
 
	 */
 
	struct YearMonthDay {
 
		Year  year;   ///< Year (0...)
 
		Month month;  ///< Month (0..11)
 
		Day   day;    ///< Day (1..31)
 
	};
 

	
 
	enum Trigger {
 
		DAY,
 
		WEEK,
 
@@ -77,33 +100,35 @@ public:
 
	struct TStorage {
 
	};
 

	
 
	/** The type to store our dates in. */
 
	using Date = StrongType::Typedef<int32_t, struct DateTag, StrongType::Compare, StrongType::Integer>;
 

	
 
	/** The fraction of a date we're in, i.e. the number of ticks since the last date changeover. */
 
	using DateFract = uint16_t;
 

	
 
	/** Type for the year, note: 0 based, i.e. starts at the year 0. */
 
	using Year = StrongType::Typedef<int32_t, struct YearTag, StrongType::Compare, StrongType::Integer>;
 
	/** Type for the month, note: 0 based, i.e. 0 = January, 11 = December. */
 
	using Month = uint8_t;
 
	/** Type for the day of the month, note: 1 based, first day of a month is 1. */
 
	using Day = uint8_t;
 
	static bool IsLeapYear(Year yr);
 
	static void ConvertDateToYMD(Date date, YearMonthDay * ymd);
 
	static Date ConvertYMDToDate(Year year, Month month, Day day);
 
	static void SetDate(Date date, DateFract fract);
 

	
 
	/**
 
	 * Data structure to convert between Date and triplet (year, month, and day).
 
	 * @see TimerGameCalendar::ConvertDateToYMD(), TimerGameCalendar::ConvertYMDToDate()
 
	 */
 
	struct YearMonthDay {
 
		Year  year;   ///< Year (0...)
 
		Month month;  ///< Month (0..11)
 
		Day   day;    ///< Day (1..31)
 
	};
 
	* Calculate the year of a given date.
 
	* @param date The date to consider.
 
	* @return the year.
 
	*/
 
	static constexpr Year DateToYear(Date date)
 
	{
 
		/* Hardcode the number of days in a year because we can't access CalendarTime from here. */
 
		return static_cast<int32_t>(date) / 366;
 
	}
 

	
 
	static bool IsLeapYear(TimerGameCalendar::Year yr);
 
	static void ConvertDateToYMD(TimerGameCalendar::Date date, YearMonthDay *ymd);
 
	static TimerGameCalendar::Date ConvertYMDToDate(TimerGameCalendar::Year year, TimerGameCalendar::Month month, TimerGameCalendar::Day day);
 
	static void SetDate(TimerGameCalendar::Date date, TimerGameCalendar::DateFract fract);
 
	/**
 
	* Calculate the date of the first day of a given year.
 
	* @param year the year to get the first day of.
 
	* @return the date.
 
	*/
 
	static constexpr Date DateAtStartOfYear(Year year)
 
	{
 
		int32_t year_as_int = static_cast<int32_t>(year);
 
		uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1);
 

	
 
		/* Hardcode the number of days in a year because we can't access CalendarTime from here. */
 
		return (365 * year_as_int) + number_of_leap_years;
 
	}
 

	
 
	static Year year; ///< Current year, starting at 0.
 
	static Month month; ///< Current month (0..11).
 
@@ -111,4 +136,53 @@ public:
 
	static DateFract date_fract; ///< Fractional part of the day.
 
};
 

	
 
/**
 
 * Storage class for Calendar time constants.
 
 */
 
class CalendarTime {
 
public:
 
	static constexpr int DAYS_IN_YEAR = 365; ///< days per year
 
	static constexpr int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more...
 
	static constexpr int MONTHS_IN_YEAR = 12; ///< months per year
 

	
 
	static constexpr int SECONDS_PER_DAY = 2;   ///< approximate seconds per day, not for precise calculations
 

	
 
	/*
 
	 * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are
 
	 * primarily used for loading newgrf and savegame data and returning some
 
	 * newgrf (callback) functions that were in the original (TTD) inherited
 
	 * format, where 'TimerGameCalendar::date == 0' meant that it was 1920-01-01.
 
	 */
 

	
 
	/** The minimum starting year/base year of the original TTD */
 
	static constexpr TimerGameCalendar::Year ORIGINAL_BASE_YEAR = 1920;
 
	/** The original ending year */
 
	static constexpr TimerGameCalendar::Year ORIGINAL_END_YEAR = 2051;
 
	/** The maximum year of the original TTD */
 
	static constexpr TimerGameCalendar::Year ORIGINAL_MAX_YEAR = 2090;
 

	
 
	/** The absolute minimum & maximum years in OTTD */
 
	static constexpr TimerGameCalendar::Year MIN_YEAR = 0;
 

	
 
	/** The default starting year */
 
	static constexpr TimerGameCalendar::Year DEF_START_YEAR = 1950;
 
	/** The default scoring end year */
 
	static constexpr TimerGameCalendar::Year DEF_END_YEAR = ORIGINAL_END_YEAR - 1;
 

	
 
	/**
 
	 * MAX_YEAR, nicely rounded value of the number of years that can
 
	 * be encoded in a single 32 bits date, about 2^31 / 366 years.
 
	 */
 
	static constexpr TimerGameCalendar::Year MAX_YEAR = 5000000;
 

	
 
	/** The date of the first day of the original base year. */
 
	static constexpr TimerGameCalendar::Date DAYS_TILL_ORIGINAL_BASE_YEAR = TimerGameCalendar::DateAtStartOfYear(ORIGINAL_BASE_YEAR);
 

	
 
	/** The date of the last day of the max year. */
 
	static constexpr TimerGameCalendar::Date MAX_DATE = TimerGameCalendar::DateAtStartOfYear(CalendarTime::MAX_YEAR + 1) - 1;
 

	
 
	static constexpr TimerGameCalendar::Year INVALID_YEAR = -1; ///< Representation of an invalid year
 
	static constexpr TimerGameCalendar::Date INVALID_DATE = -1; ///< Representation of an invalid date
 
};
 

	
 
#endif /* TIMER_GAME_CALENDAR_H */