Fixes and stuff
Using proper SDL Audio APIs now Fixed borderless Create game window before asset load Bump up root loading worker thread count to 8 Fix not hearing other player songs on load-in Fix issues with shipworlds missing ship.level property Fix rare thread race with received chat packets on the server-side
This commit is contained in:
parent
0ec3000536
commit
d6fdd96076
@ -262,6 +262,7 @@ public:
|
|||||||
if (!m_sdlGlContext)
|
if (!m_sdlGlContext)
|
||||||
throw ApplicationException::format("Application: Could not create OpenGL context: %s", SDL_GetError());
|
throw ApplicationException::format("Application: Could not create OpenGL context: %s", SDL_GetError());
|
||||||
|
|
||||||
|
SDL_GL_SwapWindow(m_sdlWindow);
|
||||||
setVSyncEnabled(m_windowVSync);
|
setVSyncEnabled(m_windowVSync);
|
||||||
|
|
||||||
SDL_StopTextInput();
|
SDL_StopTextInput();
|
||||||
@ -277,13 +278,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
SDL_AudioSpec obtained = {};
|
SDL_AudioSpec obtained = {};
|
||||||
if (SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, 0) < 0) {
|
m_audioDevice = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, 0);
|
||||||
|
if (!m_audioDevice) {
|
||||||
Logger::error("Application: Could not open audio device, no sound available!");
|
Logger::error("Application: Could not open audio device, no sound available!");
|
||||||
} else if (obtained.freq != desired.freq || obtained.channels != desired.channels || obtained.format != desired.format) {
|
} else if (obtained.freq != desired.freq || obtained.channels != desired.channels || obtained.format != desired.format) {
|
||||||
SDL_CloseAudio();
|
SDL_CloseAudioDevice(m_audioDevice);
|
||||||
Logger::error("Application: Could not open 44.1khz / 16 bit stereo audio device, no sound available!");
|
Logger::error("Application: Could not open 44.1khz / 16 bit stereo audio device, no sound available!");
|
||||||
} else {
|
} else {
|
||||||
Logger::info("Application: Opened default audio device with 44.1khz / 16 bit stereo audio, %s sample size buffer", obtained.samples);
|
Logger::info("Application: Opened default audio device with 44.1khz / 16 bit stereo audio, %s sample size buffer", obtained.samples);
|
||||||
|
SDL_PauseAudioDevice(m_audioDevice, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderer = make_shared<OpenGl20Renderer>();
|
m_renderer = make_shared<OpenGl20Renderer>();
|
||||||
@ -291,7 +294,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~SdlPlatform() {
|
~SdlPlatform() {
|
||||||
SDL_CloseAudio();
|
SDL_CloseAudioDevice(m_audioDevice);
|
||||||
|
|
||||||
m_renderer.reset();
|
m_renderer.reset();
|
||||||
|
|
||||||
@ -370,7 +373,7 @@ public:
|
|||||||
Logger::error("Application: threw exception during shutdown: %s", outputException(e, true));
|
Logger::error("Application: threw exception during shutdown: %s", outputException(e, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_CloseAudio();
|
SDL_CloseAudioDevice(m_audioDevice);
|
||||||
m_application.reset();
|
m_application.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,8 +441,10 @@ private:
|
|||||||
|
|
||||||
void setNormalWindow(Vec2U windowSize) override {
|
void setNormalWindow(Vec2U windowSize) override {
|
||||||
if (parent->m_windowMode != WindowMode::Normal || parent->m_windowSize != windowSize) {
|
if (parent->m_windowMode != WindowMode::Normal || parent->m_windowSize != windowSize) {
|
||||||
if (parent->m_windowMode == WindowMode::Fullscreen || parent->m_windowMode == WindowMode::Borderless)
|
if (parent->m_windowMode == WindowMode::Fullscreen || parent->m_windowMode == WindowMode::Borderless) {
|
||||||
SDL_SetWindowFullscreen(parent->m_sdlWindow, 0);
|
SDL_SetWindowFullscreen(parent->m_sdlWindow, 0);
|
||||||
|
SDL_SetWindowBordered(parent->m_sdlWindow, SDL_TRUE);
|
||||||
|
}
|
||||||
else if (parent->m_windowMode == WindowMode::Maximized)
|
else if (parent->m_windowMode == WindowMode::Maximized)
|
||||||
SDL_RestoreWindow(parent->m_sdlWindow);
|
SDL_RestoreWindow(parent->m_sdlWindow);
|
||||||
|
|
||||||
@ -453,8 +458,10 @@ private:
|
|||||||
|
|
||||||
void setMaximizedWindow() override {
|
void setMaximizedWindow() override {
|
||||||
if (parent->m_windowMode != WindowMode::Maximized) {
|
if (parent->m_windowMode != WindowMode::Maximized) {
|
||||||
if (parent->m_windowMode == WindowMode::Fullscreen || parent->m_windowMode == WindowMode::Borderless)
|
if (parent->m_windowMode == WindowMode::Fullscreen || parent->m_windowMode == WindowMode::Borderless) {
|
||||||
SDL_SetWindowFullscreen(parent->m_sdlWindow, 0);
|
SDL_SetWindowFullscreen(parent->m_sdlWindow, 0);
|
||||||
|
SDL_SetWindowBordered(parent->m_sdlWindow, SDL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_MaximizeWindow(parent->m_sdlWindow);
|
SDL_MaximizeWindow(parent->m_sdlWindow);
|
||||||
parent->m_windowMode = WindowMode::Maximized;
|
parent->m_windowMode = WindowMode::Maximized;
|
||||||
@ -463,7 +470,9 @@ private:
|
|||||||
|
|
||||||
void setBorderlessWindow() override {
|
void setBorderlessWindow() override {
|
||||||
if (parent->m_windowMode != WindowMode::Borderless) {
|
if (parent->m_windowMode != WindowMode::Borderless) {
|
||||||
SDL_SetWindowFullscreen(parent->m_sdlWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
SDL_SetWindowFullscreen(parent->m_sdlWindow, 0);
|
||||||
|
SDL_SetWindowBordered(parent->m_sdlWindow, SDL_FALSE);
|
||||||
|
SDL_MaximizeWindow(parent->m_sdlWindow);
|
||||||
parent->m_windowMode = WindowMode::Borderless;
|
parent->m_windowMode = WindowMode::Borderless;
|
||||||
|
|
||||||
SDL_DisplayMode actualDisplayMode;
|
SDL_DisplayMode actualDisplayMode;
|
||||||
@ -656,6 +665,7 @@ private:
|
|||||||
|
|
||||||
SDL_Window* m_sdlWindow = nullptr;
|
SDL_Window* m_sdlWindow = nullptr;
|
||||||
SDL_GLContext m_sdlGlContext = nullptr;
|
SDL_GLContext m_sdlGlContext = nullptr;
|
||||||
|
SDL_AudioDeviceID m_audioDevice = 0;
|
||||||
|
|
||||||
Vec2U m_windowSize = {800, 600};
|
Vec2U m_windowSize = {800, 600};
|
||||||
WindowMode m_windowMode = WindowMode::Normal;
|
WindowMode m_windowMode = WindowMode::Normal;
|
||||||
|
@ -693,33 +693,34 @@ void OpenGl20Renderer::GlRenderBuffer::set(List<RenderPrimitive> primitives) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGl20Renderer::logGlErrorSummary(String prefix) {
|
void OpenGl20Renderer::logGlErrorSummary(String prefix) {
|
||||||
|
prefix += ": ";
|
||||||
|
Logger::error(prefix.utf8Ptr());
|
||||||
List<GLenum> errors;
|
List<GLenum> errors;
|
||||||
while (GLenum error = glGetError())
|
while (GLenum error = glGetError())
|
||||||
errors.append(error);
|
errors.append(error);
|
||||||
|
|
||||||
if (!errors.empty()) {
|
if (GLenum error = glGetError()) {
|
||||||
String errorMessage = move(prefix);
|
prefix += ": ";
|
||||||
errorMessage.append(": ");
|
Logger::error(prefix.utf8Ptr());
|
||||||
for (auto const& error : errors) {
|
do {
|
||||||
if (error == GL_INVALID_ENUM) {
|
if (error == GL_INVALID_ENUM) {
|
||||||
errorMessage += " GL_INVALID_ENUM";
|
Logger::error("GL_INVALID_ENUM");
|
||||||
} else if (error == GL_INVALID_VALUE) {
|
} else if (error == GL_INVALID_VALUE) {
|
||||||
errorMessage += " GL_INVALID_VALUE";
|
Logger::error("GL_INVALID_VALUE");
|
||||||
} else if (error == GL_INVALID_OPERATION) {
|
} else if (error == GL_INVALID_OPERATION) {
|
||||||
errorMessage += " GL_INVALID_OPERATION";
|
Logger::error("GL_INVALID_OPERATION");
|
||||||
} else if (error == GL_INVALID_FRAMEBUFFER_OPERATION) {
|
} else if (error == GL_INVALID_FRAMEBUFFER_OPERATION) {
|
||||||
errorMessage += " GL_INVALID_FRAMEBUFFER_OPERATION";
|
Logger::error("GL_INVALID_FRAMEBUFFER_OPERATION");
|
||||||
} else if (error == GL_OUT_OF_MEMORY) {
|
} else if (error == GL_OUT_OF_MEMORY) {
|
||||||
errorMessage += " GL_OUT_OF_MEMORY";
|
Logger::error("GL_OUT_OF_MEMORY");
|
||||||
} else if (error == GL_STACK_UNDERFLOW) {
|
} else if (error == GL_STACK_UNDERFLOW) {
|
||||||
errorMessage += " GL_STACK_UNDERFLOW";
|
Logger::error("GL_STACK_UNDERFLOW");
|
||||||
} else if (error == GL_STACK_OVERFLOW) {
|
} else if (error == GL_STACK_OVERFLOW) {
|
||||||
errorMessage += " GL_STACK_OVERFLOW";
|
Logger::error("GL_STACK_OVERFLOW");
|
||||||
} else {
|
} else {
|
||||||
errorMessage += " <UNRECOGNIZED GL ERROR>";
|
Logger::error("<UNRECOGNIZED GL ERROR>");
|
||||||
}
|
}
|
||||||
}
|
} while (error = glGetError());
|
||||||
Logger::error(errorMessage.utf8Ptr());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,11 +128,6 @@ void ClientApplication::startup(StringList const& cmdLineArgs) {
|
|||||||
m_root = rootLoader.initOrDie(cmdLineArgs).first;
|
m_root = rootLoader.initOrDie(cmdLineArgs).first;
|
||||||
|
|
||||||
Logger::info("Client Version %s (%s) Source ID: %s Protocol: %s", StarVersionString, StarArchitectureString, StarSourceIdentifierString, StarProtocolVersion);
|
Logger::info("Client Version %s (%s) Source ID: %s Protocol: %s", StarVersionString, StarArchitectureString, StarSourceIdentifierString, StarProtocolVersion);
|
||||||
|
|
||||||
auto assets = m_root->assets();
|
|
||||||
m_minInterfaceScale = assets->json("/interface.config:minInterfaceScale").toInt();
|
|
||||||
m_maxInterfaceScale = assets->json("/interface.config:maxInterfaceScale").toInt();
|
|
||||||
m_crossoverRes = jsonToVec2F(assets->json("/interface.config:interfaceCrossoverRes"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientApplication::shutdown() {
|
void ClientApplication::shutdown() {
|
||||||
@ -159,6 +154,11 @@ void ClientApplication::shutdown() {
|
|||||||
void ClientApplication::applicationInit(ApplicationControllerPtr appController) {
|
void ClientApplication::applicationInit(ApplicationControllerPtr appController) {
|
||||||
Application::applicationInit(appController);
|
Application::applicationInit(appController);
|
||||||
|
|
||||||
|
auto assets = m_root->assets();
|
||||||
|
m_minInterfaceScale = assets->json("/interface.config:minInterfaceScale").toInt();
|
||||||
|
m_maxInterfaceScale = assets->json("/interface.config:maxInterfaceScale").toInt();
|
||||||
|
m_crossoverRes = jsonToVec2F(assets->json("/interface.config:interfaceCrossoverRes"));
|
||||||
|
|
||||||
appController->setCursorVisible(false);
|
appController->setCursorVisible(false);
|
||||||
|
|
||||||
AudioFormat audioFormat = appController->enableAudio();
|
AudioFormat audioFormat = appController->enableAudio();
|
||||||
@ -178,7 +178,7 @@ void ClientApplication::applicationInit(ApplicationControllerPtr appController)
|
|||||||
bool borderless = configuration->get("borderless").toBool();
|
bool borderless = configuration->get("borderless").toBool();
|
||||||
bool maximized = configuration->get("maximized").toBool();
|
bool maximized = configuration->get("maximized").toBool();
|
||||||
|
|
||||||
appController->setApplicationTitle(m_root->assets()->json("/client.config:windowTitle").toString());
|
appController->setApplicationTitle(assets->json("/client.config:windowTitle").toString());
|
||||||
appController->setVSyncEnabled(vsync);
|
appController->setVSyncEnabled(vsync);
|
||||||
|
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
@ -190,8 +190,8 @@ void ClientApplication::applicationInit(ApplicationControllerPtr appController)
|
|||||||
else
|
else
|
||||||
appController->setNormalWindow(windowedSize);
|
appController->setNormalWindow(windowedSize);
|
||||||
|
|
||||||
appController->setMaxFrameSkip(m_root->assets()->json("/client.config:maxFrameSkip").toUInt());
|
appController->setMaxFrameSkip(assets->json("/client.config:maxFrameSkip").toUInt());
|
||||||
appController->setUpdateTrackWindow(m_root->assets()->json("/client.config:updateTrackWindow").toFloat());
|
appController->setUpdateTrackWindow(assets->json("/client.config:updateTrackWindow").toFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientApplication::renderInit(RendererPtr renderer) {
|
void ClientApplication::renderInit(RendererPtr renderer) {
|
||||||
|
@ -57,7 +57,7 @@ namespace Star {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
unsigned const RootMaintenanceSleep = 5000;
|
unsigned const RootMaintenanceSleep = 5000;
|
||||||
unsigned const RootLoadThreads = 2;
|
unsigned const RootLoadThreads = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic<Root*> Root::s_singleton;
|
atomic<Root*> Root::s_singleton;
|
||||||
|
@ -18,6 +18,7 @@ Songbook::Songbook(String const& species) {
|
|||||||
m_dataUpdated = false;
|
m_dataUpdated = false;
|
||||||
m_dataChanged = false;
|
m_dataChanged = false;
|
||||||
m_timeSourceEpoch = 0;
|
m_timeSourceEpoch = 0;
|
||||||
|
m_epochUpdated = false;
|
||||||
m_globalNowDelta = 0;
|
m_globalNowDelta = 0;
|
||||||
m_species = species;
|
m_species = species;
|
||||||
m_stopped = true;
|
m_stopped = true;
|
||||||
@ -72,6 +73,10 @@ void Songbook::update(EntityMode mode, World* world) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_globalNowDelta = world->epochTime() * 1000 - Time::millisecondsSinceEpoch();
|
m_globalNowDelta = world->epochTime() * 1000 - Time::millisecondsSinceEpoch();
|
||||||
|
if (m_epochUpdated) {
|
||||||
|
m_epochUpdated = false;
|
||||||
|
m_timeSourceEpoch -= m_globalNowDelta;
|
||||||
|
}
|
||||||
if (m_dataUpdated) {
|
if (m_dataUpdated) {
|
||||||
m_dataUpdated = false;
|
m_dataUpdated = false;
|
||||||
if (!m_song.isNull()) {
|
if (!m_song.isNull()) {
|
||||||
@ -652,6 +657,7 @@ void Songbook::play(Json const& song, String const& timeSource) {
|
|||||||
m_timeSource = toString(Random::randu64());
|
m_timeSource = toString(Random::randu64());
|
||||||
|
|
||||||
{
|
{
|
||||||
|
m_epochUpdated = false;
|
||||||
m_timeSourceEpoch = Time::millisecondsSinceEpoch();
|
m_timeSourceEpoch = Time::millisecondsSinceEpoch();
|
||||||
MutexLocker lock(s_timeSourcesMutex);
|
MutexLocker lock(s_timeSourcesMutex);
|
||||||
if (!s_timeSources.contains(m_timeSource)) {
|
if (!s_timeSources.contains(m_timeSource)) {
|
||||||
@ -702,7 +708,8 @@ double Songbook::fundamentalPitch(double f) {
|
|||||||
void Songbook::netElementsNeedLoad(bool) {
|
void Songbook::netElementsNeedLoad(bool) {
|
||||||
if (m_songNetState.pullUpdated()) {
|
if (m_songNetState.pullUpdated()) {
|
||||||
m_song = m_songNetState.get();
|
m_song = m_songNetState.get();
|
||||||
m_timeSourceEpoch = m_timeSourceEpochNetState.get() - m_globalNowDelta;
|
m_timeSourceEpoch = m_timeSourceEpochNetState.get();
|
||||||
|
m_epochUpdated = true;
|
||||||
m_dataUpdated = true;
|
m_dataUpdated = true;
|
||||||
}
|
}
|
||||||
m_timeSource = m_timeSourceNetState.get();
|
m_timeSource = m_timeSourceNetState.get();
|
||||||
|
@ -81,6 +81,7 @@ private:
|
|||||||
|
|
||||||
String m_timeSource;
|
String m_timeSource;
|
||||||
int64_t m_timeSourceEpoch;
|
int64_t m_timeSourceEpoch;
|
||||||
|
bool m_epochUpdated;
|
||||||
String m_instrument;
|
String m_instrument;
|
||||||
Json m_song;
|
Json m_song;
|
||||||
bool m_stopped;
|
bool m_stopped;
|
||||||
|
@ -619,9 +619,12 @@ void UniverseServer::updateShips() {
|
|||||||
if (auto shipWorld = getWorld(ClientShipWorldId(p.second->playerUuid()))) {
|
if (auto shipWorld = getWorld(ClientShipWorldId(p.second->playerUuid()))) {
|
||||||
shipWorld->executeAction([&](WorldServerThread*, WorldServer* shipWorld) {
|
shipWorld->executeAction([&](WorldServerThread*, WorldServer* shipWorld) {
|
||||||
auto const& speciesShips = m_speciesShips.get(p.second->playerSpecies());
|
auto const& speciesShips = m_speciesShips.get(p.second->playerSpecies());
|
||||||
unsigned oldShipLevel = shipWorld->getProperty("ship.level").toUInt();
|
Json jOldShipLevel = shipWorld->getProperty("ship.level");
|
||||||
unsigned newShipLevel = min<unsigned>(speciesShips.size() - 1, newShipUpgrades.shipLevel);
|
unsigned newShipLevel = min<unsigned>(speciesShips.size() - 1, newShipUpgrades.shipLevel);
|
||||||
|
|
||||||
|
|
||||||
|
if (jOldShipLevel.isType(Json::Type::Int)) {
|
||||||
|
auto oldShipLevel = jOldShipLevel.toUInt();
|
||||||
if (oldShipLevel < newShipLevel) {
|
if (oldShipLevel < newShipLevel) {
|
||||||
for (unsigned i = oldShipLevel + 1; i <= newShipLevel; ++i) {
|
for (unsigned i = oldShipLevel + 1; i <= newShipLevel; ++i) {
|
||||||
auto shipStructure = WorldStructure(speciesShips[i]);
|
auto shipStructure = WorldStructure(speciesShips[i]);
|
||||||
@ -632,7 +635,7 @@ void UniverseServer::updateShips() {
|
|||||||
p.second->setShipUpgrades(newShipUpgrades);
|
p.second->setShipUpgrades(newShipUpgrades);
|
||||||
p.second->updateShipChunks(shipWorld->readChunks());
|
p.second->updateShipChunks(shipWorld->readChunks());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
shipWorld->setProperty("ship.level", newShipUpgrades.shipLevel);
|
shipWorld->setProperty("ship.level", newShipUpgrades.shipLevel);
|
||||||
shipWorld->setProperty("ship.maxFuel", newShipUpgrades.maxFuel);
|
shipWorld->setProperty("ship.maxFuel", newShipUpgrades.maxFuel);
|
||||||
shipWorld->setProperty("ship.crewSize", newShipUpgrades.crewSize);
|
shipWorld->setProperty("ship.crewSize", newShipUpgrades.crewSize);
|
||||||
@ -1430,6 +1433,7 @@ void UniverseServer::packetsReceived(UniverseConnectionServer*, ConnectionId cli
|
|||||||
clientFlyShip(clientId, flyShip->system, flyShip->location);
|
clientFlyShip(clientId, flyShip->system, flyShip->location);
|
||||||
|
|
||||||
} else if (auto chatSend = as<ChatSendPacket>(packet)) {
|
} else if (auto chatSend = as<ChatSendPacket>(packet)) {
|
||||||
|
RecursiveMutexLocker locker(m_mainLock);
|
||||||
m_pendingChat[clientId].append({move(chatSend->text), chatSend->sendMode});
|
m_pendingChat[clientId].append({move(chatSend->text), chatSend->sendMode});
|
||||||
|
|
||||||
} else if (auto clientContextUpdatePacket = as<ClientContextUpdatePacket>(packet)) {
|
} else if (auto clientContextUpdatePacket = as<ClientContextUpdatePacket>(packet)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user