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) {
|
||||
Logger::error("{}\n{}", error, outputException(e, true));
|
||||
m_errorScreen->setMessage(strf("{}\n{}", error, outputException(e, false)));
|
||||
changeState(MainAppState::Title);
|
||||
}
|
||||
|
||||
void ClientApplication::updateMods() {
|
||||
|
@ -83,6 +83,7 @@ SET (star_core_HEADERS
|
||||
StarOptionParser.hpp
|
||||
StarOrderedMap.hpp
|
||||
StarOrderedSet.hpp
|
||||
StarOutputProxy.hpp
|
||||
StarParametricFunction.hpp
|
||||
StarPch.hpp
|
||||
StarPeriodic.hpp
|
||||
|
@ -65,7 +65,7 @@ namespace {
|
||||
|
||||
if ((strcmp(riffSig.get(), "RIFF") != 0) || (strcmp(waveSig.get(), "WAVE") != 0)) { // bytes are not magic
|
||||
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])));
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ namespace {
|
||||
device->readFull(fmtSig.get(), sigLength);
|
||||
if (strcmp(fmtSig.get(), "fmt ") != 0) { // friendship is magic
|
||||
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[1]),
|
||||
p(fmtSig[2]),
|
||||
@ -110,7 +110,7 @@ namespace {
|
||||
device->readFull(dataSig.get(), sigLength);
|
||||
if (strcmp(dataSig.get(), "data") != 0) { // magic or more magic?
|
||||
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])));
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
#ifndef STAR_EXCEPTION_HPP
|
||||
#define STAR_EXCEPTION_HPP
|
||||
|
||||
#include "StarFormat.hpp"
|
||||
#include "StarMemory.hpp"
|
||||
#include "StarOutputProxy.hpp"
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Star {
|
||||
|
||||
template <typename... T>
|
||||
std::string strf(fmt::format_string<T...> fmt, T&&... args);
|
||||
|
||||
class StarException : public std::exception {
|
||||
public:
|
||||
template <typename... Args>
|
||||
@ -68,22 +76,22 @@ void fatalException(std::exception const& e, bool showStackTrace);
|
||||
{}
|
||||
#endif
|
||||
|
||||
#define STAR_EXCEPTION(ClassName, BaseName) \
|
||||
class ClassName : public BaseName { \
|
||||
public: \
|
||||
template <typename... Args> \
|
||||
static ClassName format(fmt::format_string<Args...> fmt, Args const&... args) { \
|
||||
return ClassName(strf(fmt, args...)); \
|
||||
} \
|
||||
ClassName() : BaseName(#ClassName, std::string()) {} \
|
||||
#define STAR_EXCEPTION(ClassName, BaseName) \
|
||||
class ClassName : public BaseName { \
|
||||
public: \
|
||||
template <typename... Args> \
|
||||
static ClassName format(fmt::format_string<Args...> fmt, Args const&... args) { \
|
||||
return ClassName(strf(fmt, args...)); \
|
||||
} \
|
||||
ClassName() : BaseName(#ClassName, std::string()) {} \
|
||||
explicit ClassName(std::string message, bool genStackTrace = true) : BaseName(#ClassName, move(message), genStackTrace) {} \
|
||||
explicit ClassName(std::exception const& cause) : BaseName(#ClassName, std::string(), cause) {} \
|
||||
ClassName(std::string message, std::exception const& cause) : BaseName(#ClassName, move(message), cause) {} \
|
||||
\
|
||||
protected: \
|
||||
explicit ClassName(std::exception const& cause) : BaseName(#ClassName, std::string(), cause) {} \
|
||||
ClassName(std::string message, std::exception const& cause) : BaseName(#ClassName, move(message), cause) {} \
|
||||
\
|
||||
protected: \
|
||||
ClassName(char const* type, std::string message, bool genStackTrace = true) : BaseName(type, move(message), genStackTrace) {} \
|
||||
ClassName(char const* type, std::string message, std::exception const& cause) \
|
||||
: BaseName(type, move(message), cause) {} \
|
||||
ClassName(char const* type, std::string message, std::exception const& cause) \
|
||||
: BaseName(type, move(message), cause) {} \
|
||||
}
|
||||
|
||||
STAR_EXCEPTION(OutOfRangeException, StarException);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "StarException.hpp"
|
||||
#include "StarOutputProxy.hpp"
|
||||
#include "StarLogging.hpp"
|
||||
#include "StarCasting.hpp"
|
||||
#include "StarString_windows.hpp"
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define STAR_FORMAT_HPP
|
||||
|
||||
#include "StarMemory.hpp"
|
||||
#include "StarException.hpp"
|
||||
|
||||
#include "fmt/core.h"
|
||||
#include "fmt/ostream.h"
|
||||
@ -10,23 +11,19 @@
|
||||
|
||||
namespace Star {
|
||||
|
||||
struct FormatException : public std::exception {
|
||||
FormatException(std::string what) : whatmsg(move(what)) {}
|
||||
STAR_EXCEPTION(FormatException, StarException);
|
||||
|
||||
char const* what() const noexcept override {
|
||||
return whatmsg.c_str();
|
||||
template <typename... T>
|
||||
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>
|
||||
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.
|
||||
@ -43,66 +40,6 @@ void cerrf(char const* fmt, Args const&... args) {
|
||||
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
|
||||
|
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())
|
||||
break;
|
||||
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(overlapBoundBox), { 0, 0, 255, 255 });
|
||||
//SpatialLogger::logPoly("screen", PolyF(box), { 255, 0, 0, 255 });
|
||||
//SpatialLogger::logPoly("screen", PolyF(overlapBoundBox), { 0, 0, 255, 255 });
|
||||
auto height = box.height();
|
||||
box.setYMin(overlapBoundBox.yMax());
|
||||
box.setYMax(box.yMin() + height);
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
namespace Star {
|
||||
|
||||
float WorldTimestep = 1.0f / 120.0f;
|
||||
float ServerWorldTimestep = 1.0f / 20.0f;
|
||||
|
||||
EnumMap<Direction> const DirectionNames{
|
||||
{Direction::Left, "left"},
|
||||
{Direction::Right, "right"},
|
||||
|
@ -93,7 +93,8 @@ extern EnumMap<Rarity> const RarityNames;
|
||||
// distance (one tile).
|
||||
unsigned const TilePixels = 8;
|
||||
|
||||
float const WorldTimestep = 1.0f / 60.0f;
|
||||
extern float WorldTimestep;
|
||||
extern float ServerWorldTimestep;
|
||||
float const SystemWorldTimestep = 1.0f / 20.0f;
|
||||
|
||||
size_t const WorldSectorSize = 32;
|
||||
|
@ -32,6 +32,7 @@ WorldClient::WorldClient(PlayerPtr mainPlayer) {
|
||||
m_clientConfig = assets->json("/client.config");
|
||||
|
||||
m_currentStep = 0;
|
||||
m_currentServerStep = 0.0;
|
||||
m_fullBright = false;
|
||||
m_worldDimTimer = GameTimer(m_clientConfig.getFloat("worldDimTime"));
|
||||
m_worldDimTimer.setDone();
|
||||
@ -463,10 +464,15 @@ void WorldClient::render(WorldRenderData& renderData, unsigned bufferTiles) {
|
||||
for (size_t y = 0; y < ySize; ++y) {
|
||||
auto& tile = column[y];
|
||||
|
||||
Vec3F light = materialDatabase->radiantLight(tile.foreground, tile.foregroundMod);
|
||||
light += liquidsDatabase->radiantLight(tile.liquid) * tile.liquid.level;
|
||||
Vec3F light;
|
||||
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) {
|
||||
light += materialDatabase->radiantLight(tile.background, tile.backgroundMod);
|
||||
if (tile.background != EmptyMaterialId || tile.backgroundMod != NoModId)
|
||||
light += materialDatabase->radiantLight(tile.background, tile.backgroundMod);
|
||||
if (tile.backgroundLightTransparent && pos[1] + y > undergroundLevel)
|
||||
light += environmentLight;
|
||||
}
|
||||
@ -758,7 +764,8 @@ void WorldClient::handleIncomingPackets(List<PacketPtr> const& packets) {
|
||||
tryGiveMainPlayerItem(itemDatabase->item(giveItem->item));
|
||||
|
||||
} 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)) {
|
||||
m_sky->readUpdate(environmentUpdatePacket->skyDelta);
|
||||
@ -893,7 +900,8 @@ void WorldClient::update() {
|
||||
}
|
||||
|
||||
++m_currentStep;
|
||||
m_interpolationTracker.update(m_currentStep);
|
||||
//m_interpolationTracker.update(m_currentStep);
|
||||
m_interpolationTracker.update(Time::monotonicTime());
|
||||
|
||||
List<WorldAction> triggeredActions;
|
||||
eraseWhere(m_timers, [&triggeredActions](pair<int, WorldAction>& timer) {
|
||||
@ -1464,6 +1472,7 @@ void WorldClient::clearWorld() {
|
||||
}
|
||||
|
||||
m_currentStep = 0;
|
||||
m_currentServerStep = 0.0;
|
||||
m_inWorld = false;
|
||||
m_clientId.reset();
|
||||
|
||||
|
@ -235,6 +235,7 @@ private:
|
||||
|
||||
WorldGeometry m_geometry;
|
||||
uint64_t m_currentStep;
|
||||
double m_currentServerStep;
|
||||
bool m_fullBright;
|
||||
CellularLightingCalculator m_lightingCalculator;
|
||||
mutable CellularLightIntensityCalculator m_lightIntensityCalculator;
|
||||
|
@ -6,9 +6,9 @@
|
||||
namespace Star {
|
||||
|
||||
namespace Text {
|
||||
static auto stripEscapeRegex = std::regex(strf("\\{:c}[^;]*{:c}", CmdEsc, EndEsc));
|
||||
String stripEscapeCodes(String const& s) {
|
||||
String regex = strf("\\{}[^;]*{}", CmdEsc, EndEsc);
|
||||
return std::regex_replace(s.utf8(), std::regex(regex.utf8()), "");
|
||||
return std::regex_replace(s.utf8(), stripEscapeRegex, "");
|
||||
}
|
||||
|
||||
String preprocessEscapeCodes(String const& s) {
|
||||
|
Loading…
Reference in New Issue
Block a user