Merge pull request #5336 from IntelOrca/refactor/nosdl/phase-0

Remove SDL2 dependencies: Phase 0
This commit is contained in:
Ted John 2017-05-06 18:07:42 +01:00 committed by GitHub
commit b703520311
29 changed files with 439 additions and 618 deletions

View File

@ -428,7 +428,7 @@ set_target_properties(${PROJECT} PROPERTIES PREFIX "")
set_target_properties(${PROJECT} PROPERTIES COMPILE_FLAGS "-Wundef")
# Link shared libs first
TARGET_LINK_LIBRARIES(${PROJECT} ${GLLIBS})
TARGET_LINK_LIBRARIES(${PROJECT} pthread ${GLLIBS})
# if creating a static binary, precede libraries with -static, then name all the libs
TARGET_LINK_LIBRARIES(${PROJECT} ${STATIC_START} ${SDL2LIBS} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${REQUIREDLIBS} ${BREAKPAD_LIBS})

View File

@ -227,6 +227,7 @@
C686F9541CDBC3B7009F9BFC /* submarine_ride.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9091CDBC3B7009F9BFC /* submarine_ride.c */; };
C686F9551CDBC3B7009F9BFC /* water_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F90A1CDBC3B7009F9BFC /* water_coaster.c */; };
C686F9581CDBC4C7009F9BFC /* vehicle_paint.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9561CDBC4C7009F9BFC /* vehicle_paint.c */; };
C68B2CB51EB60DDE0020651C /* server_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C68B2CB41EB60DDE0020651C /* server_list.cpp */; };
C6B5A7D41CDFE4CB00C9C006 /* S6Exporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6B5A7D01CDFE4CB00C9C006 /* S6Exporter.cpp */; };
C6B5A7D51CDFE4CB00C9C006 /* S6Importer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6B5A7D21CDFE4CB00C9C006 /* S6Importer.cpp */; };
C6CABA7E1E13F11C00D33A6B /* hook.c in Sources */ = {isa = PBXBuildFile; fileRef = C6E96E181E0406F00076A04F /* hook.c */; };
@ -282,7 +283,6 @@
D44272011CC81B3200D84D28 /* Guard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D44270E71CC81B3200D84D28 /* Guard.cpp */; };
D44272021CC81B3200D84D28 /* Json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D44270EB1CC81B3200D84D28 /* Json.cpp */; };
D44272031CC81B3200D84D28 /* Path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D44270F01CC81B3200D84D28 /* Path.cpp */; };
D44272041CC81B3200D84D28 /* Stopwatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D44270F21CC81B3200D84D28 /* Stopwatch.cpp */; };
D44272051CC81B3200D84D28 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D44270F51CC81B3200D84D28 /* String.cpp */; };
D44272061CC81B3200D84D28 /* textinputbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = D44270F91CC81B3200D84D28 /* textinputbuffer.c */; };
D44272081CC81B3200D84D28 /* diagnostic.c in Sources */ = {isa = PBXBuildFile; fileRef = D44270FE1CC81B3200D84D28 /* diagnostic.c */; };
@ -392,7 +392,6 @@
D442727D1CC81B3200D84D28 /* ride_list.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271BB1CC81B3200D84D28 /* ride_list.c */; };
D442727E1CC81B3200D84D28 /* save_prompt.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271BC1CC81B3200D84D28 /* save_prompt.c */; };
D442727F1CC81B3200D84D28 /* scenery.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271BD1CC81B3200D84D28 /* scenery.c */; };
D44272801CC81B3200D84D28 /* server_list.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271BE1CC81B3200D84D28 /* server_list.c */; };
D44272811CC81B3200D84D28 /* server_start.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271BF1CC81B3200D84D28 /* server_start.c */; };
D44272821CC81B3200D84D28 /* shortcut_key_change.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271C01CC81B3200D84D28 /* shortcut_key_change.c */; };
D44272831CC81B3200D84D28 /* shortcut_keys.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271C11CC81B3200D84D28 /* shortcut_keys.c */; };
@ -695,6 +694,7 @@
C686F90A1CDBC3B7009F9BFC /* water_coaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = water_coaster.c; sourceTree = "<group>"; };
C686F9561CDBC4C7009F9BFC /* vehicle_paint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vehicle_paint.c; sourceTree = "<group>"; };
C686F9571CDBC4C7009F9BFC /* vehicle_paint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vehicle_paint.h; sourceTree = "<group>"; };
C68B2CB41EB60DDE0020651C /* server_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = server_list.cpp; sourceTree = "<group>"; };
C6B5A7D01CDFE4CB00C9C006 /* S6Exporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = S6Exporter.cpp; sourceTree = "<group>"; };
C6B5A7D11CDFE4CB00C9C006 /* S6Exporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = S6Exporter.h; sourceTree = "<group>"; };
C6B5A7D21CDFE4CB00C9C006 /* S6Importer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = S6Importer.cpp; sourceTree = "<group>"; };
@ -799,9 +799,6 @@
D44270EF1CC81B3200D84D28 /* Memory.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Memory.hpp; sourceTree = "<group>"; usesTabs = 0; };
D44270F01CC81B3200D84D28 /* Path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Path.cpp; sourceTree = "<group>"; usesTabs = 0; };
D44270F11CC81B3200D84D28 /* Path.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Path.hpp; sourceTree = "<group>"; usesTabs = 0; };
D44270F21CC81B3200D84D28 /* Stopwatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stopwatch.cpp; sourceTree = "<group>"; usesTabs = 0; };
D44270F31CC81B3200D84D28 /* stopwatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stopwatch.h; sourceTree = "<group>"; usesTabs = 1; wrapsLines = 1; };
D44270F41CC81B3200D84D28 /* Stopwatch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stopwatch.hpp; sourceTree = "<group>"; usesTabs = 0; };
D44270F51CC81B3200D84D28 /* String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = String.cpp; sourceTree = "<group>"; usesTabs = 0; };
D44270F61CC81B3200D84D28 /* String.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = String.hpp; sourceTree = "<group>"; usesTabs = 0; };
D44270F71CC81B3200D84D28 /* StringBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StringBuilder.hpp; sourceTree = "<group>"; usesTabs = 0; };
@ -970,7 +967,6 @@
D44271BB1CC81B3200D84D28 /* ride_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ride_list.c; sourceTree = "<group>"; };
D44271BC1CC81B3200D84D28 /* save_prompt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = save_prompt.c; sourceTree = "<group>"; };
D44271BD1CC81B3200D84D28 /* scenery.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scenery.c; sourceTree = "<group>"; };
D44271BE1CC81B3200D84D28 /* server_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = server_list.c; sourceTree = "<group>"; };
D44271BF1CC81B3200D84D28 /* server_start.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = server_start.c; sourceTree = "<group>"; };
D44271C01CC81B3200D84D28 /* shortcut_key_change.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shortcut_key_change.c; sourceTree = "<group>"; };
D44271C11CC81B3200D84D28 /* shortcut_keys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shortcut_keys.c; sourceTree = "<group>"; };
@ -1724,9 +1720,6 @@
D464FEBD1D31A66E00CBABAC /* MemoryStream.h */,
D44270F01CC81B3200D84D28 /* Path.cpp */,
D44270F11CC81B3200D84D28 /* Path.hpp */,
D44270F21CC81B3200D84D28 /* Stopwatch.cpp */,
D44270F31CC81B3200D84D28 /* stopwatch.h */,
D44270F41CC81B3200D84D28 /* Stopwatch.hpp */,
D44270F51CC81B3200D84D28 /* String.cpp */,
D44270F61CC81B3200D84D28 /* String.hpp */,
D44270F71CC81B3200D84D28 /* StringBuilder.hpp */,
@ -2007,7 +2000,7 @@
D44271B91CC81B3200D84D28 /* ride.c */,
D44271BC1CC81B3200D84D28 /* save_prompt.c */,
D44271BD1CC81B3200D84D28 /* scenery.c */,
D44271BE1CC81B3200D84D28 /* server_list.c */,
C68B2CB41EB60DDE0020651C /* server_list.cpp */,
D44271BF1CC81B3200D84D28 /* server_start.c */,
D44271C01CC81B3200D84D28 /* shortcut_key_change.c */,
D44271C11CC81B3200D84D28 /* shortcut_keys.c */,
@ -2856,6 +2849,7 @@
D42E337E1E5C27D600D630AF /* IniReader.cpp in Sources */,
D442723B1CC81B3200D84D28 /* crash.cpp in Sources */,
C650B21A1CCABBDD00B4D91C /* tables.cpp in Sources */,
C68B2CB51EB60DDE0020651C /* server_list.cpp in Sources */,
D44272291CC81B3200D84D28 /* LanguagePack.cpp in Sources */,
D44272901CC81B3200D84D28 /* title_options.c in Sources */,
C6CABA821E1466D600D33A6B /* FileClassifier.cpp in Sources */,
@ -2892,7 +2886,6 @@
D44272061CC81B3200D84D28 /* textinputbuffer.c in Sources */,
C686F9191CDBC3B7009F9BFC /* mine_ride.c in Sources */,
C650B2191CCABBDD00B4D91C /* S4Importer.cpp in Sources */,
D44272801CC81B3200D84D28 /* server_list.c in Sources */,
D44272911CC81B3200D84D28 /* title_scenarioselect.c in Sources */,
C686F8B61CDBC37E009F9BFC /* misc.c in Sources */,
D44272411CC81B3200D84D28 /* rct1.c in Sources */,
@ -2951,7 +2944,6 @@
D44272401CC81B3200D84D28 /* windows.c in Sources */,
D44272881CC81B3200D84D28 /* text_input.c in Sources */,
D442720F1CC81B3200D84D28 /* scrolling_text.c in Sources */,
D44272041CC81B3200D84D28 /* Stopwatch.cpp in Sources */,
D43407D81D0E14BE00C2B3D4 /* DrawImageShader.cpp in Sources */,
007A05D01CFB2C8B00F419C3 /* NetworkGroup.cpp in Sources */,
656F6C8E1E45BFC200E0F770 /* Version.cpp in Sources */,
@ -3201,7 +3193,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LD_NO_PIE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@ -3247,7 +3239,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LD_NO_PIE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};

View File

@ -14,9 +14,7 @@
*****************************************************************************/
#pragma endregion
#include <SDL_platform.h>
#if defined(DEBUG) && defined(__WINDOWS__)
#if defined(DEBUG) && defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef GetMessage
@ -29,7 +27,7 @@ namespace Debug
void Break()
{
#if defined(DEBUG)
#if defined(__WINDOWS__)
#if defined(_WIN32)
if (IsDebuggerPresent())
{
DebugBreak();

View File

@ -17,10 +17,14 @@
#pragma once
#include "../common.h"
#include <SDL.h>
#include "IStream.hpp"
#include "Math.hpp"
#include "String.hpp"
extern "C"
{
#include "../localisation/language.h"
}
enum
{
@ -30,12 +34,12 @@ enum
};
/**
* A stream for reading and writing to files. Wraps an SDL_RWops, SDL2's cross platform file stream.
* A stream for reading and writing to files.
*/
class FileStream final : public IStream
{
private:
SDL_RWops * _file = 0;
FILE * _file = nullptr;
bool _ownsFilePtr = false;
bool _canRead = false;
bool _canWrite = false;
@ -71,41 +75,35 @@ public:
throw;
}
_file = SDL_RWFromFile(path, mode);
#ifdef _WIN32
wchar_t * pathW = utf8_to_widechar(path);
wchar_t * modeW = utf8_to_widechar(mode);
_file = _wfopen(pathW, modeW);
free(pathW);
free(modeW);
#else
_file = fopen(path, mode);
#endif
if (_file == nullptr)
{
throw IOException(SDL_GetError());
throw IOException(String::StdFormat("Unable to open '%s'", path));
}
_fileSize = SDL_RWsize(_file);
Seek(0, STREAM_SEEK_END);
_fileSize = GetPosition();
Seek(0, STREAM_SEEK_BEGIN);
_ownsFilePtr = true;
}
FileStream(SDL_RWops * ops, sint32 fileMode)
{
_file = ops;
switch (fileMode) {
case FILE_MODE_OPEN:
_canRead = true;
_canWrite = false;
break;
case FILE_MODE_WRITE:
_canRead = true;
_canWrite = true;
break;
default:
throw;
}
_fileSize = SDL_RWsize(_file);
}
~FileStream()
~FileStream() override
{
if (!_disposed)
{
_disposed = true;
if (_ownsFilePtr)
{
SDL_RWclose(_file);
fclose(_file);
}
}
}
@ -114,7 +112,16 @@ public:
bool CanWrite() const override { return _canWrite; }
uint64 GetLength() const override { return _fileSize; }
uint64 GetPosition() const override { return SDL_RWtell(_file); }
uint64 GetPosition() const override
{
#if defined(_MSC_VER)
return _ftelli64(_file);
#elif (defined(__APPLE__) && defined(__MACH__))
return ftello(_file);
#else
return ftello64(_file);
#endif
}
void SetPosition(uint64 position) override
{
@ -123,17 +130,43 @@ public:
void Seek(sint64 offset, sint32 origin) override
{
#if defined(_MSC_VER)
switch (origin) {
case STREAM_SEEK_BEGIN:
SDL_RWseek(_file, offset, RW_SEEK_SET);
_fseeki64(_file, offset, SEEK_SET);
break;
case STREAM_SEEK_CURRENT:
SDL_RWseek(_file, offset, RW_SEEK_CUR);
_fseeki64(_file, offset, SEEK_CUR);
break;
case STREAM_SEEK_END:
SDL_RWseek(_file, offset, RW_SEEK_END);
_fseeki64(_file, offset, SEEK_END);
break;
}
#elif (defined(__APPLE__) && defined(__MACH__))
switch (origin) {
case STREAM_SEEK_BEGIN:
fseeko(_file, offset, SEEK_SET);
break;
case STREAM_SEEK_CURRENT:
fseeko(_file, offset, SEEK_CUR);
break;
case STREAM_SEEK_END:
fseeko(_file, offset, SEEK_END);
break;
}
#else
switch (origin) {
case STREAM_SEEK_BEGIN:
fseeko64(_file, offset, SEEK_SET);
break;
case STREAM_SEEK_CURRENT:
fseeko64(_file, offset, SEEK_CUR);
break;
case STREAM_SEEK_END:
fseeko64(_file, offset, SEEK_END);
break;
}
#endif
}
void Read(void * buffer, uint64 length) override
@ -141,7 +174,7 @@ public:
uint64 remainingBytes = GetLength() - GetPosition();
if (length <= remainingBytes)
{
if (SDL_RWread(_file, buffer, (size_t)length, 1) == 1)
if (fread(buffer, (size_t)length, 1, _file) == 1)
{
return;
}
@ -151,7 +184,7 @@ public:
void Write(const void * buffer, uint64 length) override
{
if (SDL_RWwrite(_file, buffer, (size_t)length, 1) != 1)
if (fwrite(buffer, (size_t)length, 1, _file) != 1)
{
throw IOException("Unable to write to file.");
}
@ -162,7 +195,7 @@ public:
uint64 TryRead(void * buffer, uint64 length) override
{
size_t readBytes = SDL_RWread(_file, buffer, 1, (size_t)length);
size_t readBytes = fread(buffer, 1, (size_t)length, _file);
return readBytes;
}
};

View File

@ -1,150 +0,0 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include <SDL_timer.h>
#include "Stopwatch.hpp"
uint64 Stopwatch::Frequency = 0;
Stopwatch::Stopwatch()
{
Reset();
}
uint64 Stopwatch::GetElapsedTicks() const
{
uint64 result = _total;
if (_isRunning)
{
uint64 ticks = QueryCurrentTicks();
if (ticks != 0) {
result += QueryCurrentTicks() - _last;
}
}
return result;
}
uint64 Stopwatch::GetElapsedMilliseconds() const
{
if (Frequency == 0)
{
Frequency = QueryFrequency();
if (Frequency == 0)
{
return 0;
}
}
return (GetElapsedTicks() * 1000) / Frequency;
}
void Stopwatch::Reset()
{
_isRunning = false;
_total = 0;
_last = 0;
}
void Stopwatch::Start()
{
if (_isRunning) return;
uint64 ticks = QueryCurrentTicks();
if (ticks != 0)
{
_last = ticks;
_isRunning = true;
}
}
void Stopwatch::Restart()
{
Reset();
Start();
}
void Stopwatch::Stop()
{
uint64 ticks = QueryCurrentTicks();
if (ticks != 0)
{
_total += QueryCurrentTicks() - _last;
}
_isRunning = false;
}
uint64 Stopwatch::QueryFrequency()
{
return SDL_GetPerformanceFrequency();
}
uint64 Stopwatch::QueryCurrentTicks()
{
return SDL_GetPerformanceCounter();
}
extern "C"
{
#include "stopwatch.h"
void stopwatch_create(stopwatch_t * stopwatch)
{
stopwatch->context = new Stopwatch();
}
void stopwatch_dispose(stopwatch_t * stopwatch)
{
delete static_cast<Stopwatch *>(stopwatch->context);
}
uint64 stopwatch_GetElapsedTicks(stopwatch_t * stopwatch)
{
Stopwatch * ctx = static_cast<Stopwatch *>(stopwatch->context);
return ctx->GetElapsedTicks();
}
uint64 stopwatch_GetElapsedMilliseconds(stopwatch_t * stopwatch)
{
Stopwatch * ctx = static_cast<Stopwatch *>(stopwatch->context);
return ctx->GetElapsedMilliseconds();
}
void stopwatch_Reset(stopwatch_t * stopwatch)
{
Stopwatch * ctx = static_cast<Stopwatch *>(stopwatch->context);
return ctx->Reset();
}
void stopwatch_Start(stopwatch_t * stopwatch)
{
Stopwatch * ctx = static_cast<Stopwatch *>(stopwatch->context);
return ctx->Start();
}
void stopwatch_Restart(stopwatch_t * stopwatch)
{
Stopwatch * ctx = static_cast<Stopwatch *>(stopwatch->context);
return ctx->Restart();
}
void stopwatch_Stop(stopwatch_t * stopwatch)
{
Stopwatch * ctx = static_cast<Stopwatch *>(stopwatch->context);
return ctx->Stop();
}
}

View File

@ -1,52 +0,0 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#pragma once
extern "C"
{
#include "../common.h"
}
/**
* Class to accurately measure elapsed time with high precision.
*/
class Stopwatch final
{
private:
/** Number of ticks in a second. */
static uint64 Frequency;
uint64 _total;
uint64 _last;
bool _isRunning;
static uint64 QueryFrequency();
static uint64 QueryCurrentTicks();
public:
bool IsRunning() const { return _isRunning; }
Stopwatch();
uint64 GetElapsedTicks() const;
uint64 GetElapsedMilliseconds() const;
void Reset();
void Start();
void Restart();
void Stop();
};

View File

@ -1,40 +0,0 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#ifndef _STOPWATCH_H_
#define _STOPWATCH_H_
#include "../common.h"
/////////////////////////////
// C wrapper for Stopwatch //
/////////////////////////////
typedef struct stopwatch_t {
void *context;
} stopwatch_t;
void stopwatch_create(stopwatch_t *stopwatch);
void stopwatch_dispose(stopwatch_t *stopwatch);
uint64 stopwatch_GetElapsedTicks(stopwatch_t *stopwatch);
uint64 stopwatch_GetElapsedMilliseconds(stopwatch_t *stopwatch);
void stopwatch_Reset(stopwatch_t *stopwatch);
void stopwatch_Start(stopwatch_t *stopwatch);
void stopwatch_Restart(stopwatch_t *stopwatch);
void stopwatch_Stop(stopwatch_t *stopwatch);
#endif

View File

@ -427,7 +427,7 @@ void game_logic_update()
// start autosave timer after update
if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE)
gLastAutoSaveUpdate = SDL_GetTicks();
gLastAutoSaveUpdate = platform_get_ticks();
}
/**
@ -585,7 +585,7 @@ sint32 game_do_command_p(sint32 command, sint32 *eax, sint32 *ebx, sint32 *ecx,
// start autosave timer after game command
if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE)
gLastAutoSaveUpdate = SDL_GetTicks();
gLastAutoSaveUpdate = platform_get_ticks();
return cost;
}

View File

@ -131,7 +131,8 @@ void chat_draw(rct_drawpixelinfo * dpi)
// Draw chat history
for (sint32 i = 0; i < CHAT_HISTORY_SIZE; i++, y -= stringHeight) {
if (!gChatOpen && SDL_TICKS_PASSED(SDL_GetTicks(), chat_history_get_time(i) + 10000)) {
uint32 expireTime = chat_history_get_time(i) + 10000;
if (!gChatOpen && platform_get_ticks() > expireTime) {
break;
}
@ -174,7 +175,7 @@ void chat_history_add(const char *src)
sint32 index = _chatHistoryIndex % CHAT_HISTORY_SIZE;
memset(_chatHistory[index], 0, CHAT_INPUT_SIZE);
memcpy(_chatHistory[index], src, min(strlen(src), CHAT_INPUT_SIZE - 1));
_chatHistoryTime[index] = SDL_GetTicks();
_chatHistoryTime[index] = platform_get_ticks();
_chatHistoryIndex++;
Mixer_Play_Effect(SOUND_NEWS_ITEM, 0, SDL_MIX_MAXVOLUME, 0, 1.5f, true);
network_append_chat_log(src);

View File

@ -85,7 +85,7 @@ sint32 NetworkConnection::ReadPacket()
}
if (InboundPacket.BytesTransferred == sizeof(InboundPacket.Size) + InboundPacket.Size)
{
_lastPacketTime = SDL_GetTicks();
_lastPacketTime = platform_get_ticks();
return NETWORK_READPACKET_SUCCESS;
}
}
@ -150,13 +150,13 @@ void NetworkConnection::SendQueuedPackets()
void NetworkConnection::ResetLastPacketTime()
{
_lastPacketTime = SDL_GetTicks();
_lastPacketTime = platform_get_ticks();
}
bool NetworkConnection::ReceivedPacketRecently()
{
#ifndef DEBUG
if (SDL_TICKS_PASSED(SDL_GetTicks(), _lastPacketTime + 7000))
if (platform_get_ticks() > _lastPacketTime + 7000)
{
return false;
}

View File

@ -77,13 +77,13 @@ public:
{
switch (_status) {
case ADVERTISE_STATUS_UNREGISTERED:
if (_lastAdvertiseTime == 0 || SDL_TICKS_PASSED(SDL_GetTicks(), _lastAdvertiseTime + MASTER_SERVER_REGISTER_TIME))
if (_lastAdvertiseTime == 0 || platform_get_ticks() > _lastAdvertiseTime + MASTER_SERVER_REGISTER_TIME)
{
SendRegistration();
}
break;
case ADVERTISE_STATUS_REGISTERED:
if (SDL_TICKS_PASSED(SDL_GetTicks(), _lastHeartbeatTime + MASTER_SERVER_HEARTBEAT_TIME))
if (platform_get_ticks() > _lastHeartbeatTime + MASTER_SERVER_HEARTBEAT_TIME)
{
SendHeartbeat();
}
@ -97,7 +97,7 @@ public:
private:
void SendRegistration()
{
_lastAdvertiseTime = SDL_GetTicks();
_lastAdvertiseTime = platform_get_ticks();
// Send the registration request
http_request_t request = { 0 };
@ -139,7 +139,7 @@ private:
request.root = jsonBody;
request.type = HTTP_DATA_JSON;
_lastHeartbeatTime = SDL_GetTicks();
_lastHeartbeatTime = platform_get_ticks();
http_request_async(&request, [](http_response_t *response) -> void
{
if (response == nullptr)

View File

@ -16,14 +16,7 @@
#pragma once
#include <SDL_endian.h>
#include <SDL_platform.h>
#ifndef DISABLE_NETWORK
#include "../common.h"
#endif
enum NETWORK_AUTH
{
@ -80,7 +73,7 @@ struct ByteSwapT<2>
{
static uint16 SwapBE(uint16 value)
{
return SDL_SwapBE16(value);
return (uint16)((value << 8) | (value >> 8));
}
};
@ -89,7 +82,10 @@ struct ByteSwapT<4>
{
static uint32 SwapBE(uint32 value)
{
return SDL_SwapBE32(value);
return (uint32)(((value << 24) |
((value << 8) & 0x00FF0000) |
((value >> 8) & 0x0000FF00) |
(value >> 24)));
}
};

View File

@ -16,14 +16,14 @@
#ifndef DISABLE_NETWORK
#include <chrono>
#include <future>
#include <thread>
// MSVC: include <math.h> here otherwise PI gets defined twice
#include <math.h>
#include <SDL_platform.h>
#include <SDL_thread.h>
#include <SDL_timer.h>
#ifdef __WINDOWS__
#ifdef _WIN32
// winsock2 must be included before windows.h
#include <winsock2.h>
#include <ws2tcpip.h>
@ -58,15 +58,15 @@
#define FLAG_NO_PIPE MSG_NOSIGNAL
#else
#define FLAG_NO_PIPE 0
#endif // defined(__LINUX__)
#endif // __WINDOWS__
#endif // defined(__linux__)
#endif // _WIN32
#include "../core/Exception.hpp"
#include "TcpSocket.h"
constexpr uint32 CONNECT_TIMEOUT_MS = 3000;
constexpr auto CONNECT_TIMEOUT = std::chrono::milliseconds(3000);
#ifdef __WINDOWS__
#ifdef _WIN32
static bool _wsaInitialised = false;
#endif
@ -79,13 +79,6 @@ public:
explicit SocketException(const std::string &message) : Exception(message) { }
};
struct ConnectRequest
{
TcpSocket * Socket;
std::string Address;
uint16 Port;
};
class TcpSocket final : public ITcpSocket
{
private:
@ -93,25 +86,22 @@ private:
uint16 _listeningPort = 0;
SOCKET _socket = INVALID_SOCKET;
std::string _hostName;
SDL_mutex * _connectMutex = nullptr;
std::string _error;
std::string _hostName;
std::future<void> _connectFuture;
std::string _error;
public:
TcpSocket()
{
_connectMutex = SDL_CreateMutex();
}
~TcpSocket() override
{
SDL_LockMutex(_connectMutex);
if (_connectFuture.valid())
{
CloseSocket();
_connectFuture.wait();
}
SDL_UnlockMutex(_connectMutex);
SDL_DestroyMutex(_connectMutex);
CloseSocket();
}
SOCKET_STATUS GetStatus() override
@ -264,7 +254,6 @@ public:
}
// Connect
uint32 connectStartTick;
sint32 connectResult = connect(_socket, (sockaddr *)&ss, ss_len);
if (connectResult != SOCKET_ERROR || (LAST_SOCKET_ERROR() != EINPROGRESS &&
LAST_SOCKET_ERROR() != EWOULDBLOCK))
@ -272,7 +261,7 @@ public:
throw SocketException("Failed to connect.");
}
connectStartTick = SDL_GetTicks();
auto connectStartTime = std::chrono::system_clock::now();
sint32 error = 0;
socklen_t len = sizeof(error);
@ -288,7 +277,7 @@ public:
do
{
// Sleep for a bit
SDL_Delay(100);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
fd_set writeFD;
FD_ZERO(&writeFD);
@ -310,7 +299,7 @@ public:
return;
}
}
} while (!SDL_TICKS_PASSED(SDL_GetTicks(), connectStartTick + CONNECT_TIMEOUT_MS));
} while ((std::chrono::system_clock::now() - connectStartTime) < CONNECT_TIMEOUT);
// Connection request timed out
throw SocketException("Connection timed out.");
@ -329,30 +318,22 @@ public:
throw Exception("Socket not closed.");
}
if (SDL_TryLockMutex(_connectMutex) == 0)
auto saddress = std::string(address);
std::promise<void> barrier;
_connectFuture = barrier.get_future();
auto thread = std::thread([this, saddress, port](std::promise<void> barrier2) -> void
{
// Spin off a worker thread for resolving the address
auto req = new ConnectRequest();
req->Socket = this;
req->Address = std::string(address);
req->Port = port;
SDL_CreateThread([](void * pointer) -> sint32
try
{
auto req2 = static_cast<ConnectRequest *>(pointer);
try
{
req2->Socket->Connect(req2->Address.c_str(), req2->Port);
}
catch (const Exception & ex)
{
req2->Socket->_error = std::string(ex.GetMessage());
}
SDL_UnlockMutex(req2->Socket->_connectMutex);
delete req2;
return 0;
}, 0, req);
}
Connect(saddress.c_str(), port);
}
catch (const Exception &ex)
{
_error = std::string(ex.GetMessage());
}
barrier2.set_value();
}, std::move(barrier));
thread.detach();
}
void Disconnect() override
@ -419,11 +400,11 @@ public:
void Close() override
{
SDL_LockMutex(_connectMutex);
if (_connectFuture.valid())
{
CloseSocket();
_connectFuture.wait();
}
SDL_UnlockMutex(_connectMutex);
CloseSocket();
}
const char * GetHostName() const override

View File

@ -14,9 +14,10 @@
*****************************************************************************/
#pragma endregion
#include <thread>
extern "C" {
#include "http.h"
#include "../platform/platform.h"
}
#ifdef DISABLE_HTTP
@ -41,6 +42,70 @@ void http_dispose() { }
#define MIME_TYPE_APPLICATION_JSON "application/json"
#define OPENRCT2_USER_AGENT "OpenRCT2/" OPENRCT2_VERSION
struct HttpRequest2
{
void * Tag = nullptr;
std::string Method;
std::string Url;
http_data_type Type;
size_t Size = 0;
union
{
char * Buffer = 0;
json_t * Json;
} Body;
HttpRequest2() { }
HttpRequest2(const HttpRequest2 &request)
{
Tag = request.Tag;
Method = request.Method;
Url = request.Url;
Type = request.Type;
Size = request.Size;
if (request.Type == HTTP_DATA_JSON)
{
Body.Json = json_deep_copy(request.Body.Json);
}
else
{
Body.Buffer = new char[request.Size];
memcpy(Body.Buffer, request.Body.Buffer, request.Size);
}
}
explicit HttpRequest2(const http_request_t * request)
{
Tag = request->tag;
Method = std::string(request->method);
Url = std::string(request->url);
Type = request->type;
Size = request->size;
if (request->type == HTTP_DATA_JSON)
{
Body.Json = json_deep_copy(request->root);
}
else
{
Body.Buffer = new char[request->size];
memcpy(Body.Buffer, request->body, request->size);
}
}
~HttpRequest2()
{
if (Type == HTTP_DATA_JSON)
{
json_decref(Body.Json);
}
else
{
delete Body.Buffer;
}
}
};
typedef struct read_buffer {
char *ptr;
size_t length;
@ -85,7 +150,7 @@ static size_t http_request_write_func(void *ptr, size_t size, size_t nmemb, void
return newBytesLength;
}
http_response_t *http_request(const http_request_t *request)
static http_response_t *http_request(const HttpRequest2 &request)
{
CURL *curl;
CURLcode curlResult;
@ -97,13 +162,13 @@ http_response_t *http_request(const http_request_t *request)
if (curl == NULL)
return NULL;
if (request->type == HTTP_DATA_JSON && request->root != NULL) {
readBuffer.ptr = json_dumps(request->root, JSON_COMPACT);
if (request.Type == HTTP_DATA_JSON && request.Body.Json != NULL) {
readBuffer.ptr = json_dumps(request.Body.Json, JSON_COMPACT);
readBuffer.length = strlen(readBuffer.ptr);
readBuffer.position = 0;
} else if (request->type == HTTP_DATA_RAW && request->body != NULL) {
readBuffer.ptr = request->body;
readBuffer.length = request->size;
} else if (request.Type == HTTP_DATA_RAW && request.Body.Buffer != NULL) {
readBuffer.ptr = request.Body.Buffer;
readBuffer.length = request.Size;
readBuffer.position = 0;
}
@ -113,10 +178,10 @@ http_response_t *http_request(const http_request_t *request)
curl_slist *headers = NULL;
if (request->type == HTTP_DATA_JSON) {
if (request.Type == HTTP_DATA_JSON) {
headers = curl_slist_append(headers, "Accept: " MIME_TYPE_APPLICATION_JSON);
if (request->root != NULL) {
if (request.Body.Json != NULL) {
headers = curl_slist_append(headers, "Content-Type: " MIME_TYPE_APPLICATION_JSON);
}
}
@ -129,18 +194,18 @@ http_response_t *http_request(const http_request_t *request)
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, readBuffer.ptr);
}
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, request->method);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, request.Method.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
curl_easy_setopt(curl, CURLOPT_USERAGENT, OPENRCT2_USER_AGENT);
curl_easy_setopt(curl, CURLOPT_URL, request->url);
curl_easy_setopt(curl, CURLOPT_URL, request.Url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &writeBuffer);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_request_write_func);
curlResult = curl_easy_perform(curl);
if (request->type == HTTP_DATA_JSON && request->root != NULL) {
if (request.Type == HTTP_DATA_JSON && request.Body.Json != NULL) {
free(readBuffer.ptr);
}
@ -173,7 +238,7 @@ http_response_t *http_request(const http_request_t *request)
root = json_loads(writeBuffer.ptr, 0, &error);
if (root != NULL) {
response = (http_response_t*) malloc(sizeof(http_response_t));
response->tag = request->tag;
response->tag = request.Tag;
response->status_code = (sint32) httpStatusCode;
response->root = root;
response->type = HTTP_DATA_JSON;
@ -182,7 +247,7 @@ http_response_t *http_request(const http_request_t *request)
free(writeBuffer.ptr);
} else {
response = (http_response_t*) malloc(sizeof(http_response_t));
response->tag = request->tag;
response->tag = request.Tag;
response->status_code = (sint32) httpStatusCode;
response->body = writeBuffer.ptr;
response->type = HTTP_DATA_RAW;
@ -194,54 +259,15 @@ http_response_t *http_request(const http_request_t *request)
return response;
}
void http_request_async(const http_request_t *request, void (*callback)(http_response_t*))
void http_request_async(const http_request_t * request, void (*callback)(http_response_t*))
{
struct TempThreadArgs {
http_request_t request;
void (*callback)(http_response_t*);
};
TempThreadArgs *args = (TempThreadArgs*)malloc(sizeof(TempThreadArgs));
args->request.url = _strdup(request->url);
args->request.method = request->method;
if (request->type == HTTP_DATA_JSON) {
args->request.root = json_deep_copy(request->root);
} else {
char* bodyCopy = (char*) malloc(request->size);
memcpy(bodyCopy, request->body, request->size);
args->request.body = bodyCopy;
}
args->request.type = request->type;
args->request.size = request->size;
args->request.tag = request->tag;
args->callback = callback;
SDL_Thread *thread = SDL_CreateThread([](void *ptr) -> sint32 {
TempThreadArgs *args2 = (TempThreadArgs*)ptr;
http_response_t *response = http_request(&args2->request);
args2->callback(response);
free((char*)args2->request.url);
if (args2->request.type == HTTP_DATA_JSON) {
json_decref((json_t*) args2->request.root);
} else {
free(args2->request.body);
}
free(args2);
return 0;
}, NULL, args);
if (thread == NULL) {
log_error("Unable to create thread!");
callback(NULL);
} else {
SDL_DetachThread(thread);
}
auto request2 = HttpRequest2(request);
auto thread = std::thread([](const HttpRequest2 &req, void(*callback2)(http_response_t*)) -> void
{
http_response_t * response = http_request(req);
callback2(response);
}, std::move(request2), callback);
thread.detach();
}
void http_request_dispose(http_response_t *response)
@ -269,15 +295,15 @@ const char *http_get_extension_from_url(const char *url, const char *fallback)
bool http_download_park(const char *url, char tmpPath[L_tmpnam + 10])
{
// Download park to buffer in memory
http_request_t request;
request.url = url;
request.method = "GET";
request.type = HTTP_DATA_NONE;
HttpRequest2 request;
request.Url = url;
request.Method = "GET";
request.Type = HTTP_DATA_NONE;
http_response_t *response = http_request(&request);
http_response_t *response = http_request(request);
if (response == NULL || response->status_code != 200) {
Console::Error::WriteLine("Failed to download '%s'", request.url);
Console::Error::WriteLine("Failed to download '%s'", request.Url.c_str());
if (response != NULL) {
http_request_dispose(response);
}
@ -286,20 +312,20 @@ bool http_download_park(const char *url, char tmpPath[L_tmpnam + 10])
// Generate temporary filename that includes the original extension
if (tmpnam(tmpPath) == NULL) {
Console::Error::WriteLine("Failed to generate temporary filename for downloaded park '%s'", request.url);
Console::Error::WriteLine("Failed to generate temporary filename for downloaded park '%s'", request.Url.c_str());
http_request_dispose(response);
return false;
}
size_t remainingBytes = L_tmpnam + 10 - strlen(tmpPath);
const char *ext = http_get_extension_from_url(request.url, ".sv6");
const char *ext = http_get_extension_from_url(request.Url.c_str(), ".sv6");
strncat(tmpPath, ext, remainingBytes);
// Store park in temporary file and load it (discard ending NUL in response body)
FILE* tmpFile = fopen(tmpPath, "wb");
if (tmpFile == NULL) {
Console::Error::WriteLine("Failed to write downloaded park '%s' to temporary file", request.url);
Console::Error::WriteLine("Failed to write downloaded park '%s' to temporary file", request.Url.c_str());
http_request_dispose(response);
return false;
}

View File

@ -55,7 +55,6 @@ typedef struct http_response_t {
#define HTTP_METHOD_PUT "PUT"
#define HTTP_METHOD_DELETE "DELETE"
http_response_t *http_request(const http_request_t *request);
void http_request_async(const http_request_t *request, void (*callback)(http_response_t*));
void http_request_dispose(http_response_t *response);

View File

@ -14,8 +14,6 @@
*****************************************************************************/
#pragma endregion
#include <SDL_platform.h>
#include "../core/Guard.hpp"
#include "../OpenRCT2.h"
@ -135,6 +133,7 @@ bool Network::Init()
status = NETWORK_STATUS_READY;
server_connection = new NetworkConnection();
ServerName = std::string();
ServerDescription = std::string();
ServerGreeting = std::string();
@ -153,8 +152,8 @@ void Network::Close()
return;
}
if (mode == NETWORK_MODE_CLIENT) {
delete server_connection.Socket;
server_connection.Socket = nullptr;
delete server_connection->Socket;
server_connection->Socket = nullptr;
} else if (mode == NETWORK_MODE_SERVER) {
delete listening_socket;
listening_socket = nullptr;
@ -165,9 +164,10 @@ void Network::Close()
mode = NETWORK_MODE_NONE;
status = NETWORK_STATUS_NONE;
_lastConnectStatus = SOCKET_STATUS_CLOSED;
server_connection.AuthStatus = NETWORK_AUTH_NONE;
server_connection.InboundPacket.Clear();
server_connection.SetLastDisconnectReason(nullptr);
server_connection->AuthStatus = NETWORK_AUTH_NONE;
server_connection->InboundPacket.Clear();
server_connection->SetLastDisconnectReason(nullptr);
SafeDelete(server_connection);
client_connection_list.clear();
game_command_queue.clear();
@ -192,9 +192,9 @@ bool Network::BeginClient(const char* host, uint16 port)
mode = NETWORK_MODE_CLIENT;
assert(server_connection.Socket == nullptr);
server_connection.Socket = CreateTcpSocket();
server_connection.Socket->ConnectAsync(host, port);
assert(server_connection->Socket == nullptr);
server_connection->Socket = CreateTcpSocket();
server_connection->Socket->ConnectAsync(host, port);
status = NETWORK_STATUS_CONNECTING;
_lastConnectStatus = SOCKET_STATUS_CLOSED;
@ -339,7 +339,7 @@ sint32 Network::GetStatus()
sint32 Network::GetAuthStatus()
{
if (GetMode() == NETWORK_MODE_CLIENT) {
return server_connection.AuthStatus;
return server_connection->AuthStatus;
} else
if (GetMode() == NETWORK_MODE_SERVER) {
return NETWORK_AUTH_OK;
@ -380,10 +380,12 @@ void Network::UpdateServer()
it++;
}
}
if (SDL_TICKS_PASSED(SDL_GetTicks(), last_tick_sent_time + 25)) {
uint32 ticks = platform_get_ticks();
if (ticks > last_tick_sent_time + 25) {
Server_Send_TICK();
}
if (SDL_TICKS_PASSED(SDL_GetTicks(), last_ping_sent_time + 3000)) {
if (ticks > last_ping_sent_time + 3000) {
Server_Send_PING();
Server_Send_PINGLIST();
}
@ -403,7 +405,7 @@ void Network::UpdateClient()
switch(status){
case NETWORK_STATUS_CONNECTING:
{
switch (server_connection.Socket->GetStatus()) {
switch (server_connection->Socket->GetStatus()) {
case SOCKET_STATUS_RESOLVING:
{
if (_lastConnectStatus != SOCKET_STATUS_RESOLVING)
@ -427,14 +429,14 @@ void Network::UpdateClient()
window_network_status_open(str_connecting, []() -> void {
gNetwork.Close();
});
server_connect_time = SDL_GetTicks();
server_connect_time = platform_get_ticks();
}
break;
}
case SOCKET_STATUS_CONNECTED:
{
status = NETWORK_STATUS_CONNECTED;
server_connection.ResetLastPacketTime();
server_connection->ResetLastPacketTime();
Client_Send_TOKEN();
char str_authenticating[256];
format_string(str_authenticating, 256, STR_MULTIPLAYER_AUTHENTICATING, NULL);
@ -445,7 +447,7 @@ void Network::UpdateClient()
}
default:
{
const char * error = server_connection.Socket->GetError();
const char * error = server_connection->Socket->GetError();
if (error != nullptr) {
Console::Error::WriteLine(error);
}
@ -460,15 +462,15 @@ void Network::UpdateClient()
}
case NETWORK_STATUS_CONNECTED:
{
if (!ProcessConnection(server_connection)) {
if (!ProcessConnection(*server_connection)) {
// Do not show disconnect message window when password window closed/canceled
if (server_connection.AuthStatus == NETWORK_AUTH_REQUIREPASSWORD) {
if (server_connection->AuthStatus == NETWORK_AUTH_REQUIREPASSWORD) {
window_network_status_close();
} else {
char str_disconnected[256];
if (server_connection.GetLastDisconnectReason()) {
const char * disconnect_reason = server_connection.GetLastDisconnectReason();
if (server_connection->GetLastDisconnectReason()) {
const char * disconnect_reason = server_connection->GetLastDisconnectReason();
format_string(str_disconnected, 256, STR_MULTIPLAYER_DISCONNECTED_WITH_REASON, &disconnect_reason);
} else {
format_string(str_disconnected, 256, STR_MULTIPLAYER_DISCONNECTED_NO_REASON, NULL);
@ -609,7 +611,7 @@ void Network::SetPassword(const char* password)
void Network::ShutdownClient()
{
if (GetMode() == NETWORK_MODE_CLIENT) {
server_connection.Socket->Disconnect();
server_connection->Socket->Disconnect();
}
}
@ -858,8 +860,8 @@ void Network::Client_Send_TOKEN()
log_verbose("requesting token");
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_TOKEN;
server_connection.AuthStatus = NETWORK_AUTH_REQUESTED;
server_connection.QueuePacket(std::move(packet));
server_connection->AuthStatus = NETWORK_AUTH_REQUESTED;
server_connection->QueuePacket(std::move(packet));
}
void Network::Client_Send_AUTH(const char* name, const char* password, const char* pubkey, const char *sig, size_t sigsize)
@ -873,8 +875,8 @@ void Network::Client_Send_AUTH(const char* name, const char* password, const cha
assert(sigsize <= (size_t)UINT32_MAX);
*packet << (uint32)sigsize;
packet->Write((const uint8 *)sig, sigsize);
server_connection.AuthStatus = NETWORK_AUTH_REQUESTED;
server_connection.QueuePacket(std::move(packet));
server_connection->AuthStatus = NETWORK_AUTH_REQUESTED;
server_connection->QueuePacket(std::move(packet));
}
void Network::Client_Send_OBJECTS(const std::vector<std::string> &objects)
@ -887,7 +889,7 @@ void Network::Client_Send_OBJECTS(const std::vector<std::string> &objects)
log_verbose("client requests object %s", objects[i].c_str());
packet->Write((const uint8 *)objects[i].c_str(), 8);
}
server_connection.QueuePacket(std::move(packet));
server_connection->QueuePacket(std::move(packet));
}
void Network::Server_Send_TOKEN(NetworkConnection& connection)
@ -1015,7 +1017,7 @@ void Network::Client_Send_CHAT(const char* text)
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_CHAT;
packet->WriteString(text);
server_connection.QueuePacket(std::move(packet));
server_connection->QueuePacket(std::move(packet));
}
void Network::Server_Send_CHAT(const char* text)
@ -1031,7 +1033,7 @@ void Network::Client_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_GAMECMD << (uint32)gCurrentTicks << eax << (ebx | GAME_COMMAND_FLAG_NETWORKED)
<< ecx << edx << esi << edi << ebp << callback;
server_connection.QueuePacket(std::move(packet));
server_connection->QueuePacket(std::move(packet));
}
void Network::Server_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 playerid, uint8 callback)
@ -1044,7 +1046,7 @@ void Network::Server_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx
void Network::Server_Send_TICK()
{
last_tick_sent_time = SDL_GetTicks();
last_tick_sent_time = platform_get_ticks();
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_TICK << (uint32)gCurrentTicks << (uint32)gScenarioSrand0;
uint32 flags = 0;
@ -1080,16 +1082,16 @@ void Network::Client_Send_PING()
{
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_PING;
server_connection.QueuePacket(std::move(packet));
server_connection->QueuePacket(std::move(packet));
}
void Network::Server_Send_PING()
{
last_ping_sent_time = SDL_GetTicks();
last_ping_sent_time = platform_get_ticks();
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_PING;
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
(*it)->PingTime = SDL_GetTicks();
(*it)->PingTime = platform_get_ticks();
}
SendPacketToClients(*packet, true);
}
@ -1254,7 +1256,7 @@ void Network::ProcessGameCommandQueue()
NetworkPlayer* player = GetPlayerByID(gc.playerid);
if (player) {
player->LastAction = NetworkActions::FindCommand(command);
player->LastActionTime = SDL_GetTicks();
player->LastActionTime = platform_get_ticks();
player->AddMoneySpent(cost);
}
}
@ -1860,7 +1862,7 @@ void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket
sint32 commandCommand = args[4];
uint32 ticks = SDL_GetTicks(); //tick count is different by time last_action_time is set, keep same value.
uint32 ticks = platform_get_ticks(); //tick count is different by time last_action_time is set, keep same value.
// Check if player's group permission allows command to run
NetworkGroup* group = GetGroupByID(connection.Player->Group);
@ -1875,7 +1877,7 @@ void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket
if (commandCommand == GAME_COMMAND_PLACE_SCENERY) {
if (
ticks - connection.Player->LastPlaceSceneryTime < ACTION_COOLDOWN_TIME_PLACE_SCENERY &&
// Incase SDL_GetTicks() wraps after ~49 days, ignore larger logged times.
// Incase platform_get_ticks() wraps after ~49 days, ignore larger logged times.
ticks > connection.Player->LastPlaceSceneryTime
) {
if (!(group->CanPerformCommand(MISC_COMMAND_TOGGLE_SCENERY_CLUSTER))) {
@ -1889,7 +1891,7 @@ void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket
else if (commandCommand == GAME_COMMAND_DEMOLISH_RIDE) {
if (
ticks - connection.Player->LastDemolishRideTime < ACTION_COOLDOWN_TIME_DEMOLISH_RIDE &&
// Incase SDL_GetTicks() wraps after ~49 days, ignore larger logged times.
// Incase platform_get_ticks() wraps after ~49 days, ignore larger logged times.
ticks > connection.Player->LastDemolishRideTime
) {
Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE);
@ -1912,7 +1914,7 @@ void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket
}
connection.Player->LastAction = NetworkActions::FindCommand(commandCommand);
connection.Player->LastActionTime = SDL_GetTicks();
connection.Player->LastActionTime = platform_get_ticks();
connection.Player->AddMoneySpent(cost);
if (commandCommand == GAME_COMMAND_PLACE_SCENERY) {
@ -1963,7 +1965,7 @@ void Network::Client_Handle_PLAYERLIST(NetworkConnection& connection, NetworkPac
if (player) {
*player = tempplayer;
if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER) {
server_connection.Player = player;
server_connection->Player = player;
}
}
}
@ -1986,7 +1988,7 @@ void Network::Client_Handle_PING(NetworkConnection& connection, NetworkPacket& p
void Network::Server_Handle_PING(NetworkConnection& connection, NetworkPacket& packet)
{
sint32 ping = SDL_GetTicks() - connection.PingTime;
sint32 ping = platform_get_ticks() - connection.PingTime;
if (ping < 0) {
ping = 0;
}
@ -2081,7 +2083,7 @@ void Network::Client_Send_GAMEINFO()
log_verbose("requesting gameinfo");
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32)NETWORK_COMMAND_GAMEINFO;
server_connection.QueuePacket(std::move(packet));
server_connection->QueuePacket(std::move(packet));
}
static std::string json_stdstring_value(const json_t * string)
@ -2204,7 +2206,7 @@ void network_add_player_money_spent(uint32 index, money32 cost)
sint32 network_get_player_last_action(uint32 index, sint32 time)
{
if (time && SDL_TICKS_PASSED(SDL_GetTicks(), gNetwork.player_list[index]->LastActionTime + time)) {
if (time && platform_get_ticks() > gNetwork.player_list[index]->LastActionTime + time) {
return -999;
}
return gNetwork.player_list[index]->LastAction;
@ -2213,7 +2215,7 @@ sint32 network_get_player_last_action(uint32 index, sint32 time)
void network_set_player_last_action(uint32 index, sint32 command)
{
gNetwork.player_list[index]->LastAction = NetworkActions::FindCommand(command);
gNetwork.player_list[index]->LastActionTime = SDL_GetTicks();
gNetwork.player_list[index]->LastActionTime = platform_get_ticks();
}
rct_xyz16 network_get_player_last_action_coord(uint32 index)

View File

@ -198,7 +198,7 @@ private:
bool wsa_initialized = false;
ITcpSocket * listening_socket = nullptr;
uint16 listening_port = 0;
NetworkConnection server_connection;
NetworkConnection * server_connection = nullptr;
SOCKET_STATUS _lastConnectStatus = SOCKET_STATUS_CLOSED;
uint32 last_tick_sent_time = 0;
uint32 last_ping_sent_time = 0;

View File

@ -43,6 +43,7 @@ extern "C"
#include "../localisation/localisation.h"
#include "../management/news_item.h"
#include "../peep/peep.h"
#include "../platform/platform.h"
#include "../rct2.h"
#include "../util/util.h"
#include "../world/sprite.h"
@ -142,7 +143,7 @@ namespace Twitch
switch (_twitchState) {
case TWITCH_STATE_LEFT:
{
uint32 currentTime = SDL_GetTicks();
uint32 currentTime = platform_get_ticks();
uint32 timeSinceLastPulse = currentTime - _twitchLastPulseTick;
if (_twitchLastPulseTick == 0 || timeSinceLastPulse > PulseTime)
{
@ -153,7 +154,7 @@ namespace Twitch
}
case TWITCH_STATE_JOINED:
{
uint32 currentTime = SDL_GetTicks();
uint32 currentTime = platform_get_ticks();
uint32 timeSinceLastPulse = currentTime - _twitchLastPulseTick;
if (_twitchLastPulseTick == 0 || timeSinceLastPulse > PulseTime) {
_twitchLastPulseTick = currentTime;

View File

@ -15,6 +15,7 @@
#pragma endregion
#include <algorithm>
#include <chrono>
#include <memory>
#include <unordered_map>
#include <vector>
@ -28,7 +29,6 @@
#include "../core/Memory.hpp"
#include "../core/MemoryStream.h"
#include "../core/Path.hpp"
#include "../core/Stopwatch.hpp"
#include "../core/String.hpp"
#include "../PlatformEnvironment.h"
#include "../rct12/SawyerChunkReader.h"
@ -296,16 +296,17 @@ private:
Console::WriteLine("Scanning %lu objects...", _queryDirectoryResult.TotalFiles);
_numConflicts = 0;
auto stopwatch = Stopwatch();
stopwatch.Start();
auto startTime = std::chrono::high_resolution_clock::now();
const std::string &rct2Path = _env->GetDirectoryPath(DIRBASE::RCT2, DIRID::OBJECT);
const std::string &openrct2Path = _env->GetDirectoryPath(DIRBASE::USER, DIRID::OBJECT);
ScanDirectory(rct2Path);
ScanDirectory(openrct2Path);
stopwatch.Stop();
Console::WriteLine("Scanning complete in %.2f seconds.", stopwatch.GetElapsedMilliseconds() / 1000.0f);
auto endTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> duration = endTime - startTime;
Console::WriteLine("Scanning complete in %.2f seconds.", duration.count());
if (_numConflicts > 0)
{
Console::WriteLine("%d object conflicts found.", _numConflicts);

View File

@ -14,14 +14,13 @@
*****************************************************************************/
#pragma endregion
#include <SDL_platform.h>
#include "crash.h"
#ifdef USE_BREAKPAD
#include <memory>
#include <stdio.h>
#if defined(__WINDOWS__)
#if defined(_WIN32)
#include <breakpad/client/windows/handler/exception_handler.h>
#include <string>
#include <ShlObj.h>

View File

@ -188,6 +188,7 @@ void platform_get_cursor_position(sint32 *x, sint32 *y);
void platform_get_cursor_position_scaled(sint32 *x, sint32 *y);
void platform_set_cursor_position(sint32 x, sint32 y);
uint32 platform_get_ticks();
void platform_sleep(uint32 ms);
void platform_resolve_user_data_path();
void platform_resolve_openrct_data_path();
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize);

View File

@ -14,6 +14,8 @@
*****************************************************************************/
#pragma endregion
#include <stdlib.h>
#include <time.h>
#include "../audio/audio.h"
#include "../audio/AudioMixer.h"
#include "../config/Config.h"
@ -37,6 +39,14 @@
#include "../world/Climate.h"
#include "platform.h"
#ifdef __APPLE__
#include <mach/mach_time.h>
#include <AvailabilityMacros.h>
#ifndef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
#error Missing __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ define
#endif
#endif
typedef void(*update_palette_func)(const uint8*, sint32, sint32);
openrct2_cursor gCursorState;
@ -69,6 +79,10 @@ static float _gestureRadius;
static void platform_create_window();
#if defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200)
mach_timebase_info_data_t _mach_base_info = { 0 };
#endif
static sint32 resolution_sort_func(const void *pa, const void *pb)
{
const resolution_t *a = (resolution_t*)pa;
@ -761,7 +775,23 @@ void platform_set_cursor_position(sint32 x, sint32 y)
uint32 platform_get_ticks()
{
return SDL_GetTicks();
#ifdef _WIN32
return GetTickCount();
#elif defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200)
return (uint32)(((mach_absolute_time() * _mach_base_info.numer) / _mach_base_info.denom) / 1000000);
#else
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
log_fatal("clock_gettime failed");
exit(-1);
}
return (uint32)(ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
#endif
}
void platform_sleep(uint32 ms)
{
SDL_Delay(ms);
}
uint8 platform_get_currency_value(const char *currCode) {
@ -781,4 +811,12 @@ uint8 platform_get_currency_value(const char *currCode) {
void core_init()
{
bitcount_init();
#if defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200)
kern_return_t ret = mach_timebase_info(&_mach_base_info);
if (ret != 0) {
log_fatal("Unable to get mach_timebase_info.");
exit(-1);
}
#endif
}

View File

@ -380,7 +380,7 @@ sint32 check_file_paths()
void rct2_update()
{
sint32 tickCount = SDL_GetTicks();
sint32 tickCount = platform_get_ticks();
gTicksSinceLastUpdate = min(tickCount - gLastTickCount, 500);
gLastTickCount = tickCount;
if (game_is_not_paused()) {

View File

@ -14,6 +14,8 @@
*****************************************************************************/
#pragma endregion
#include <stdio.h>
#include "../common.h"
#if defined(__WINDOWS__)
@ -179,17 +181,20 @@ bool rct2_interop_setup_segment()
utf8 segmentDataPath[MAX_PATH];
rct2_interop_get_segment_data_path(segmentDataPath, sizeof(segmentDataPath));
SDL_RWops * rw = SDL_RWFromFile(segmentDataPath, "rb");
if (rw == NULL)
// Warning: for Windows this will fail if given a non-ASCII path,
// but given this code is temporary - its not worth resolving.
FILE * file = fopen(segmentDataPath, "rb");
if (file == NULL)
{
log_error("failed to load file");
return false;
}
if (SDL_RWread(rw, segments, len, 1) != 1) {
if (fread(segments, len, 1, file) != 1) {
log_error("Unable to read chunk header!");
return false;
}
SDL_RWclose(rw);
fclose(file);
#endif // defined(USE_MMAP) && defined(__WINDOWS__)
#if !defined(NO_RCT2) && defined(USE_MMAP)

View File

@ -362,7 +362,7 @@ void scenario_autosave_check()
if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE) return;
// Milliseconds since last save
uint32 timeSinceSave = SDL_GetTicks() - gLastAutoSaveUpdate;
uint32 timeSinceSave = platform_get_ticks() - gLastAutoSaveUpdate;
bool shouldSave = false;
switch (gConfigGeneral.autosave_frequency) {

View File

@ -17,7 +17,6 @@
#ifndef _SAWYERCODING_H_
#define _SAWYERCODING_H_
#include <SDL.h>
#include "../common.h"
#pragma pack(push, 1)

View File

@ -14,10 +14,7 @@
*****************************************************************************/
#pragma endregion
// Include common.h before SDL, otherwise M_PI gets redefined
#include "../common.h"
#include <SDL.h>
#include "../core/Guard.hpp"
#include "../localisation/localisation.h"
#include "../platform/platform.h"

View File

@ -14,20 +14,25 @@
*****************************************************************************/
#pragma endregion
#include <mutex>
#include "../config/Config.h"
#include "../interface/colour.h"
#include "../interface/themes.h"
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../localisation/localisation.h"
#include "../network/http.h"
#include "../network/network.h"
#include "../network/ServerList.h"
#include "../sprites.h"
#include "../util/util.h"
#include "../windows/dropdown.h"
#include "../windows/tooltip.h"
#include "error.h"
extern "C"
{
#include "../interface/colour.h"
#include "../interface/themes.h"
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../localisation/localisation.h"
#include "../network/http.h"
#include "../sprites.h"
#include "../util/util.h"
#include "../windows/dropdown.h"
#include "../windows/tooltip.h"
#include "error.h"
}
#define WWIDTH_MIN 500
#define WHEIGHT_MIN 300
@ -38,7 +43,7 @@
static char _playerName[32 + 1];
static server_entry *_serverEntries = NULL;
static sint32 _numServerEntries = 0;
static SDL_mutex *_mutex = 0;
static std::mutex _mutex;
static uint32 _numPlayersOnline = 0;
enum {
@ -119,6 +124,7 @@ enum {
};
static sint32 _hoverButtonIndex = -1;
static char * _version = NULL;
static void server_list_get_item_button(sint32 buttonIndex, sint32 x, sint32 y, sint32 width, sint32 *outX, sint32 *outY);
static void server_list_load_server_entries();
@ -134,63 +140,58 @@ static void fetch_servers();
static void fetch_servers_callback(http_response_t* response);
#endif
void window_server_list_open()
extern "C"
{
rct_window* window;
// Check if window is already open
window = window_bring_to_front_by_class(WC_SERVER_LIST);
if (window != NULL)
return;
if (_mutex == 0) {
_mutex = SDL_CreateMutex();
void window_server_list_open()
{
rct_window* window;
// Check if window is already open
window = window_bring_to_front_by_class(WC_SERVER_LIST);
if (window != NULL)
return;
window = window_create_centred(WWIDTH_MIN, WHEIGHT_MIN, &window_server_list_events, WC_SERVER_LIST, WF_10 | WF_RESIZABLE);
window_server_list_widgets[WIDX_PLAYER_NAME_INPUT].string = _playerName;
window->widgets = window_server_list_widgets;
window->enabled_widgets = (
(1 << WIDX_CLOSE) |
(1 << WIDX_PLAYER_NAME_INPUT) |
(1 << WIDX_FETCH_SERVERS) |
(1 << WIDX_ADD_SERVER) |
(1 << WIDX_START_SERVER)
);
window_init_scroll_widgets(window);
window->no_list_items = 0;
window->selected_list_item = -1;
window->frame_no = 0;
window->min_width = 320;
window->min_height = 90;
window->max_width = window->min_width;
window->max_height = window->min_height;
window->page = 0;
window->list_information_type = 0;
window->colours[0] = COLOUR_GREY;
window->colours[1] = COLOUR_BORDEAUX_RED;
window->colours[2] = COLOUR_BORDEAUX_RED;
window_set_resize(window, WWIDTH_MIN, WHEIGHT_MIN, WWIDTH_MAX, WHEIGHT_MAX);
safe_strcpy(_playerName, gConfigNetwork.player_name, sizeof(_playerName));
server_list_load_server_entries();
window->no_list_items = _numServerEntries;
fetch_servers();
}
window = window_create_centred(WWIDTH_MIN, WHEIGHT_MIN, &window_server_list_events, WC_SERVER_LIST, WF_10 | WF_RESIZABLE);
window_server_list_widgets[WIDX_PLAYER_NAME_INPUT].string = _playerName;
window->widgets = window_server_list_widgets;
window->enabled_widgets = (
(1 << WIDX_CLOSE) |
(1 << WIDX_PLAYER_NAME_INPUT) |
(1 << WIDX_FETCH_SERVERS) |
(1 << WIDX_ADD_SERVER) |
(1 << WIDX_START_SERVER)
);
window_init_scroll_widgets(window);
window->no_list_items = 0;
window->selected_list_item = -1;
window->frame_no = 0;
window->min_width = 320;
window->min_height = 90;
window->max_width = window->min_width;
window->max_height = window->min_height;
window->page = 0;
window->list_information_type = 0;
window->colours[0] = COLOUR_GREY;
window->colours[1] = COLOUR_BORDEAUX_RED;
window->colours[2] = COLOUR_BORDEAUX_RED;
window_set_resize(window, WWIDTH_MIN, WHEIGHT_MIN, WWIDTH_MAX, WHEIGHT_MAX);
safe_strcpy(_playerName, gConfigNetwork.player_name, sizeof(_playerName));
server_list_load_server_entries();
window->no_list_items = _numServerEntries;
fetch_servers();
}
static void window_server_list_close(rct_window *w)
{
std::lock_guard<std::mutex> guard(_mutex);
dispose_server_entry_list();
if (_mutex) {
SDL_LockMutex(_mutex);
SDL_DestroyMutex(_mutex);
_mutex = 0;
}
}
static void window_server_list_mouseup(rct_window *w, rct_widgetindex widgetIndex)
@ -249,8 +250,11 @@ static void window_server_list_dropdown(rct_window *w, rct_widgetindex widgetInd
join_server(serverAddress);
break;
case DDIDX_FAVOURITE:
_serverEntries[serverIndex].favourite = !_serverEntries[serverIndex].favourite;
server_list_save_server_entries();
{
std::lock_guard<std::mutex> guard(_mutex);
_serverEntries[serverIndex].favourite = !_serverEntries[serverIndex].favourite;
server_list_save_server_entries();
}
break;
}
}
@ -288,8 +292,6 @@ static void window_server_list_scroll_mousedown(rct_window *w, sint32 scrollInde
window_dropdown_show_text(ddx, ddy, 0, COLOUR_GREY, 0, 2);
}
char *gVersion = NULL;
static void window_server_list_scroll_mouseover(rct_window *w, sint32 scrollIndex, sint32 x, sint32 y)
{
// Item
@ -355,9 +357,12 @@ static void window_server_list_textinput(rct_window *w, rct_widgetindex widgetIn
break;
case WIDX_ADD_SERVER:
add_server_entry(text);
sort_servers();
server_list_save_server_entries();
{
std::lock_guard<std::mutex> guard(_mutex);
add_server_entry(text);
sort_servers();
server_list_save_server_entries();
}
window_invalidate(w);
break;
}
@ -367,7 +372,7 @@ static void window_server_list_invalidate(rct_window *w)
{
colour_scheme_update(w);
set_format_arg(0, char *, gVersion);
set_format_arg(0, char *, _version);
window_server_list_widgets[WIDX_BACKGROUND].right = w->width - 1;
window_server_list_widgets[WIDX_BACKGROUND].bottom = w->height - 1;
window_server_list_widgets[WIDX_TITLE].right = w->width - 2;
@ -399,7 +404,7 @@ static void window_server_list_paint(rct_window *w, rct_drawpixelinfo *dpi)
window_draw_widgets(w, dpi);
gfx_draw_string_left(dpi, STR_PLAYER_NAME, NULL, COLOUR_WHITE, w->x + 6, w->y + w->widgets[WIDX_PLAYER_NAME_INPUT].top);
char *version = NETWORK_STREAM_ID;
const char * version = NETWORK_STREAM_ID;
gfx_draw_string_left(dpi, STR_NETWORK_VERSION, (void*)&version, COLOUR_WHITE, w->x + 324, w->y + w->widgets[WIDX_START_SERVER].top);
gfx_draw_string_left(dpi, STR_X_PLAYERS_ONLINE, (void*)&_numPlayersOnline, COLOUR_WHITE, w->x + 8, w->y + w->height - 15);
@ -407,6 +412,8 @@ static void window_server_list_paint(rct_window *w, rct_drawpixelinfo *dpi)
static void window_server_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex)
{
std::lock_guard<std::mutex> guard(_mutex);
uint8 paletteIndex = ColourMapA[w->colours[1]].mid_light;
gfx_clear(dpi, paletteIndex);
@ -424,7 +431,7 @@ static void window_server_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi
// Draw hover highlight
if (highlighted) {
gfx_filter_rect(dpi, 0, y, width, y + ITEM_HEIGHT, PALETTE_DARKEN_1);
gVersion = serverDetails->version;
_version = serverDetails->version;
w->widgets[WIDX_LIST].tooltip = STR_NETWORK_VERSION_TIP;
}
@ -484,26 +491,19 @@ static void server_list_get_item_button(sint32 buttonIndex, sint32 x, sint32 y,
static void server_list_load_server_entries()
{
SDL_LockMutex(_mutex);
uint32 numEntries;
server_entry * entries;
if (server_list_read(&numEntries, &entries)) {
std::lock_guard<std::mutex> guard(_mutex);
dispose_server_entry_list();
_numServerEntries = numEntries;
_serverEntries = entries;
sort_servers();
}
SDL_UnlockMutex(_mutex);
}
static void server_list_save_server_entries()
{
SDL_LockMutex(_mutex);
// Get total number of favourite servers
sint32 count = 0;
for (sint32 i = 0; i < _numServerEntries; i++) {
@ -514,7 +514,7 @@ static void server_list_save_server_entries()
}
// Create temporary list of just favourite servers
server_entry * entries = calloc(count, sizeof(server_entry));
server_entry * entries = (server_entry *)calloc(count, sizeof(server_entry));
sint32 eindex = 0;
for (sint32 i = 0; i < _numServerEntries; i++) {
server_entry *serverInfo = &_serverEntries[i];
@ -528,13 +528,10 @@ static void server_list_save_server_entries()
// Free temporary list
free(entries);
SDL_UnlockMutex(_mutex);
}
static void dispose_server_entry_list()
{
SDL_LockMutex(_mutex);
if (_serverEntries != NULL) {
for (sint32 i = 0; i < _numServerEntries; i++) {
dispose_server_entry(&_serverEntries[i]);
@ -543,7 +540,6 @@ static void dispose_server_entry_list()
_serverEntries = NULL;
}
_numServerEntries = 0;
SDL_UnlockMutex(_mutex);
}
static void dispose_server_entry(server_entry *serverInfo)
@ -556,19 +552,17 @@ static void dispose_server_entry(server_entry *serverInfo)
static server_entry* add_server_entry(char *address)
{
SDL_LockMutex(_mutex);
for (sint32 i = 0; i < _numServerEntries; i++) {
if (strcmp(_serverEntries[i].address, address) == 0) {
SDL_UnlockMutex(_mutex);
return &_serverEntries[i];
}
}
_numServerEntries++;
if (_serverEntries == NULL) {
_serverEntries = malloc(_numServerEntries * sizeof(server_entry));
_serverEntries = (server_entry *)malloc(_numServerEntries * sizeof(server_entry));
} else {
_serverEntries = realloc(_serverEntries, _numServerEntries * sizeof(server_entry));
_serverEntries = (server_entry *)realloc(_serverEntries, _numServerEntries * sizeof(server_entry));
}
sint32 index = _numServerEntries - 1;
@ -581,21 +575,18 @@ static server_entry* add_server_entry(char *address)
newserver->favourite = false;
newserver->players = 0;
newserver->maxplayers = 0;
SDL_UnlockMutex(_mutex);
return newserver;
}
static void remove_server_entry(sint32 index)
{
SDL_LockMutex(_mutex);
if (_numServerEntries > index) {
sint32 serversToMove = _numServerEntries - index - 1;
memmove(&_serverEntries[index], &_serverEntries[index + 1], serversToMove * sizeof(server_entry));
_numServerEntries--;
_serverEntries = realloc(_serverEntries, _numServerEntries * sizeof(server_entry));
_serverEntries = (server_entry *)realloc(_serverEntries, _numServerEntries * sizeof(server_entry));
}
SDL_UnlockMutex(_mutex);
}
static sint32 server_compare(const void *a, const void *b)
@ -637,7 +628,7 @@ static void sort_servers()
static char *substr(char *start, sint32 length)
{
char *result = malloc(length + 1);
char *result = (char *)malloc(length + 1);
memcpy(result, start, length);
result[length] = 0;
return result;
@ -692,15 +683,16 @@ static void fetch_servers()
masterServerUrl = gConfigNetwork.master_server_url;
}
SDL_LockMutex(_mutex);
for (sint32 i = 0; i < _numServerEntries; i++) {
if (!_serverEntries[i].favourite) {
remove_server_entry(i);
i = 0;
{
std::lock_guard<std::mutex> guard(_mutex);
for (sint32 i = 0; i < _numServerEntries; i++) {
if (!_serverEntries[i].favourite) {
remove_server_entry(i);
i = 0;
}
}
sort_servers();
}
sort_servers();
SDL_UnlockMutex(_mutex);
http_request_t request = { 0 };
request.url = masterServerUrl;
@ -767,18 +759,19 @@ static void fetch_servers_callback(http_response_t* response)
char address[256];
snprintf(address, sizeof(address), "%s:%d", json_string_value(addressIp), (sint32)json_integer_value(port));
SDL_LockMutex(_mutex);
server_entry* newserver = add_server_entry(address);
SafeFree(newserver->name);
SafeFree(newserver->description);
SafeFree(newserver->version);
newserver->name = _strdup(json_string_value(name));
newserver->requiresPassword = json_is_true(requiresPassword);
newserver->description = _strdup(description == NULL ? "" : json_string_value(description));
newserver->version = _strdup(json_string_value(version));
newserver->players = (uint8)json_integer_value(players);
newserver->maxplayers = (uint8)json_integer_value(maxPlayers);
SDL_UnlockMutex(_mutex);
{
std::lock_guard<std::mutex> guard(_mutex);
server_entry* newserver = add_server_entry(address);
SafeFree(newserver->name);
SafeFree(newserver->description);
SafeFree(newserver->version);
newserver->name = _strdup(json_string_value(name));
newserver->requiresPassword = json_is_true(requiresPassword);
newserver->description = _strdup(description == NULL ? "" : json_string_value(description));
newserver->version = _strdup(json_string_value(version));
newserver->players = (uint8)json_integer_value(players);
newserver->maxplayers = (uint8)json_integer_value(maxPlayers);
}
}
http_request_dispose(response);

View File

@ -22,6 +22,7 @@
#include "../game.h"
#include "../localisation/string_ids.h"
#include "../object.h"
#include "../platform/platform.h"
#include "../util/util.h"
#include "../windows/error.h"
#include "map.h"
@ -142,7 +143,7 @@ void mapgen_generate(mapgen_settings *settings)
sint32 x, y, mapSize, floorTexture, wallTexture, waterLevel;
rct_map_element *mapElement;
util_srand((sint32)SDL_GetTicks());
util_srand((sint32)platform_get_ticks());
mapSize = settings->mapSize;
floorTexture = settings->floor;