Merge pull request #32 from OpenRCT2/implement/date-tick

Implement date_tick()
This commit is contained in:
Ted John 2018-01-25 18:20:26 +00:00 committed by GitHub
commit cfaf7a9466
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 599 additions and 6 deletions

469
src/openloco/date.cpp Normal file
View File

@ -0,0 +1,469 @@
#include "date.h"
#include "interop/interop.hpp"
#include <limits>
#include <utility>
using namespace openloco::interop;
namespace openloco
{
static loco_global<uint32_t, 0x00525E2C> _current_day;
static loco_global<uint16_t, 0x00525E30> _day_progression;
static loco_global<int16_t, 0x00525E32> _current_year;
static loco_global<int8_t, 0x00525E34> _current_month;
static loco_global<int8_t, 0x00525E35> _current_day_of_month;
static loco_global<int32_t, 0x0112C810> _current_day_in_olympiad;
static std::pair<month_id, uint8_t> get_month_day(int32_t dayOfYear);
uint32_t current_day()
{
return _current_day;
}
date current_date()
{
return date(_current_year, (month_id)(*_current_month), _current_day_of_month);
}
void set_date(const date& date)
{
_current_day_of_month = date.day;
_current_month = (int8_t)date.month;
_current_year = date.year;
}
bool update_day_counter()
{
bool result = false;
constexpr uint16_t increment = 682; // ~17s
// Check if counter is going to wrap
if (_day_progression + increment > std::numeric_limits<uint16_t>::max())
{
_current_day++;
result = true;
}
_day_progression += increment;
return result;
}
// 0x00495C65
// eax: totalDays
// returns:
// eax: year
// ebx: month
// edx: day
date calc_date(uint32_t totalDays)
{
constexpr auto base_year = 1800;
constexpr auto days_in_year = 365;
constexpr auto days_in_olympiad = (365 * 4) + 1;
constexpr auto feb_29 = 31 + 28;
int32_t years = ((totalDays / days_in_olympiad) & 0xFFFF) * 4;
int32_t day = totalDays % days_in_olympiad;
// Count the years and add an extra day for when there isn't leap year
if (day > days_in_year)
{
day -= days_in_year;
day -= 1;
do
{
years++;
day -= days_in_year;
} while (day >= 0);
day += days_in_year;
if (day >= feb_29)
{
day++;
}
}
_current_day_in_olympiad = day;
auto year = base_year + years;
auto monthDay = get_month_day(day);
auto result = date(year, monthDay.first, monthDay.second);
result.day_of_olympiad = day;
return result;
}
static std::pair<month_id, uint8_t> get_month_day(int32_t dayOfYear)
{
// clang-format off
static constexpr std::pair<month_id, uint8_t> month_table[] = {
{ month_id::january, 0 },
{ month_id::january, 1 },
{ month_id::january, 2 },
{ month_id::january, 3 },
{ month_id::january, 4 },
{ month_id::january, 5 },
{ month_id::january, 6 },
{ month_id::january, 7 },
{ month_id::january, 8 },
{ month_id::january, 9 },
{ month_id::january, 10 },
{ month_id::january, 11 },
{ month_id::january, 12 },
{ month_id::january, 13 },
{ month_id::january, 14 },
{ month_id::january, 15 },
{ month_id::january, 16 },
{ month_id::january, 17 },
{ month_id::january, 18 },
{ month_id::january, 19 },
{ month_id::january, 20 },
{ month_id::january, 21 },
{ month_id::january, 22 },
{ month_id::january, 23 },
{ month_id::january, 24 },
{ month_id::january, 25 },
{ month_id::january, 26 },
{ month_id::january, 27 },
{ month_id::january, 28 },
{ month_id::january, 29 },
{ month_id::january, 30 },
{ month_id::february, 0 },
{ month_id::february, 1 },
{ month_id::february, 2 },
{ month_id::february, 3 },
{ month_id::february, 4 },
{ month_id::february, 5 },
{ month_id::february, 6 },
{ month_id::february, 7 },
{ month_id::february, 8 },
{ month_id::february, 9 },
{ month_id::february, 10 },
{ month_id::february, 11 },
{ month_id::february, 12 },
{ month_id::february, 13 },
{ month_id::february, 14 },
{ month_id::february, 15 },
{ month_id::february, 16 },
{ month_id::february, 17 },
{ month_id::february, 18 },
{ month_id::february, 19 },
{ month_id::february, 20 },
{ month_id::february, 21 },
{ month_id::february, 22 },
{ month_id::february, 23 },
{ month_id::february, 24 },
{ month_id::february, 25 },
{ month_id::february, 26 },
{ month_id::february, 27 },
{ month_id::february, 28 },
{ month_id::march, 0 },
{ month_id::march, 1 },
{ month_id::march, 2 },
{ month_id::march, 3 },
{ month_id::march, 4 },
{ month_id::march, 5 },
{ month_id::march, 6 },
{ month_id::march, 7 },
{ month_id::march, 8 },
{ month_id::march, 9 },
{ month_id::march, 10 },
{ month_id::march, 11 },
{ month_id::march, 12 },
{ month_id::march, 13 },
{ month_id::march, 14 },
{ month_id::march, 15 },
{ month_id::march, 16 },
{ month_id::march, 17 },
{ month_id::march, 18 },
{ month_id::march, 19 },
{ month_id::march, 20 },
{ month_id::march, 21 },
{ month_id::march, 22 },
{ month_id::march, 23 },
{ month_id::march, 24 },
{ month_id::march, 25 },
{ month_id::march, 26 },
{ month_id::march, 27 },
{ month_id::march, 28 },
{ month_id::march, 29 },
{ month_id::march, 30 },
{ month_id::april, 0 },
{ month_id::april, 1 },
{ month_id::april, 2 },
{ month_id::april, 3 },
{ month_id::april, 4 },
{ month_id::april, 5 },
{ month_id::april, 6 },
{ month_id::april, 7 },
{ month_id::april, 8 },
{ month_id::april, 9 },
{ month_id::april, 10 },
{ month_id::april, 11 },
{ month_id::april, 12 },
{ month_id::april, 13 },
{ month_id::april, 14 },
{ month_id::april, 15 },
{ month_id::april, 16 },
{ month_id::april, 17 },
{ month_id::april, 18 },
{ month_id::april, 19 },
{ month_id::april, 20 },
{ month_id::april, 21 },
{ month_id::april, 22 },
{ month_id::april, 23 },
{ month_id::april, 24 },
{ month_id::april, 25 },
{ month_id::april, 26 },
{ month_id::april, 27 },
{ month_id::april, 28 },
{ month_id::april, 29 },
{ month_id::may, 0 },
{ month_id::may, 1 },
{ month_id::may, 2 },
{ month_id::may, 3 },
{ month_id::may, 4 },
{ month_id::may, 5 },
{ month_id::may, 6 },
{ month_id::may, 7 },
{ month_id::may, 8 },
{ month_id::may, 9 },
{ month_id::may, 10 },
{ month_id::may, 11 },
{ month_id::may, 12 },
{ month_id::may, 13 },
{ month_id::may, 14 },
{ month_id::may, 15 },
{ month_id::may, 16 },
{ month_id::may, 17 },
{ month_id::may, 18 },
{ month_id::may, 19 },
{ month_id::may, 20 },
{ month_id::may, 21 },
{ month_id::may, 22 },
{ month_id::may, 23 },
{ month_id::may, 24 },
{ month_id::may, 25 },
{ month_id::may, 26 },
{ month_id::may, 27 },
{ month_id::may, 28 },
{ month_id::may, 29 },
{ month_id::may, 30 },
{ month_id::june, 0 },
{ month_id::june, 1 },
{ month_id::june, 2 },
{ month_id::june, 3 },
{ month_id::june, 4 },
{ month_id::june, 5 },
{ month_id::june, 6 },
{ month_id::june, 7 },
{ month_id::june, 8 },
{ month_id::june, 9 },
{ month_id::june, 10 },
{ month_id::june, 11 },
{ month_id::june, 12 },
{ month_id::june, 13 },
{ month_id::june, 14 },
{ month_id::june, 15 },
{ month_id::june, 16 },
{ month_id::june, 17 },
{ month_id::june, 18 },
{ month_id::june, 19 },
{ month_id::june, 20 },
{ month_id::june, 21 },
{ month_id::june, 22 },
{ month_id::june, 23 },
{ month_id::june, 24 },
{ month_id::june, 25 },
{ month_id::june, 26 },
{ month_id::june, 27 },
{ month_id::june, 28 },
{ month_id::june, 29 },
{ month_id::july, 0 },
{ month_id::july, 1 },
{ month_id::july, 2 },
{ month_id::july, 3 },
{ month_id::july, 4 },
{ month_id::july, 5 },
{ month_id::july, 6 },
{ month_id::july, 7 },
{ month_id::july, 8 },
{ month_id::july, 9 },
{ month_id::july, 10 },
{ month_id::july, 11 },
{ month_id::july, 12 },
{ month_id::july, 13 },
{ month_id::july, 14 },
{ month_id::july, 15 },
{ month_id::july, 16 },
{ month_id::july, 17 },
{ month_id::july, 18 },
{ month_id::july, 19 },
{ month_id::july, 20 },
{ month_id::july, 21 },
{ month_id::july, 22 },
{ month_id::july, 23 },
{ month_id::july, 24 },
{ month_id::july, 25 },
{ month_id::july, 26 },
{ month_id::july, 27 },
{ month_id::july, 28 },
{ month_id::july, 29 },
{ month_id::july, 30 },
{ month_id::august, 0 },
{ month_id::august, 1 },
{ month_id::august, 2 },
{ month_id::august, 3 },
{ month_id::august, 4 },
{ month_id::august, 5 },
{ month_id::august, 6 },
{ month_id::august, 7 },
{ month_id::august, 8 },
{ month_id::august, 9 },
{ month_id::august, 10 },
{ month_id::august, 11 },
{ month_id::august, 12 },
{ month_id::august, 13 },
{ month_id::august, 14 },
{ month_id::august, 15 },
{ month_id::august, 16 },
{ month_id::august, 17 },
{ month_id::august, 18 },
{ month_id::august, 19 },
{ month_id::august, 20 },
{ month_id::august, 21 },
{ month_id::august, 22 },
{ month_id::august, 23 },
{ month_id::august, 24 },
{ month_id::august, 25 },
{ month_id::august, 26 },
{ month_id::august, 27 },
{ month_id::august, 28 },
{ month_id::august, 29 },
{ month_id::august, 30 },
{ month_id::september, 0 },
{ month_id::september, 1 },
{ month_id::september, 2 },
{ month_id::september, 3 },
{ month_id::september, 4 },
{ month_id::september, 5 },
{ month_id::september, 6 },
{ month_id::september, 7 },
{ month_id::september, 8 },
{ month_id::september, 9 },
{ month_id::september, 10 },
{ month_id::september, 11 },
{ month_id::september, 12 },
{ month_id::september, 13 },
{ month_id::september, 14 },
{ month_id::september, 15 },
{ month_id::september, 16 },
{ month_id::september, 17 },
{ month_id::september, 18 },
{ month_id::september, 19 },
{ month_id::september, 20 },
{ month_id::september, 21 },
{ month_id::september, 22 },
{ month_id::september, 23 },
{ month_id::september, 24 },
{ month_id::september, 25 },
{ month_id::september, 26 },
{ month_id::september, 27 },
{ month_id::september, 28 },
{ month_id::september, 29 },
{ month_id::october, 0 },
{ month_id::october, 1 },
{ month_id::october, 2 },
{ month_id::october, 3 },
{ month_id::october, 4 },
{ month_id::october, 5 },
{ month_id::october, 6 },
{ month_id::october, 7 },
{ month_id::october, 8 },
{ month_id::october, 9 },
{ month_id::october, 10 },
{ month_id::october, 11 },
{ month_id::october, 12 },
{ month_id::october, 13 },
{ month_id::october, 14 },
{ month_id::october, 15 },
{ month_id::october, 16 },
{ month_id::october, 17 },
{ month_id::october, 18 },
{ month_id::october, 19 },
{ month_id::october, 20 },
{ month_id::october, 21 },
{ month_id::october, 22 },
{ month_id::october, 23 },
{ month_id::october, 24 },
{ month_id::october, 25 },
{ month_id::october, 26 },
{ month_id::october, 27 },
{ month_id::october, 28 },
{ month_id::october, 29 },
{ month_id::october, 30 },
{ month_id::november, 0 },
{ month_id::november, 1 },
{ month_id::november, 2 },
{ month_id::november, 3 },
{ month_id::november, 4 },
{ month_id::november, 5 },
{ month_id::november, 6 },
{ month_id::november, 7 },
{ month_id::november, 8 },
{ month_id::november, 9 },
{ month_id::november, 10 },
{ month_id::november, 11 },
{ month_id::november, 12 },
{ month_id::november, 13 },
{ month_id::november, 14 },
{ month_id::november, 15 },
{ month_id::november, 16 },
{ month_id::november, 17 },
{ month_id::november, 18 },
{ month_id::november, 19 },
{ month_id::november, 20 },
{ month_id::november, 21 },
{ month_id::november, 22 },
{ month_id::november, 23 },
{ month_id::november, 24 },
{ month_id::november, 25 },
{ month_id::november, 26 },
{ month_id::november, 27 },
{ month_id::november, 28 },
{ month_id::november, 29 },
{ month_id::december, 0 },
{ month_id::december, 1 },
{ month_id::december, 2 },
{ month_id::december, 3 },
{ month_id::december, 4 },
{ month_id::december, 5 },
{ month_id::december, 6 },
{ month_id::december, 7 },
{ month_id::december, 8 },
{ month_id::december, 9 },
{ month_id::december, 10 },
{ month_id::december, 11 },
{ month_id::december, 12 },
{ month_id::december, 13 },
{ month_id::december, 14 },
{ month_id::december, 15 },
{ month_id::december, 16 },
{ month_id::december, 17 },
{ month_id::december, 18 },
{ month_id::december, 19 },
{ month_id::december, 20 },
{ month_id::december, 21 },
{ month_id::december, 22 },
{ month_id::december, 23 },
{ month_id::december, 24 },
{ month_id::december, 25 },
{ month_id::december, 26 },
{ month_id::december, 27 },
{ month_id::december, 28 },
{ month_id::december, 29 },
{ month_id::december, 30 },
};
// clang-format on
return month_table[dayOfYear];
}
}

52
src/openloco/date.h Normal file
View File

@ -0,0 +1,52 @@
#pragma once
#include <cstdint>
namespace openloco
{
enum class month_id
{
january,
february,
march,
april,
may,
june,
july,
august,
september,
october,
november,
december
};
struct date
{
int32_t day = 0;
month_id month;
int32_t year = 0;
// 0x0112C810 originally used as a return argument in calc_date
int32_t day_of_olympiad = 0;
date() = default;
date(int32_t y, month_id m, int32_t d)
: year(y)
, month(m)
, day(d)
{
}
};
uint32_t current_day();
date current_date();
void set_date(const date& date);
/**
* Updates the current day counter.
* @returns true if the counter wraps indicating a new day.
*/
bool update_day_counter();
date calc_date(uint32_t totalDays);
}

View File

@ -17,6 +17,7 @@
#include "audio/audio.h"
#include "config.h"
#include "date.h"
#include "environment.h"
#include "graphics/gfx.h"
#include "input.h"
@ -68,9 +69,10 @@ namespace openloco
loco_global<uint32_t, 0x00525E1C> _srand1;
loco_global<uint32_t, 0x00525F5E> _scenario_ticks;
void tick_logic(int32_t count);
void tick_logic();
void tick_wait();
static void tick_logic(int32_t count);
static void tick_logic();
static void tick_wait();
static void date_tick();
#ifdef _WIN32
void* hInstance()
@ -507,7 +509,7 @@ namespace openloco
tick_wait();
}
void tick_logic(int32_t count)
static void tick_logic(int32_t count)
{
for (int32_t i = 0; i < count; i++)
{
@ -522,7 +524,7 @@ namespace openloco
}
// 0x0046ABCB
void tick_logic()
static void tick_logic()
{
_scenario_ticks++;
addr<0x00525F64, int32_t>()++;
@ -530,7 +532,7 @@ namespace openloco
addr<0x00525FD0, int32_t>() = _srand1;
call(0x004613F0);
addr<0x00F25374, uint8_t>() = addr<0x009C871C, uint8_t>();
call(0x004968C7);
date_tick();
call(0x00463ABA);
call(0x004C56F6);
call(0x00496B6D);
@ -561,6 +563,74 @@ namespace openloco
}
}
static void sub_496A84(int32_t edx)
{
// This is responsible for updating the snow line
registers regs;
regs.edx = edx;
call(0x00496A84, regs);
}
// 0x004968C7
static void date_tick()
{
if ((addr<0x00525E28, uint32_t>() & 1) && !is_editor_mode())
{
if (update_day_counter())
{
call(0x0048B244);
call(0x004B94CF);
call(0x00453487);
call(0x004284DB);
call(0x004969DA);
call(0x00439BA5);
auto yesterday = calc_date(current_day() - 1);
auto today = calc_date(current_day());
set_date(today);
sub_496A84(today.day_of_olympiad);
if (today.month != yesterday.month)
{
// End of every month
addr<0x0050A004, uint16_t>() += 2;
addr<0x00526243, uint16_t>()++;
call(0x0049748C);
call(0x0045383B);
call(0x0043037B);
call(0x0042F213);
call(0x004C3C54);
if (today.year <= 2029)
{
call(0x0046E239);
}
// clang-format off
if (today.month == month_id::january ||
today.month == month_id::april ||
today.month == month_id::july ||
today.month == month_id::october)
// clang-format on
{
// Start of every season?
call(0x00487FC1);
}
if (today.year != yesterday.year)
{
// End of every year
call(0x004312C7);
call(0x004796A9);
call(0x004C3A9E);
call(0x0047AB9B);
}
}
call(0x00437FB8);
}
}
}
// 0x0046AD4D
void tick_wait()
{

View File

@ -17,6 +17,7 @@
<ClCompile Include="audio\audio.cpp" />
<ClCompile Include="config.cpp" />
<ClCompile Include="console.cpp" />
<ClCompile Include="date.cpp" />
<ClCompile Include="envionment.cpp" />
<ClCompile Include="input.cpp" />
<ClCompile Include="interop\hooks.cpp" />
@ -52,6 +53,7 @@
<ClInclude Include="audio\audio.h" />
<ClInclude Include="config.h" />
<ClInclude Include="console.h" />
<ClInclude Include="date.h" />
<ClInclude Include="environment.h" />
<ClInclude Include="graphics\colours.h" />
<ClInclude Include="input.h" />