Display a progress bar when receiving a map
Replaces the old useless "num-bytes-loaded/16777216" message with a real progress bar.
This commit is contained in:
parent
97ed5d46ad
commit
cd3304ef24
@ -867,20 +867,34 @@ namespace spades {
|
||||
MakeVector4(1, 1, 1, 0.95f));
|
||||
|
||||
img = renderer->RegisterImage("Gfx/White.tga");
|
||||
float pos = timeSinceInit / 3.6f;
|
||||
pos -= floorf(pos);
|
||||
pos = 1.f - pos * 2.0f;
|
||||
for (float v = 0; v < 0.6f; v += 0.14f) {
|
||||
float p = pos + v;
|
||||
if (p < 0.01f || p > .99f)
|
||||
continue;
|
||||
p = asin(p * 2.f - 1.f);
|
||||
p = p / (float)M_PI + 0.5f;
|
||||
|
||||
float op = p * (1.f - p) * 4.f;
|
||||
renderer->SetColorAlphaPremultiplied(MakeVector4(op, op, op, op));
|
||||
if (net->GetStatus() == NetClientStatusReceivingMap) {
|
||||
// Normal progress bar
|
||||
float progress = net->GetMapReceivingProgress();
|
||||
|
||||
renderer->SetColorAlphaPremultiplied(MakeVector4(0.2f, 0.2f, 0.2f, 0.2f));
|
||||
renderer->DrawImage(img, AABB2(scrWidth - 236.f, scrHeight - 18.f, 222.f, 4.f));
|
||||
|
||||
renderer->SetColorAlphaPremultiplied(MakeVector4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
renderer->DrawImage(
|
||||
img, AABB2(scrWidth - 236.f + p * 234.f, scrHeight - 18.f, 4.f, 4.f));
|
||||
img, AABB2(scrWidth - 236.f, scrHeight - 18.f, 222.f * progress, 4.f));
|
||||
} else {
|
||||
// Indeterminate progress bar
|
||||
float pos = timeSinceInit / 3.6f;
|
||||
pos -= floorf(pos);
|
||||
pos = 1.f - pos * 2.0f;
|
||||
for (float v = 0; v < 0.6f; v += 0.14f) {
|
||||
float p = pos + v;
|
||||
if (p < 0.01f || p > .99f)
|
||||
continue;
|
||||
p = asin(p * 2.f - 1.f);
|
||||
p = p / (float)M_PI + 0.5f;
|
||||
|
||||
float op = p * (1.f - p) * 4.f;
|
||||
renderer->SetColorAlphaPremultiplied(MakeVector4(op, op, op, op));
|
||||
renderer->DrawImage(
|
||||
img, AABB2(scrWidth - 236.f + p * 234.f, scrHeight - 18.f, 4.f, 4.f));
|
||||
}
|
||||
}
|
||||
|
||||
DrawAlert();
|
||||
|
@ -70,7 +70,7 @@ namespace spades {
|
||||
}
|
||||
};
|
||||
|
||||
GameMapLoader::GameMapLoader() {
|
||||
GameMapLoader::GameMapLoader() : progressCell{0} {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
auto pipe = CreatePipeStream();
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "CTFGameMode.h"
|
||||
#include "Client.h"
|
||||
#include "GameMap.h"
|
||||
#include "GameMapLoader.h"
|
||||
#include "Grenade.h"
|
||||
#include "NetClient.h"
|
||||
#include "Player.h"
|
||||
@ -525,22 +526,24 @@ namespace spades {
|
||||
SPRaise("Unexpected packet: %d", (int)reader.GetType());
|
||||
}
|
||||
|
||||
mapSize = reader.ReadInt();
|
||||
auto mapSize = reader.ReadInt();
|
||||
SPLog("Map size advertised by the server: %lu", (unsigned long)mapSize);
|
||||
|
||||
mapLoader.reset(new GameMapLoader());
|
||||
|
||||
status = NetClientStatusReceivingMap;
|
||||
statusString = _Tr("NetClient", "Loading snapshot");
|
||||
}
|
||||
} else if (status == NetClientStatusReceivingMap) {
|
||||
SPAssert(mapLoader);
|
||||
|
||||
if (event.type == ENET_EVENT_TYPE_RECEIVE) {
|
||||
auto &reader = readerOrNone.value();
|
||||
|
||||
if (reader.GetType() == PacketTypeMapChunk) {
|
||||
std::vector<char> dt = reader.GetData();
|
||||
dt.erase(dt.begin());
|
||||
mapData.insert(mapData.end(), dt.begin(), dt.end());
|
||||
|
||||
statusString = _Tr("NetClient", "Loading snapshot ({0}/{1})",
|
||||
mapData.size(), mapSize);
|
||||
|
||||
mapLoader->AddRawChunk(dt.data() + 1, dt.size() - 1);
|
||||
} else {
|
||||
reader.DumpDebug();
|
||||
|
||||
@ -580,8 +583,7 @@ namespace spades {
|
||||
} catch (const std::exception &ex) {
|
||||
if (strstr(ex.what(), "File truncated") ||
|
||||
strstr(ex.what(), "EOF reached")) {
|
||||
SPLog("Map decoder returned error:\n%s",
|
||||
ex.what());
|
||||
SPLog("Map decoder returned error:\n%s", ex.what());
|
||||
Disconnect();
|
||||
statusString = _Tr("NetClient", "Error");
|
||||
throw;
|
||||
@ -597,7 +599,7 @@ namespace spades {
|
||||
// cancel the reload packets on map change and
|
||||
// they would cause an error if we would
|
||||
// process them
|
||||
} else {
|
||||
} else {
|
||||
// Save the packet for later
|
||||
savedPackets.push_back(reader.GetData());
|
||||
}
|
||||
@ -1275,7 +1277,12 @@ namespace spades {
|
||||
case PacketTypeMapStart: {
|
||||
// next map!
|
||||
client->SetWorld(NULL);
|
||||
mapSize = reader.ReadInt();
|
||||
|
||||
auto mapSize = reader.ReadInt();
|
||||
SPLog("Map size advertised by the server: %lu", (unsigned long)mapSize);
|
||||
|
||||
mapLoader.reset(new GameMapLoader());
|
||||
|
||||
status = NetClientStatusReceivingMap;
|
||||
statusString = _Tr("NetClient", "Loading snapshot");
|
||||
} break;
|
||||
@ -1751,12 +1758,18 @@ namespace spades {
|
||||
|
||||
void NetClient::MapLoaded() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
MemoryStream compressed(mapData.data(), mapData.size());
|
||||
DeflateStream inflate(&compressed, CompressModeDecompress, false);
|
||||
GameMap *map;
|
||||
map = GameMap::Load(&inflate);
|
||||
|
||||
SPLog("Map decoding succeeded.");
|
||||
SPAssert(mapLoader);
|
||||
|
||||
// Move `mapLoader` to a local variable so that the associated resources
|
||||
// are released as soon as possible when no longer needed
|
||||
std::unique_ptr<GameMapLoader> mapLoader = std::move(this->mapLoader);
|
||||
|
||||
SPLog("Waiting for the game map decoding to complete...");
|
||||
mapLoader->MarkEOF();
|
||||
mapLoader->WaitComplete();
|
||||
GameMap *map = mapLoader->TakeGameMap();
|
||||
SPLog("The game map was decoded successfully.");
|
||||
|
||||
// now initialize world
|
||||
World *w = new World(properties);
|
||||
@ -1766,8 +1779,6 @@ namespace spades {
|
||||
|
||||
client->SetWorld(w);
|
||||
|
||||
mapData.clear();
|
||||
|
||||
SPAssert(GetWorld());
|
||||
|
||||
SPLog("World loaded. Processing saved packets (%d)...", (int)savedPackets.size());
|
||||
@ -1790,6 +1801,12 @@ namespace spades {
|
||||
}
|
||||
}
|
||||
|
||||
float NetClient::GetMapReceivingProgress() {
|
||||
SPAssert(status == NetClientStatusReceivingMap);
|
||||
|
||||
return mapLoader->GetProgress();
|
||||
}
|
||||
|
||||
NetClient::BandwidthMonitor::BandwidthMonitor(ENetHost *host)
|
||||
: host(host), lastDown(0.0), lastUp(0.0) {
|
||||
sw.Reset();
|
||||
|
@ -58,14 +58,18 @@ namespace spades {
|
||||
struct WeaponInput;
|
||||
class Grenade;
|
||||
struct GameProperties;
|
||||
class GameMapLoader;
|
||||
|
||||
class NetClient {
|
||||
Client *client;
|
||||
NetClientStatus status;
|
||||
ENetHost *host;
|
||||
ENetPeer *peer;
|
||||
std::string statusString;
|
||||
unsigned int mapSize;
|
||||
std::vector<char> mapData;
|
||||
|
||||
/** Only valid in the `NetClientStatusReceivingMap` state */
|
||||
std::unique_ptr<GameMapLoader> mapLoader;
|
||||
|
||||
std::shared_ptr<GameProperties> properties;
|
||||
|
||||
int protocolVersion;
|
||||
@ -133,6 +137,14 @@ namespace spades {
|
||||
|
||||
std::string GetStatusString() { return statusString; }
|
||||
|
||||
/**
|
||||
* Gets how much portion of the map has completed loading.
|
||||
* `GetStatus()` must be `NetClientStatusReceivingMap`.
|
||||
*
|
||||
* @return A value in range `[0, 1]`.
|
||||
*/
|
||||
float GetMapReceivingProgress();
|
||||
|
||||
/**
|
||||
* Return a non-null reference to `GameProperties` for this connection.
|
||||
* Must be the connected state.
|
||||
|
Loading…
x
Reference in New Issue
Block a user