Fix broken regex, make game timestep non-const
This commit is contained in:
parent
2496789ea7
commit
152af87655
@ -558,6 +558,7 @@ void ClientApplication::setError(String const& error) {
|
|||||||
void ClientApplication::setError(String const& error, std::exception const& e) {
|
void ClientApplication::setError(String const& error, std::exception const& e) {
|
||||||
Logger::error("{}\n{}", error, outputException(e, true));
|
Logger::error("{}\n{}", error, outputException(e, true));
|
||||||
m_errorScreen->setMessage(strf("{}\n{}", error, outputException(e, false)));
|
m_errorScreen->setMessage(strf("{}\n{}", error, outputException(e, false)));
|
||||||
|
changeState(MainAppState::Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientApplication::updateMods() {
|
void ClientApplication::updateMods() {
|
||||||
|
@ -83,6 +83,7 @@ SET (star_core_HEADERS
|
|||||||
StarOptionParser.hpp
|
StarOptionParser.hpp
|
||||||
StarOrderedMap.hpp
|
StarOrderedMap.hpp
|
||||||
StarOrderedSet.hpp
|
StarOrderedSet.hpp
|
||||||
|
StarOutputProxy.hpp
|
||||||
StarParametricFunction.hpp
|
StarParametricFunction.hpp
|
||||||
StarPch.hpp
|
StarPch.hpp
|
||||||
StarPeriodic.hpp
|
StarPeriodic.hpp
|
||||||
|
@ -65,7 +65,7 @@ namespace {
|
|||||||
|
|
||||||
if ((strcmp(riffSig.get(), "RIFF") != 0) || (strcmp(waveSig.get(), "WAVE") != 0)) { // bytes are not magic
|
if ((strcmp(riffSig.get(), "RIFF") != 0) || (strcmp(waveSig.get(), "WAVE") != 0)) { // bytes are not magic
|
||||||
auto p = [](char a) { return isprint(a) ? a : '?'; };
|
auto p = [](char a) { return isprint(a) ? a : '?'; };
|
||||||
throw AudioException(strf("Wav file has wrong magic bytes, got `{}{}{}{}' and `{}{}{}{}' but expected `RIFF' and `WAVE'",
|
throw AudioException(strf("Wav file has wrong magic bytes, got `{:c}{:c}{:c}{:c}' and `{:c}{:c}{:c}{:c}' but expected `RIFF' and `WAVE'",
|
||||||
p(riffSig[0]), p(riffSig[1]), p(riffSig[2]), p(riffSig[3]), p(waveSig[0]), p(waveSig[1]), p(waveSig[2]), p(waveSig[3])));
|
p(riffSig[0]), p(riffSig[1]), p(riffSig[2]), p(riffSig[3]), p(waveSig[0]), p(waveSig[1]), p(waveSig[2]), p(waveSig[3])));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ namespace {
|
|||||||
device->readFull(fmtSig.get(), sigLength);
|
device->readFull(fmtSig.get(), sigLength);
|
||||||
if (strcmp(fmtSig.get(), "fmt ") != 0) { // friendship is magic
|
if (strcmp(fmtSig.get(), "fmt ") != 0) { // friendship is magic
|
||||||
auto p = [](char a) { return isprint(a) ? a : '?'; };
|
auto p = [](char a) { return isprint(a) ? a : '?'; };
|
||||||
throw AudioException(strf("Wav file fmt subchunk has wrong magic bytes, got `{}{}{}{}' but expected `fmt '",
|
throw AudioException(strf("Wav file fmt subchunk has wrong magic bytes, got `{:c}{:c}{:c}{:c}' but expected `fmt '",
|
||||||
p(fmtSig[0]),
|
p(fmtSig[0]),
|
||||||
p(fmtSig[1]),
|
p(fmtSig[1]),
|
||||||
p(fmtSig[2]),
|
p(fmtSig[2]),
|
||||||
@ -110,7 +110,7 @@ namespace {
|
|||||||
device->readFull(dataSig.get(), sigLength);
|
device->readFull(dataSig.get(), sigLength);
|
||||||
if (strcmp(dataSig.get(), "data") != 0) { // magic or more magic?
|
if (strcmp(dataSig.get(), "data") != 0) { // magic or more magic?
|
||||||
auto p = [](char a) { return isprint(a) ? a : '?'; };
|
auto p = [](char a) { return isprint(a) ? a : '?'; };
|
||||||
throw AudioException(strf("Wav file data subchunk has wrong magic bytes, got `{}{}{}{}' but expected `data'",
|
throw AudioException(strf("Wav file data subchunk has wrong magic bytes, got `{:c}{:c}{:c}{:c}' but expected `data'",
|
||||||
p(dataSig[0]), p(dataSig[1]), p(dataSig[2]), p(dataSig[3])));
|
p(dataSig[0]), p(dataSig[1]), p(dataSig[2]), p(dataSig[3])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
#ifndef STAR_EXCEPTION_HPP
|
#ifndef STAR_EXCEPTION_HPP
|
||||||
#define STAR_EXCEPTION_HPP
|
#define STAR_EXCEPTION_HPP
|
||||||
|
|
||||||
#include "StarFormat.hpp"
|
#include "StarMemory.hpp"
|
||||||
|
#include "StarOutputProxy.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
std::string strf(fmt::format_string<T...> fmt, T&&... args);
|
||||||
|
|
||||||
class StarException : public std::exception {
|
class StarException : public std::exception {
|
||||||
public:
|
public:
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "StarException.hpp"
|
#include "StarException.hpp"
|
||||||
|
#include "StarOutputProxy.hpp"
|
||||||
#include "StarLogging.hpp"
|
#include "StarLogging.hpp"
|
||||||
#include "StarCasting.hpp"
|
#include "StarCasting.hpp"
|
||||||
#include "StarString_windows.hpp"
|
#include "StarString_windows.hpp"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define STAR_FORMAT_HPP
|
#define STAR_FORMAT_HPP
|
||||||
|
|
||||||
#include "StarMemory.hpp"
|
#include "StarMemory.hpp"
|
||||||
|
#include "StarException.hpp"
|
||||||
|
|
||||||
#include "fmt/core.h"
|
#include "fmt/core.h"
|
||||||
#include "fmt/ostream.h"
|
#include "fmt/ostream.h"
|
||||||
@ -10,23 +11,19 @@
|
|||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
struct FormatException : public std::exception {
|
STAR_EXCEPTION(FormatException, StarException);
|
||||||
FormatException(std::string what) : whatmsg(move(what)) {}
|
|
||||||
|
|
||||||
char const* what() const noexcept override {
|
template <typename... T>
|
||||||
return whatmsg.c_str();
|
std::string strf(fmt::format_string<T...> fmt, T&&... args) {
|
||||||
|
try { return fmt::format(fmt, args...); }
|
||||||
|
catch (std::exception const& e) {
|
||||||
|
throw FormatException(strf("Exception thrown during string format: {}", e.what()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string whatmsg;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Star {
|
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
void format(std::ostream& out, fmt::format_string<T...> fmt, T&&... args) {
|
void format(std::ostream& out, fmt::format_string<T...> fmt, T&&... args) {
|
||||||
out << fmt::format(fmt, args...);
|
out << strf(fmt, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically flushes, use format to avoid flushing.
|
// Automatically flushes, use format to avoid flushing.
|
||||||
@ -43,66 +40,6 @@ void cerrf(char const* fmt, Args const&... args) {
|
|||||||
std::cerr.flush();
|
std::cerr.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... T>
|
|
||||||
std::string strf(fmt::format_string<T...> fmt, T&&... args) {
|
|
||||||
return fmt::format(fmt, args...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OutputAnyDetail {
|
|
||||||
template<typename T, typename CharT, typename Traits>
|
|
||||||
std::basic_string<CharT, Traits> string(T const& t) {
|
|
||||||
return fmt::format("<type {} at address: {}>", typeid(T).name(), (void*)&t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename CharT, typename Traits>
|
|
||||||
std::basic_ostream<CharT, Traits>& output(std::basic_ostream<CharT, Traits>& os, T const& t) {
|
|
||||||
return os << string<T, CharT, Traits>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Operator {
|
|
||||||
template<typename T, typename CharT, typename Traits>
|
|
||||||
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, T const& t) {
|
|
||||||
return output(os, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Wrapper {
|
|
||||||
T const& wrapped;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::ostream& operator<<(std::ostream& os, Wrapper<T> const& wrapper) {
|
|
||||||
using namespace Operator;
|
|
||||||
return os << wrapper.wrapped;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wraps a type so that is printable no matter what.. If no operator<< is
|
|
||||||
// defined for a type, then will print <type [typeid] at address: [address]>
|
|
||||||
template <typename T>
|
|
||||||
OutputAnyDetail::Wrapper<T> outputAny(T const& t) {
|
|
||||||
return OutputAnyDetail::Wrapper<T>{t};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct OutputProxy {
|
|
||||||
typedef function<void(std::ostream&)> PrintFunction;
|
|
||||||
|
|
||||||
OutputProxy(PrintFunction p)
|
|
||||||
: print(move(p)) {}
|
|
||||||
|
|
||||||
PrintFunction print;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, OutputProxy const& p) {
|
|
||||||
p.print(os);
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct fmt::formatter<Star::OutputAnyDetail::Wrapper<T>> : ostream_formatter {};
|
|
||||||
template <> struct fmt::formatter<Star::OutputProxy> : ostream_formatter {};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
68
source/core/StarOutputProxy.hpp
Normal file
68
source/core/StarOutputProxy.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#ifndef STAR_OUTPUT_PROXY_HPP
|
||||||
|
#define STAR_OUTPUT_PROXY_HPP
|
||||||
|
|
||||||
|
#include "StarMemory.hpp"
|
||||||
|
|
||||||
|
#include "fmt/format.h"
|
||||||
|
#include "fmt/ostream.h"
|
||||||
|
|
||||||
|
namespace Star {
|
||||||
|
|
||||||
|
namespace OutputAnyDetail {
|
||||||
|
template<typename T, typename CharT, typename Traits>
|
||||||
|
std::basic_string<CharT, Traits> string(T const& t) {
|
||||||
|
return fmt::format("<type {} at address: {}>", typeid(T).name(), (void*)&t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename CharT, typename Traits>
|
||||||
|
std::basic_ostream<CharT, Traits>& output(std::basic_ostream<CharT, Traits>& os, T const& t) {
|
||||||
|
return os << string<T, CharT, Traits>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Operator {
|
||||||
|
template<typename T, typename CharT, typename Traits>
|
||||||
|
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, T const& t) {
|
||||||
|
return output(os, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Wrapper {
|
||||||
|
T const& wrapped;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::ostream& operator<<(std::ostream& os, Wrapper<T> const& wrapper) {
|
||||||
|
using namespace Operator;
|
||||||
|
return os << wrapper.wrapped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wraps a type so that is printable no matter what.. If no operator<< is
|
||||||
|
// defined for a type, then will print <type [typeid] at address: [address]>
|
||||||
|
template <typename T>
|
||||||
|
OutputAnyDetail::Wrapper<T> outputAny(T const& t) {
|
||||||
|
return OutputAnyDetail::Wrapper<T>{t};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OutputProxy {
|
||||||
|
typedef function<void(std::ostream&)> PrintFunction;
|
||||||
|
|
||||||
|
OutputProxy(PrintFunction p)
|
||||||
|
: print(move(p)) {}
|
||||||
|
|
||||||
|
PrintFunction print;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, OutputProxy const& p) {
|
||||||
|
p.print(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct fmt::formatter<Star::OutputAnyDetail::Wrapper<T>> : ostream_formatter {};
|
||||||
|
template <> struct fmt::formatter<Star::OutputProxy> : ostream_formatter {};
|
||||||
|
|
||||||
|
#endif
|
@ -73,8 +73,8 @@ RectF separateBubble(List<RectF> const& sortedLeftEdges, List<RectF> const& sort
|
|||||||
if (overlappingBoxes.empty())
|
if (overlappingBoxes.empty())
|
||||||
break;
|
break;
|
||||||
RectF overlapBoundBox = fold(overlappingBoxes, box, [](RectF const& a, RectF const& b) { return a.combined(b); });
|
RectF overlapBoundBox = fold(overlappingBoxes, box, [](RectF const& a, RectF const& b) { return a.combined(b); });
|
||||||
SpatialLogger::logPoly("screen", PolyF(box), { 255, 0, 0, 255 });
|
//SpatialLogger::logPoly("screen", PolyF(box), { 255, 0, 0, 255 });
|
||||||
SpatialLogger::logPoly("screen", PolyF(overlapBoundBox), { 0, 0, 255, 255 });
|
//SpatialLogger::logPoly("screen", PolyF(overlapBoundBox), { 0, 0, 255, 255 });
|
||||||
auto height = box.height();
|
auto height = box.height();
|
||||||
box.setYMin(overlapBoundBox.yMax());
|
box.setYMin(overlapBoundBox.yMax());
|
||||||
box.setYMax(box.yMin() + height);
|
box.setYMax(box.yMin() + height);
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
|
float WorldTimestep = 1.0f / 120.0f;
|
||||||
|
float ServerWorldTimestep = 1.0f / 20.0f;
|
||||||
|
|
||||||
EnumMap<Direction> const DirectionNames{
|
EnumMap<Direction> const DirectionNames{
|
||||||
{Direction::Left, "left"},
|
{Direction::Left, "left"},
|
||||||
{Direction::Right, "right"},
|
{Direction::Right, "right"},
|
||||||
|
@ -93,7 +93,8 @@ extern EnumMap<Rarity> const RarityNames;
|
|||||||
// distance (one tile).
|
// distance (one tile).
|
||||||
unsigned const TilePixels = 8;
|
unsigned const TilePixels = 8;
|
||||||
|
|
||||||
float const WorldTimestep = 1.0f / 60.0f;
|
extern float WorldTimestep;
|
||||||
|
extern float ServerWorldTimestep;
|
||||||
float const SystemWorldTimestep = 1.0f / 20.0f;
|
float const SystemWorldTimestep = 1.0f / 20.0f;
|
||||||
|
|
||||||
size_t const WorldSectorSize = 32;
|
size_t const WorldSectorSize = 32;
|
||||||
|
@ -32,6 +32,7 @@ WorldClient::WorldClient(PlayerPtr mainPlayer) {
|
|||||||
m_clientConfig = assets->json("/client.config");
|
m_clientConfig = assets->json("/client.config");
|
||||||
|
|
||||||
m_currentStep = 0;
|
m_currentStep = 0;
|
||||||
|
m_currentServerStep = 0.0;
|
||||||
m_fullBright = false;
|
m_fullBright = false;
|
||||||
m_worldDimTimer = GameTimer(m_clientConfig.getFloat("worldDimTime"));
|
m_worldDimTimer = GameTimer(m_clientConfig.getFloat("worldDimTime"));
|
||||||
m_worldDimTimer.setDone();
|
m_worldDimTimer.setDone();
|
||||||
@ -463,9 +464,14 @@ void WorldClient::render(WorldRenderData& renderData, unsigned bufferTiles) {
|
|||||||
for (size_t y = 0; y < ySize; ++y) {
|
for (size_t y = 0; y < ySize; ++y) {
|
||||||
auto& tile = column[y];
|
auto& tile = column[y];
|
||||||
|
|
||||||
Vec3F light = materialDatabase->radiantLight(tile.foreground, tile.foregroundMod);
|
Vec3F light;
|
||||||
light += liquidsDatabase->radiantLight(tile.liquid) * tile.liquid.level;
|
if (tile.foreground != EmptyMaterialId || tile.foregroundMod != NoModId)
|
||||||
|
light += materialDatabase->radiantLight(tile.foreground, tile.foregroundMod);
|
||||||
|
|
||||||
|
if (tile.liquid.liquid != EmptyLiquidId && tile.liquid.level != 0.0f)
|
||||||
|
light += liquidsDatabase->radiantLight(tile.liquid);
|
||||||
if (tile.foregroundLightTransparent) {
|
if (tile.foregroundLightTransparent) {
|
||||||
|
if (tile.background != EmptyMaterialId || tile.backgroundMod != NoModId)
|
||||||
light += materialDatabase->radiantLight(tile.background, tile.backgroundMod);
|
light += materialDatabase->radiantLight(tile.background, tile.backgroundMod);
|
||||||
if (tile.backgroundLightTransparent && pos[1] + y > undergroundLevel)
|
if (tile.backgroundLightTransparent && pos[1] + y > undergroundLevel)
|
||||||
light += environmentLight;
|
light += environmentLight;
|
||||||
@ -758,7 +764,8 @@ void WorldClient::handleIncomingPackets(List<PacketPtr> const& packets) {
|
|||||||
tryGiveMainPlayerItem(itemDatabase->item(giveItem->item));
|
tryGiveMainPlayerItem(itemDatabase->item(giveItem->item));
|
||||||
|
|
||||||
} else if (auto stepUpdate = as<StepUpdatePacket>(packet)) {
|
} else if (auto stepUpdate = as<StepUpdatePacket>(packet)) {
|
||||||
m_interpolationTracker.receiveStepUpdate(stepUpdate->remoteStep);
|
m_currentServerStep = ((double)stepUpdate->remoteStep * (WorldTimestep / ServerWorldTimestep));
|
||||||
|
m_interpolationTracker.receiveStepUpdate(m_currentServerStep);
|
||||||
|
|
||||||
} else if (auto environmentUpdatePacket = as<EnvironmentUpdatePacket>(packet)) {
|
} else if (auto environmentUpdatePacket = as<EnvironmentUpdatePacket>(packet)) {
|
||||||
m_sky->readUpdate(environmentUpdatePacket->skyDelta);
|
m_sky->readUpdate(environmentUpdatePacket->skyDelta);
|
||||||
@ -893,7 +900,8 @@ void WorldClient::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
++m_currentStep;
|
++m_currentStep;
|
||||||
m_interpolationTracker.update(m_currentStep);
|
//m_interpolationTracker.update(m_currentStep);
|
||||||
|
m_interpolationTracker.update(Time::monotonicTime());
|
||||||
|
|
||||||
List<WorldAction> triggeredActions;
|
List<WorldAction> triggeredActions;
|
||||||
eraseWhere(m_timers, [&triggeredActions](pair<int, WorldAction>& timer) {
|
eraseWhere(m_timers, [&triggeredActions](pair<int, WorldAction>& timer) {
|
||||||
@ -1464,6 +1472,7 @@ void WorldClient::clearWorld() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_currentStep = 0;
|
m_currentStep = 0;
|
||||||
|
m_currentServerStep = 0.0;
|
||||||
m_inWorld = false;
|
m_inWorld = false;
|
||||||
m_clientId.reset();
|
m_clientId.reset();
|
||||||
|
|
||||||
|
@ -235,6 +235,7 @@ private:
|
|||||||
|
|
||||||
WorldGeometry m_geometry;
|
WorldGeometry m_geometry;
|
||||||
uint64_t m_currentStep;
|
uint64_t m_currentStep;
|
||||||
|
double m_currentServerStep;
|
||||||
bool m_fullBright;
|
bool m_fullBright;
|
||||||
CellularLightingCalculator m_lightingCalculator;
|
CellularLightingCalculator m_lightingCalculator;
|
||||||
mutable CellularLightIntensityCalculator m_lightIntensityCalculator;
|
mutable CellularLightIntensityCalculator m_lightIntensityCalculator;
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
namespace Text {
|
namespace Text {
|
||||||
|
static auto stripEscapeRegex = std::regex(strf("\\{:c}[^;]*{:c}", CmdEsc, EndEsc));
|
||||||
String stripEscapeCodes(String const& s) {
|
String stripEscapeCodes(String const& s) {
|
||||||
String regex = strf("\\{}[^;]*{}", CmdEsc, EndEsc);
|
return std::regex_replace(s.utf8(), stripEscapeRegex, "");
|
||||||
return std::regex_replace(s.utf8(), std::regex(regex.utf8()), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String preprocessEscapeCodes(String const& s) {
|
String preprocessEscapeCodes(String const& s) {
|
||||||
|
Loading…
Reference in New Issue
Block a user