Skip to content

Commit

Permalink
first pass time of day calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
fallahn committed Nov 9, 2024
1 parent 9986d64 commit cfdce91
Show file tree
Hide file tree
Showing 7 changed files with 355 additions and 29 deletions.
2 changes: 2 additions & 0 deletions libsocial/include/Social.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,6 @@ class Social final

static void showWebPage(const std::string&) {}
static void readAllStats();

static bool getLatLon() { return false; }
};
2 changes: 2 additions & 0 deletions samples/golf/golf.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@
<ClCompile Include="src\golf\TerrainChunks.cpp" />
<ClCompile Include="src\golf\TerrainDepthmap.cpp" />
<ClCompile Include="src\golf\TextChat.cpp" />
<ClCompile Include="src\golf\TimeOfDay.cpp" />
<ClCompile Include="src\golf\TrophyDisplaySystem.cpp" />
<ClCompile Include="src\golf\TrophyState.cpp" />
<ClCompile Include="src\golf\TutorialDirector.cpp" />
Expand Down Expand Up @@ -859,6 +860,7 @@
<ClInclude Include="src\golf\TextAnimCallback.hpp" />
<ClInclude Include="src\golf\TextChat.hpp" />
<ClInclude Include="src\golf\Thumbsticks.hpp" />
<ClInclude Include="src\golf\TimeOfDay.hpp" />
<ClInclude Include="src\golf\Treeset.hpp" />
<ClInclude Include="src\golf\TrophyDisplaySystem.hpp" />
<ClInclude Include="src\golf\TrophyState.hpp" />
Expand Down
18 changes: 15 additions & 3 deletions samples/golf/golf.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@
<Filter Include="Source Files\scrub">
<UniqueIdentifier>{4ba8aac9-a5e8-479b-b1da-bce7d195fb06}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\golf\client\time of day">
<UniqueIdentifier>{53f50006-c51f-4812-b3b9-fa5904be7d82}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\golf\client\time of day">
<UniqueIdentifier>{be9dd921-53a3-46e0-a093-6cb68606eb52}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\LoadingScreen.cpp">
Expand Down Expand Up @@ -496,7 +502,10 @@
<Filter>Source Files\scrub</Filter>
</ClCompile>
<ClCompile Include="src\Sunclock.cpp">
<Filter>Source Files\golf\client</Filter>
<Filter>Source Files\golf\client\time of day</Filter>
</ClCompile>
<ClCompile Include="src\golf\TimeOfDay.cpp">
<Filter>Source Files\golf\client\time of day</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
Expand Down Expand Up @@ -1023,10 +1032,13 @@
<Filter>Header Files\scrub</Filter>
</ClInclude>
<ClInclude Include="src\Sunclock.hpp">
<Filter>Header Files\golf\client</Filter>
<Filter>Header Files\golf\client\time of day</Filter>
</ClInclude>
<ClInclude Include="src\LatLong.hpp">
<Filter>Header Files</Filter>
<Filter>Header Files\golf\client\time of day</Filter>
</ClInclude>
<ClInclude Include="src\golf\TimeOfDay.hpp">
<Filter>Header Files\golf\client\time of day</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions samples/golf/src/golf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ set(GOLF_SRC
${PROJECT_DIR}/golf/TerrainChunks.cpp
${PROJECT_DIR}/golf/TerrainDepthmap.cpp
${PROJECT_DIR}/golf/TextChat.cpp
${PROJECT_DIR}/golf/TimeOfDay.cpp
${PROJECT_DIR}/golf/TrophyDisplaySystem.cpp
${PROJECT_DIR}/golf/TrophyState.cpp
${PROJECT_DIR}/golf/TutorialDirector.cpp
Expand Down
35 changes: 9 additions & 26 deletions samples/golf/src/golf/MenuState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ source distribution.
#include "Clubs.hpp"
#include "HoleData.hpp"
#include "League.hpp"
#include "TimeOfDay.hpp"
#include "../ErrorCheck.hpp"

#include <Achievements.hpp>
Expand Down Expand Up @@ -1791,40 +1792,22 @@ void MenuState::createScene()
}
else
{
const auto hour = cro::SysTime::now().hours();
switch (hour)
TimeOfDay tod;
auto td = tod.getTimeOfDay();

switch (td)
{
default:
case 21:
case 22:
case 23:
case 0:
case 1:
case 2:
case 3:
case 4:
case TimeOfDay::Night:
propFilePath = "00.bgd";
break;
case 5:
case TimeOfDay::Morning:
propFilePath = "01.bgd";
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case TimeOfDay::Day:
propFilePath = "02.bgd";
break;
case 20:
case TimeOfDay::Evening:
propFilePath = "03.bgd";
break;
}
Expand Down
266 changes: 266 additions & 0 deletions samples/golf/src/golf/TimeOfDay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
/*-----------------------------------------------------------------------
Matt Marchant 2024
http://trederia.blogspot.com
Super Video Golf - zlib licence.
This software is provided 'as-is', without any express or
implied warranty.In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions :
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but
is not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any
source distribution.
-----------------------------------------------------------------------*/

#include "TimeOfDay.hpp"
#include "../Sunclock.hpp"
#include "../LatLong.hpp"

#include <Social.hpp>

#include <crogine/core/ConfigFile.hpp>
#include <crogine/core/SysTime.hpp>
#include <crogine/detail/glm/gtx/norm.hpp>

#ifdef _WIN32
#include <winnls.h>
#endif

namespace
{
constexpr float MinLat = -90.f;
constexpr float MaxLat = -90.f;

constexpr float MinLon = -180.f;
constexpr float MaxLon = 180.f;

constexpr std::time_t FourWeeks = 28 * 24 * 60 * 60;

const std::string DataFile("latlon.pos");
}

TimeOfDay::TimeOfDay()
: m_latlon(0.f)
{
//attempt to read local data file
const auto path = Social::getBaseContentPath() + DataFile;

//if file doesn't exist, refresh
if (!cro::FileSystem::fileExists(path))
{
updateLatLon();
}
else //if file does exist but timestamp > 28 days, refresh
{
cro::ConfigFile cfg;
if (cfg.loadFromFile(path, false))
{
std::uint32_t ts = 0;
for (const auto& prop : cfg.getProperties())
{
if (prop.getName() == "lat_lon")
{
m_latlon = prop.getValue<glm::vec2>();
m_latlon.x = std::clamp(m_latlon.x, MinLat, MaxLat);
m_latlon.y = std::clamp(m_latlon.y, MinLon, MaxLon);
}
else if (prop.getName() == "timestamp")
{
ts = prop.getValue<std::uint32_t>();
}
}

auto tsNow = std::time(nullptr);
if (ts == 0
|| ts > tsNow
|| (tsNow - ts) > FourWeeks)
{
updateLatLon();
}
}
else
{
updateLatLon();
}
}
}

//public
std::int32_t TimeOfDay::getTimeOfDay() const
{
if (/*glm::length2(m_latlon) == 0*/false)
{
//take a best guess based on the system time
//I mean technically 0, 0 is valid but it's unlikely
//we're playing golf in the gulf (groan) of Guinea
const auto hour = cro::SysTime::now().hours();
switch (hour)
{
default:
case 21:
case 22:
case 23:
case 0:
case 1:
case 2:
case 3:
case 4:
return Night;
case 5:
return Morning;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
return Day;
case 20:
return Evening;
break;
}
}
else
{
//calculate the sunrise / sunset based on local time
//and our lat/lon
//sunrise / sunset is +/- 30 mins of calc'd time
//else return day or night.
auto ts = std::time(nullptr);
std::tm* gmtm = std::gmtime(&ts);
std::tm* localtm = std::localtime(&ts);

auto hourDiff = localtm->tm_hour - gmtm->tm_hour;
auto dayDiff = localtm->tm_yday - gmtm->tm_yday;
auto yearDiff = localtm->tm_year - gmtm->tm_year;

dayDiff -= (365 * yearDiff); //so this will be wrong on Jan 1st every 4 years... meh.
hourDiff -= (24 * dayDiff);
hourDiff = std::clamp(hourDiff, -12, 12);

Sunclock sunclock(m_latlon.x, m_latlon.y, static_cast<double>(hourDiff));

auto sunrise = sunclock.sunrise();
auto* risetm = std::localtime(&sunrise);

if (risetm->tm_hour == localtm->tm_hour)
{
return Morning;
}

//LogI << "Sun rise is " << risetm->tm_hour << ":" << risetm->tm_min << std::endl;

auto sunset = sunclock.sunset();
auto* settm = std::localtime(&sunset);

if (settm->tm_hour == localtm->tm_hour)
{
return Evening;
}

//LogI << "Sun set is " << settm->tm_hour << ":" << settm->tm_min << std::endl;

if (localtm->tm_hour > risetm->tm_hour
&& localtm->tm_hour < settm->tm_hour)
{
return Day;
}
return Night;
}

return Day;
}

void TimeOfDay::setLatLon(glm::vec2 latlon)
{
m_latlon = latlon;
m_latlon.x = std::clamp(m_latlon.x, MinLat, MaxLat);
m_latlon.y = std::clamp(m_latlon.y, MinLon, MaxLon);

writeDataFile();
}

//private
void TimeOfDay::updateLatLon()
{
m_latlon = { 0.f, 0.f };

//query web latlon - async so if we return true wait for the result message
if (!Social::getLatLon()) //webAPI for open sauce, else use steam
{
//if we failed try querying the OS
auto countryCode = getCountryCode();

//look up in table
if (LatLong.count(countryCode))
{
m_latlon = LatLong.at(countryCode);
}
}

writeDataFile();
}

std::string TimeOfDay::getCountryCode()
{
std::string retVal;
#ifdef USE_GNS
//query Steam
retVal = Social::getCountryCode();
#endif

if (retVal.empty())
{
//query the OS
#ifdef _WIN32
static constexpr std::int32_t BuffSize = 8;
WCHAR buffer[BuffSize] = { 0 };
if (auto charCount = GetUserDefaultGeoName(buffer, BuffSize); charCount == 0)
{
retVal = "US";
}
else
{
cro::String temp = cro::String::fromUtf16(std::begin(buffer), std::begin(buffer) + charCount);
retVal = temp.toAnsiString();
}
#else
//TODO figure out linux.
//mac... well probably toughS
retVal = "US";
#endif
}
return retVal;
}

void TimeOfDay::writeDataFile() const
{
const auto path = Social::getBaseContentPath() + DataFile;
cro::ConfigFile cfg;
cfg.addProperty("lat_lon").setValue(m_latlon);
cfg.addProperty("timestamp").setValue(static_cast<std::uint32_t>(std::time(nullptr)));
//cfg.save(path); //TODO enable this once we're done testing!
}
Loading

0 comments on commit cfdce91

Please sign in to comment.