Remove YBaseLib dependency

This commit is contained in:
Connor McLaughlin 2020-01-10 13:31:12 +10:00
parent 1c2c4c8489
commit 71c1e243fe
112 changed files with 6888 additions and 522 deletions

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "dep/YBaseLib"]
path = dep/YBaseLib
url = https://github.com/stenzek/YBaseLib.git

View file

@ -13,90 +13,3 @@ if(${CPU_ARCH} STREQUAL "aarch64")
add_subdirectory(vixl)
endif()
###################### YBaseLib ############################
set(YBASELIB_SRC_BASE ${CMAKE_SOURCE_DIR}/dep/YBaseLib/Source)
set(YBASELIB_INCLUDES ${CMAKE_SOURCE_DIR}/dep/YBaseLib/Include)
set(YBASELIB_SRC_FILES
${YBASELIB_SRC_BASE}/YBaseLib/Android
${YBASELIB_SRC_BASE}/YBaseLib/Android/AndroidBarrier.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Android/AndroidConditionVariable.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Android/AndroidEvent.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Android/AndroidFileSystem.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Android/AndroidPlatform.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Android/AndroidReadWriteLock.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Android/AndroidThread.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Assert.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Atomic.cpp
${YBASELIB_SRC_BASE}/YBaseLib/BinaryBlob.cpp
${YBASELIB_SRC_BASE}/YBaseLib/BinaryReadBuffer.cpp
${YBASELIB_SRC_BASE}/YBaseLib/BinaryReader.cpp
${YBASELIB_SRC_BASE}/YBaseLib/BinaryWriteBuffer.cpp
${YBASELIB_SRC_BASE}/YBaseLib/BinaryWriter.cpp
${YBASELIB_SRC_BASE}/YBaseLib/ByteStream.cpp
${YBASELIB_SRC_BASE}/YBaseLib/CallbackQueue.cpp
${YBASELIB_SRC_BASE}/YBaseLib/CircularBuffer.cpp
${YBASELIB_SRC_BASE}/YBaseLib/CPUID.cpp
${YBASELIB_SRC_BASE}/YBaseLib/CRC32.cpp
${YBASELIB_SRC_BASE}/YBaseLib/CString.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Endian.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Error.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Exception.cpp
${YBASELIB_SRC_BASE}/YBaseLib/FileSystem.cpp
${YBASELIB_SRC_BASE}/YBaseLib/HashTrait.cpp
${YBASELIB_SRC_BASE}/YBaseLib/HTML5
${YBASELIB_SRC_BASE}/YBaseLib/HTML5/HTML5Barrier.cpp
${YBASELIB_SRC_BASE}/YBaseLib/HTML5/HTML5ConditionVariable.cpp
${YBASELIB_SRC_BASE}/YBaseLib/HTML5/HTML5FileSystem.cpp
${YBASELIB_SRC_BASE}/YBaseLib/HTML5/HTML5Platform.cpp
${YBASELIB_SRC_BASE}/YBaseLib/HTML5/HTML5ReadWriteLock.cpp
${YBASELIB_SRC_BASE}/YBaseLib/HTML5/HTML5Thread.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Log.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Math.cpp
${YBASELIB_SRC_BASE}/YBaseLib/MD5Digest.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Memory.cpp
${YBASELIB_SRC_BASE}/YBaseLib/NameTable.cpp
${YBASELIB_SRC_BASE}/YBaseLib/NumericLimits.cpp
${YBASELIB_SRC_BASE}/YBaseLib/POSIX
${YBASELIB_SRC_BASE}/YBaseLib/POSIX/POSIXConditionVariable.cpp
${YBASELIB_SRC_BASE}/YBaseLib/POSIX/POSIXFileSystem.cpp
${YBASELIB_SRC_BASE}/YBaseLib/POSIX/POSIXPlatform.cpp
${YBASELIB_SRC_BASE}/YBaseLib/POSIX/POSIXReadWriteLock.cpp
${YBASELIB_SRC_BASE}/YBaseLib/POSIX/POSIXSubprocess.cpp
${YBASELIB_SRC_BASE}/YBaseLib/POSIX/POSIXThread.cpp
${YBASELIB_SRC_BASE}/YBaseLib/ProgressCallbacks.cpp
${YBASELIB_SRC_BASE}/YBaseLib/ReferenceCounted.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Sockets
${YBASELIB_SRC_BASE}/YBaseLib/Sockets/Generic
${YBASELIB_SRC_BASE}/YBaseLib/Sockets/Generic/BufferedStreamSocket.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Sockets/Generic/ListenSocket.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Sockets/Generic/SocketMultiplexer.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Sockets/Generic/StreamSocket.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Sockets/SocketAddress.cpp
${YBASELIB_SRC_BASE}/YBaseLib/StringConverter.cpp
${YBASELIB_SRC_BASE}/YBaseLib/String.cpp
${YBASELIB_SRC_BASE}/YBaseLib/StringParser.cpp
${YBASELIB_SRC_BASE}/YBaseLib/TaskQueue.cpp
${YBASELIB_SRC_BASE}/YBaseLib/TextReader.cpp
${YBASELIB_SRC_BASE}/YBaseLib/TextWriter.cpp
${YBASELIB_SRC_BASE}/YBaseLib/ThreadPool.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Timer.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Timestamp.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Windows
${YBASELIB_SRC_BASE}/YBaseLib/Windows/WindowsBarrier.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Windows/WindowsConditionVariable.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Windows/WindowsFileSystem.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Windows/WindowsPlatform.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Windows/WindowsReadWriteLock.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Windows/WindowsSubprocess.cpp
${YBASELIB_SRC_BASE}/YBaseLib/Windows/WindowsThread.cpp
)
add_library(YBaseLib STATIC ${YBASELIB_SRC_FILES})
target_include_directories(YBaseLib PRIVATE ${YBASELIB_INCLUDES} ${YBASELIB_SRC_BASE})
target_include_directories(YBaseLib PUBLIC ${YBASELIB_INCLUDES})
target_link_libraries(YBaseLib PUBLIC Threads::Threads)
if(ANDROID)
target_link_libraries(YBaseLib PRIVATE log)
endif()

@ -1 +0,0 @@
Subproject commit 7004a8b562373915bb56ea73171c4f3b43fafdea

View file

@ -15,8 +15,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "src\core\core.vcxpr
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "duckstation", "src\duckstation\duckstation.vcxproj", "{DAA8F93D-9C17-4DE2-BD0B-57891E0FF0D9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YBaseLib", "dep\YBaseLib\Source\YBaseLib.vcxproj", "{B56CE698-7300-4FA5-9609-942F1D05C5A2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stb", "dep\stb\stb.vcxproj", "{ED601289-AC1A-46B8-A8ED-17DB9EB73423}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcue", "dep\libcue\libcue.vcxproj", "{6A4208ED-E3DC-41E1-81CD-F61025FC285A}"
@ -121,22 +119,6 @@ Global
{DAA8F93D-9C17-4DE2-BD0B-57891E0FF0D9}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64
{DAA8F93D-9C17-4DE2-BD0B-57891E0FF0D9}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32
{DAA8F93D-9C17-4DE2-BD0B-57891E0FF0D9}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Debug|x64.ActiveCfg = Debug|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Debug|x64.Build.0 = Debug|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Debug|x86.ActiveCfg = Debug|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Debug|x86.Build.0 = Debug|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.DebugFast|x64.ActiveCfg = DebugFast|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.DebugFast|x64.Build.0 = DebugFast|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.DebugFast|x86.ActiveCfg = DebugFast|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.DebugFast|x86.Build.0 = DebugFast|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Release|x64.ActiveCfg = Release|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Release|x64.Build.0 = Release|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Release|x86.ActiveCfg = Release|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.Release|x86.Build.0 = Release|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.ReleaseLTCG|x64.ActiveCfg = ReleaseLTCG|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32
{B56CE698-7300-4FA5-9609-942F1D05C5A2}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32
{ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Debug|x64.ActiveCfg = Debug|x64
{ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Debug|x64.Build.0 = Debug|x64
{ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Debug|x86.ActiveCfg = Debug|Win32
@ -236,7 +218,6 @@ Global
GlobalSection(NestedProjects) = preSolution
{43540154-9E1E-409C-834F-B84BE5621388} = {BA490C0E-497D-4634-A21E-E65012006385}
{BB08260F-6FBC-46AF-8924-090EE71360C6} = {BA490C0E-497D-4634-A21E-E65012006385}
{B56CE698-7300-4FA5-9609-942F1D05C5A2} = {BA490C0E-497D-4634-A21E-E65012006385}
{ED601289-AC1A-46B8-A8ED-17DB9EB73423} = {BA490C0E-497D-4634-A21E-E65012006385}
{6A4208ED-E3DC-41E1-81CD-F61025FC285A} = {BA490C0E-497D-4634-A21E-E65012006385}
{ACE32F47-2960-4FB3-9F77-2C375625BF61} = {BA490C0E-497D-4634-A21E-E65012006385}

View file

@ -1,7 +1,12 @@
add_library(common
align.h
assert.cpp
assert.h
audio_stream.cpp
audio_stream.h
bitfield.h
byte_stream.cpp
byte_stream.h
cd_image.cpp
cd_image.h
cd_image_bin.cpp
@ -10,27 +15,44 @@ add_library(common
cd_subchannel_replacement.h
cd_xa.cpp
cd_xa.h
cpu_detect.h
fifo_queue.h
file_system.cpp
file_system.h
gl/program.cpp
gl/program.h
gl/stream_buffer.cpp
gl/stream_buffer.h
gl/texture.cpp
gl/texture.h
heap_array.h
iso_reader.cpp
iso_reader.h
jit_code_buffer.cpp
jit_code_buffer.h
log.cpp
log.h
md5_digest.cpp
md5_digest.h
null_audio_stream.cpp
null_audio_stream.h
rectangle.h
state_wrapper.cpp
state_wrapper.h
string.cpp
string.h
string_util.cpp
string_util.h
timer.cpp
timer.h
timestamp.cpp
timestamp.h
types.h
)
target_include_directories(common PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_include_directories(common PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_link_libraries(common PRIVATE YBaseLib glad libcue Threads::Threads)
target_link_libraries(common PRIVATE glad libcue Threads::Threads)
if(WIN32)
target_sources(common PRIVATE
@ -42,6 +64,11 @@ if(WIN32)
d3d11/stream_buffer.h
d3d11/texture.cpp
d3d11/texture.h
windows_headers.h
)
target_link_libraries(common PRIVATE d3dcompiler.lib)
endif()
if(ANDROID)
target_link_libraries(common PRIVATE log)
endif()

39
src/common/align.h Normal file
View file

@ -0,0 +1,39 @@
#pragma once
namespace Common {
template<typename T>
bool IsAligned(T value, unsigned int alignment)
{
return (value % static_cast<T>(alignment)) == 0;
}
template<typename T>
T AlignUp(T value, unsigned int alignment)
{
return (value + static_cast<T>(alignment - 1)) / static_cast<T>(alignment) * static_cast<T>(alignment);
}
template<typename T>
T AlignDown(T value, unsigned int alignment)
{
return value / static_cast<T>(alignment) * static_cast<T>(alignment);
}
template<typename T>
bool IsAlignedPow2(T value, unsigned int alignment)
{
return (value & static_cast<T>(alignment - 1)) == 0;
}
template<typename T>
T AlignUpPow2(T value, unsigned int alignment)
{
return (value + static_cast<T>(alignment - 1)) & static_cast<T>(~static_cast<T>(alignment - 1));
}
template<typename T>
T AlignDownPow2(T value, unsigned int alignment)
{
return value & static_cast<T>(~static_cast<T>(alignment - 1));
}
template<typename T>
bool IsPow2(T value)
{
return (value & (value - 1)) == 0;
}
} // namespace Common

135
src/common/assert.cpp Normal file
View file

@ -0,0 +1,135 @@
#include "assert.h"
#include <cstdio>
#include <cstdlib>
#include <mutex>
#ifdef Y_PLATFORM_WINDOWS
#define WIN32_LEAN_AND_MEAN 1
#include <intrin.h>
#include <tlhelp32.h>
#include <windows.h>
#endif
static std::mutex s_AssertFailedMutex;
static inline void FreezeThreads(void** ppHandle)
{
#ifdef Y_PLATFORM_WINDOWS
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
THREADENTRY32 threadEntry;
if (Thread32First(hSnapshot, &threadEntry))
{
do
{
if (threadEntry.th32ThreadID == GetCurrentThreadId())
continue;
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, threadEntry.th32ThreadID);
if (hThread != NULL)
{
SuspendThread(hThread);
CloseHandle(hThread);
}
} while (Thread32Next(hSnapshot, &threadEntry));
}
}
*ppHandle = (void*)hSnapshot;
#else
*ppHandle = nullptr;
#endif
}
static inline void ResumeThreads(void* pHandle)
{
#ifdef Y_PLATFORM_WINDOWS
HANDLE hSnapshot = (HANDLE)pHandle;
if (pHandle != INVALID_HANDLE_VALUE)
{
THREADENTRY32 threadEntry;
if (Thread32First(hSnapshot, &threadEntry))
{
do
{
if (threadEntry.th32ThreadID == GetCurrentThreadId())
continue;
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, threadEntry.th32ThreadID);
if (hThread != NULL)
{
ResumeThread(hThread);
CloseHandle(hThread);
}
} while (Thread32Next(hSnapshot, &threadEntry));
}
CloseHandle(hSnapshot);
}
#else
#endif
}
void Y_OnAssertFailed(const char* szMessage, const char* szFunction, const char* szFile, unsigned uLine)
{
std::lock_guard<std::mutex> guard(s_AssertFailedMutex);
void* pHandle;
FreezeThreads(&pHandle);
char szMsg[512];
std::snprintf(szMsg, sizeof(szMsg), "%s in function %s (%s:%u)", szMessage, szFunction, szFile, uLine);
#ifdef Y_PLATFORM_WINDOWS
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), szMsg, Y_strlen(szMsg), NULL, NULL);
OutputDebugStringA(szMsg);
Y_strncat(szMsg, sizeof(szMsg),
"\n\nPress Abort to exit, Retry to break to debugger, or Ignore to attempt to continue.");
int result = MessageBoxA(NULL, szMsg, NULL, MB_ABORTRETRYIGNORE | MB_ICONERROR);
if (result == IDRETRY)
__debugbreak();
else if (result != IDIGNORE)
TerminateProcess(GetCurrentProcess(), 0xBAADC0DE);
#else
fputs(szMsg, stderr);
fputs("\nAborting application.\n", stderr);
fflush(stderr);
abort();
#endif
ResumeThreads(pHandle);
}
void Y_OnPanicReached(const char* szMessage, const char* szFunction, const char* szFile, unsigned uLine)
{
std::lock_guard<std::mutex> guard(s_AssertFailedMutex);
void* pHandle;
FreezeThreads(&pHandle);
char szMsg[512];
std::snprintf(szMsg, sizeof(szMsg), "%s in function %s (%s:%u)", szMessage, szFunction, szFile, uLine);
#ifdef Y_PLATFORM_WINDOWS
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), szMsg, Y_strlen(szMsg), NULL, NULL);
OutputDebugStringA(szMsg);
Y_strncat(szMsg, sizeof(szMsg),
"\n\nDo you want to attempt to break into a debugger? Pressing Cancel will abort the application.");
int result = MessageBoxA(NULL, szMsg, NULL, MB_OKCANCEL | MB_ICONERROR);
if (result == IDOK)
__debugbreak();
TerminateProcess(GetCurrentProcess(), 0xBAADC0DE);
#else
fputs(szMsg, stderr);
fputs("\nAborting application.\n", stderr);
fflush(stderr);
abort();
#endif
ResumeThreads(pHandle);
}

48
src/common/assert.h Normal file
View file

@ -0,0 +1,48 @@
#pragma once
void Y_OnAssertFailed(const char* szMessage, const char* szFunction, const char* szFile, unsigned uLine);
void Y_OnPanicReached(const char* szMessage, const char* szFunction, const char* szFile, unsigned uLine);
#define Assert(expr) \
if (!(expr)) \
{ \
Y_OnAssertFailed("Assertion failed: '" #expr "'", __FUNCTION__, __FILE__, __LINE__); \
}
#define AssertMsg(expr, msg) \
if (!(expr)) \
{ \
Y_OnAssertFailed("Assertion failed: '" msg "'", __FUNCTION__, __FILE__, __LINE__); \
}
#if Y_BUILD_CONFIG_DEBUG
#define DebugAssert(expr) \
if (!(expr)) \
{ \
Y_OnAssertFailed("Debug assertion failed: '" #expr "'", __FUNCTION__, __FILE__, __LINE__); \
}
#define DebugAssertMsg(expr, msg) \
if (!(expr)) \
{ \
Y_OnAssertFailed("Debug assertion failed: '" msg "'", __FUNCTION__, __FILE__, __LINE__); \
}
#define DebugUnreachableCode() Y_OnPanicReached("Unreachable code reached", __FUNCTION__, __FILE__, __LINE__)
#else
#define DebugAssert(expr)
#define DebugAssertMsg(expr, msg)
#define DebugUnreachableCode()
#endif
// Panics the application, displaying an error message.
#define Panic(Message) Y_OnPanicReached("Panic triggered: '" Message "'", __FUNCTION__, __FILE__, __LINE__)
// Kills the application, indicating a pure function call that should not have happened.
#define PureCall() Y_OnPanicReached("PureCall encountered", __FUNCTION__, __FILE__, __LINE__)
// Kills the application, indicating that code that was never supposed to be reached has been executed.
#define UnreachableCode() Y_OnPanicReached("Unreachable code reached", __FUNCTION__, __FILE__, __LINE__)
// Helper for switch cases.
#define DefaultCaseIsUnreachable() \
default: \
UnreachableCode(); \
break;

View file

@ -1,5 +1,7 @@
#include "audio_stream.h"
#include "YBaseLib/Assert.h"
#include "assert.h"
#include <algorithm>
#include <cstring>
AudioStream::AudioStream() = default;

1325
src/common/byte_stream.cpp Normal file

File diff suppressed because it is too large Load diff

226
src/common/byte_stream.h Normal file
View file

@ -0,0 +1,226 @@
#pragma once
#include "types.h"
#include <memory>
// base byte stream creation functions
enum BYTESTREAM_OPEN_MODE
{
BYTESTREAM_OPEN_READ = 1, // open stream for writing
BYTESTREAM_OPEN_WRITE = 2, // open stream for writing
BYTESTREAM_OPEN_APPEND = 4, // seek to the end
BYTESTREAM_OPEN_TRUNCATE = 8, // truncate the file, seek to start
BYTESTREAM_OPEN_CREATE = 16, // if the file does not exist, create it
BYTESTREAM_OPEN_CREATE_PATH = 32, // if the file parent directories don't exist, create them
BYTESTREAM_OPEN_ATOMIC_UPDATE = 64, //
BYTESTREAM_OPEN_SEEKABLE = 128,
BYTESTREAM_OPEN_STREAMED = 256,
};
// interface class used by readers, writers, etc.
class ByteStream
{
public:
virtual ~ByteStream() {}
// reads a single byte from the stream.
virtual bool ReadByte(u8* pDestByte) = 0;
// read bytes from this stream. returns the number of bytes read, if this isn't equal to the requested size, an error
// or EOF occurred.
virtual u32 Read(void* pDestination, u32 ByteCount) = 0;
// read bytes from this stream, optionally returning the number of bytes read.
virtual bool Read2(void* pDestination, u32 ByteCount, u32* pNumberOfBytesRead = nullptr) = 0;
// writes a single byte to the stream.
virtual bool WriteByte(u8 SourceByte) = 0;
// write bytes to this stream, returns the number of bytes written. if this isn't equal to the requested size, a
// buffer overflow, or write error occurred.
virtual u32 Write(const void* pSource, u32 ByteCount) = 0;
// write bytes to this stream, optionally returning the number of bytes written.
virtual bool Write2(const void* pSource, u32 ByteCount, u32* pNumberOfBytesWritten = nullptr) = 0;
// seeks to the specified position in the stream
// if seek failed, returns false.
virtual bool SeekAbsolute(u64 Offset) = 0;
virtual bool SeekRelative(s64 Offset) = 0;
virtual bool SeekToEnd() = 0;
// gets the current offset in the stream
virtual u64 GetPosition() const = 0;
// gets the size of the stream
virtual u64 GetSize() const = 0;
// flush any changes to the stream to disk
virtual bool Flush() = 0;
// if the file was opened in atomic update mode, discards any changes made to the file
virtual bool Discard() = 0;
// if the file was opened in atomic update mode, commits the file and replaces the temporary file
virtual bool Commit() = 0;
// state accessors
inline bool InErrorState() const { return m_errorState; }
inline void SetErrorState() { m_errorState = true; }
inline void ClearErrorState() { m_errorState = false; }
protected:
ByteStream() : m_errorState(false) {}
// state bits
bool m_errorState;
// make it noncopyable
ByteStream(const ByteStream&) = delete;
ByteStream& operator=(const ByteStream&) = delete;
};
class NullByteStream : public ByteStream
{
public:
NullByteStream();
~NullByteStream();
virtual bool ReadByte(u8* pDestByte) override final;
virtual u32 Read(void* pDestination, u32 ByteCount) override final;
virtual bool Read2(void* pDestination, u32 ByteCount, u32* pNumberOfBytesRead /* = nullptr */) override final;
virtual bool WriteByte(u8 SourceByte) override final;
virtual u32 Write(const void* pSource, u32 ByteCount) override final;
virtual bool Write2(const void* pSource, u32 ByteCount, u32* pNumberOfBytesWritten /* = nullptr */) override final;
virtual bool SeekAbsolute(u64 Offset) override final;
virtual bool SeekRelative(s64 Offset) override final;
virtual bool SeekToEnd() override final;
virtual u64 GetSize() const override final;
virtual u64 GetPosition() const override final;
virtual bool Flush() override final;
virtual bool Commit() override final;
virtual bool Discard() override final;
};
class MemoryByteStream : public ByteStream
{
public:
MemoryByteStream(void* pMemory, u32 MemSize);
virtual ~MemoryByteStream();
u8* GetMemoryPointer() const { return m_pMemory; }
u32 GetMemorySize() const { return m_iSize; }
virtual bool ReadByte(u8* pDestByte) override;
virtual u32 Read(void* pDestination, u32 ByteCount) override;
virtual bool Read2(void* pDestination, u32 ByteCount, u32* pNumberOfBytesRead /* = nullptr */) override;
virtual bool WriteByte(u8 SourceByte) override;
virtual u32 Write(const void* pSource, u32 ByteCount) override;
virtual bool Write2(const void* pSource, u32 ByteCount, u32* pNumberOfBytesWritten /* = nullptr */) override;
virtual bool SeekAbsolute(u64 Offset) override;
virtual bool SeekRelative(s64 Offset) override;
virtual bool SeekToEnd() override;
virtual u64 GetSize() const override;
virtual u64 GetPosition() const override;
virtual bool Flush() override;
virtual bool Commit() override;
virtual bool Discard() override;
private:
u8* m_pMemory;
u32 m_iPosition;
u32 m_iSize;
};
class ReadOnlyMemoryByteStream : public ByteStream
{
public:
ReadOnlyMemoryByteStream(const void* pMemory, u32 MemSize);
virtual ~ReadOnlyMemoryByteStream();
const u8* GetMemoryPointer() const { return m_pMemory; }
u32 GetMemorySize() const { return m_iSize; }
virtual bool ReadByte(u8* pDestByte) override;
virtual u32 Read(void* pDestination, u32 ByteCount) override;
virtual bool Read2(void* pDestination, u32 ByteCount, u32* pNumberOfBytesRead /* = nullptr */) override;
virtual bool WriteByte(u8 SourceByte) override;
virtual u32 Write(const void* pSource, u32 ByteCount) override;
virtual bool Write2(const void* pSource, u32 ByteCount, u32* pNumberOfBytesWritten /* = nullptr */) override;
virtual bool SeekAbsolute(u64 Offset) override;
virtual bool SeekRelative(s64 Offset) override;
virtual bool SeekToEnd() override;
virtual u64 GetSize() const override;
virtual u64 GetPosition() const override;
virtual bool Flush() override;
virtual bool Commit() override;
virtual bool Discard() override;
private:
const u8* m_pMemory;
u32 m_iPosition;
u32 m_iSize;
};
class GrowableMemoryByteStream : public ByteStream
{
public:
GrowableMemoryByteStream(void* pInitialMem, u32 InitialMemSize);
virtual ~GrowableMemoryByteStream();
u8* GetMemoryPointer() const { return m_pMemory; }
u32 GetMemorySize() const { return m_iSize; }
virtual bool ReadByte(u8* pDestByte) override;
virtual u32 Read(void* pDestination, u32 ByteCount) override;
virtual bool Read2(void* pDestination, u32 ByteCount, u32* pNumberOfBytesRead /* = nullptr */) override;
virtual bool WriteByte(u8 SourceByte) override;
virtual u32 Write(const void* pSource, u32 ByteCount) override;
virtual bool Write2(const void* pSource, u32 ByteCount, u32* pNumberOfBytesWritten /* = nullptr */) override;
virtual bool SeekAbsolute(u64 Offset) override;
virtual bool SeekRelative(s64 Offset) override;
virtual bool SeekToEnd() override;
virtual u64 GetSize() const override;
virtual u64 GetPosition() const override;
virtual bool Flush() override;
virtual bool Commit() override;
virtual bool Discard() override;
private:
void Grow(u32 MinimumGrowth);
u8* m_pPrivateMemory;
u8* m_pMemory;
u32 m_iPosition;
u32 m_iSize;
u32 m_iMemorySize;
};
// base byte stream creation functions
// opens a local file-based stream. fills in error if passed, and returns false if the file cannot be opened.
std::unique_ptr<ByteStream> ByteStream_OpenFileStream(const char* FileName, u32 OpenMode);
// memory byte stream, caller is responsible for management, therefore it can be located on either the stack or on the
// heap.
std::unique_ptr<MemoryByteStream> ByteStream_CreateMemoryStream(void* pMemory, u32 Size);
// a growable memory byte stream will automatically allocate its own memory if the provided memory is overflowed.
// a "pure heap" buffer, i.e. a buffer completely managed by this implementation, can be created by supplying a NULL
// pointer and initialSize of zero.
std::unique_ptr<GrowableMemoryByteStream> ByteStream_CreateGrowableMemoryStream(void* pInitialMemory, u32 InitialSize);
std::unique_ptr<GrowableMemoryByteStream> ByteStream_CreateGrowableMemoryStream();
// readable memory stream
std::unique_ptr<ReadOnlyMemoryByteStream> ByteStream_CreateReadOnlyMemoryStream(const void* pMemory, u32 Size);
// null memory stream
std::unique_ptr<NullByteStream> ByteStream_CreateNullStream();
// copies one stream's contents to another. rewinds source streams automatically, and returns it back to its old
// position.
bool ByteStream_CopyStream(ByteStream* pDestinationStream, ByteStream* pSourceStream);
// appends one stream's contents to another.
bool ByteStream_AppendStream(ByteStream* pSourceStream, ByteStream* pDestinationStream);
// copies a number of bytes from one to another
u32 ByteStream_CopyBytes(ByteStream* pSourceStream, u32 byteCount, ByteStream* pDestinationStream);

View file

@ -1,6 +1,6 @@
#include "cd_image.h"
#include "YBaseLib/ByteStream.h"
#include "YBaseLib/Log.h"
#include "assert.h"
#include "log.h"
#include <array>
Log_SetChannel(CDImage);

View file

@ -1,6 +1,7 @@
#include "YBaseLib/Log.h"
#include "cd_image.h"
#include "cd_subchannel_replacement.h"
#include "file_system.h"
#include "log.h"
Log_SetChannel(CDImageBin);
class CDImageBin : public CDImage
@ -41,7 +42,7 @@ CDImageBin::~CDImageBin()
bool CDImageBin::Open(const char* filename)
{
m_filename = filename;
m_fp = std::fopen(filename, "rb");
m_fp = FileSystem::OpenCFile(filename, "rb");
if (!m_fp)
{
Log_ErrorPrintf("Failed to open binfile '%s'", filename);

View file

@ -1,7 +1,10 @@
#include "YBaseLib/Log.h"
#include "assert.h"
#include "cd_image.h"
#include "cd_subchannel_replacement.h"
#include "file_system.h"
#include "log.h"
#include <libcue/libcue.h>
#include <algorithm>
#include <map>
Log_SetChannel(CDImageCueSheet);
@ -61,7 +64,7 @@ static std::string ReplaceExtension(std::string_view path, std::string_view new_
bool CDImageCueSheet::OpenAndParse(const char* filename)
{
std::FILE* cue_fp = std::fopen(filename, "rb");
std::FILE* cue_fp = FileSystem::OpenCFile(filename, "rb");
if (!cue_fp)
{
Log_ErrorPrintf("Failed to open cuesheet '%s'", filename);
@ -98,7 +101,7 @@ bool CDImageCueSheet::OpenAndParse(const char* filename)
if (it == m_files.end())
{
std::string track_full_filename = basepath + track_filename;
std::FILE* track_fp = std::fopen(track_full_filename.c_str(), "rb");
std::FILE* track_fp = FileSystem::OpenCFile(track_full_filename.c_str(), "rb");
if (!track_fp)
{
Log_ErrorPrintf("Failed to open track filename '%s' (from '%s' and '%s')", track_full_filename.c_str(),

View file

@ -1,5 +1,7 @@
#include "cd_subchannel_replacement.h"
#include "YBaseLib/Log.h"
#include "log.h"
#include "file_system.h"
#include <algorithm>
#include <memory>
Log_SetChannel(CDSubChannelReplacement);
@ -29,7 +31,7 @@ static constexpr u32 MSFToLBA(u8 minute_bcd, u8 second_bcd, u8 frame_bcd)
bool CDSubChannelReplacement::LoadSBI(const char* path)
{
std::unique_ptr<std::FILE, void (*)(std::FILE*)> fp(std::fopen(path, "rb"), [](std::FILE* fp) { std::fclose(fp); });
auto fp = FileSystem::OpenManagedCFile(path, "rb");
if (!fp)
return false;

View file

@ -35,29 +35,42 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="align.h" />
<ClInclude Include="assert.h" />
<ClInclude Include="audio_stream.h" />
<ClInclude Include="bitfield.h" />
<ClInclude Include="byte_stream.h" />
<ClInclude Include="cd_image.h" />
<ClInclude Include="cpu_detect.h" />
<ClInclude Include="d3d11\shader_compiler.h" />
<ClInclude Include="d3d11\staging_texture.h" />
<ClInclude Include="d3d11\stream_buffer.h" />
<ClInclude Include="d3d11\texture.h" />
<ClInclude Include="fifo_queue.h" />
<ClInclude Include="file_system.h" />
<ClInclude Include="gl\program.h" />
<ClInclude Include="gl\stream_buffer.h" />
<ClInclude Include="gl\texture.h" />
<ClInclude Include="heap_array.h" />
<ClInclude Include="iso_reader.h" />
<ClInclude Include="jit_code_buffer.h" />
<ClInclude Include="log.h" />
<ClInclude Include="md5_digest.h" />
<ClInclude Include="null_audio_stream.h" />
<ClInclude Include="rectangle.h" />
<ClInclude Include="cd_subchannel_replacement.h" />
<ClInclude Include="state_wrapper.h" />
<ClInclude Include="string.h" />
<ClInclude Include="string_util.h" />
<ClInclude Include="timer.h" />
<ClInclude Include="timestamp.h" />
<ClInclude Include="types.h" />
<ClInclude Include="cd_xa.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="assert.cpp" />
<ClCompile Include="audio_stream.cpp" />
<ClCompile Include="byte_stream.cpp" />
<ClCompile Include="cd_image.cpp" />
<ClCompile Include="cd_image_bin.cpp" />
<ClCompile Include="cd_image_cue.cpp" />
@ -65,15 +78,22 @@
<ClCompile Include="d3d11\staging_texture.cpp" />
<ClCompile Include="d3d11\stream_buffer.cpp" />
<ClCompile Include="d3d11\texture.cpp" />
<ClCompile Include="file_system.cpp" />
<ClCompile Include="gl\program.cpp" />
<ClCompile Include="gl\stream_buffer.cpp" />
<ClCompile Include="gl\texture.cpp" />
<ClCompile Include="iso_reader.cpp" />
<ClCompile Include="jit_code_buffer.cpp" />
<ClCompile Include="cd_subchannel_replacement.cpp" />
<ClCompile Include="log.cpp" />
<ClCompile Include="md5_digest.cpp" />
<ClCompile Include="null_audio_stream.cpp" />
<ClCompile Include="state_wrapper.cpp" />
<ClCompile Include="cd_xa.cpp" />
<ClCompile Include="string.cpp" />
<ClCompile Include="string_util.cpp" />
<ClCompile Include="timer.cpp" />
<ClCompile Include="timestamp.cpp" />
</ItemGroup>
<ItemGroup>
<Natvis Include="bitfield.natvis" />
@ -85,9 +105,6 @@
<ProjectReference Include="..\..\dep\libcue\libcue.vcxproj">
<Project>{6a4208ed-e3dc-41e1-81cd-f61025fc285a}</Project>
</ProjectReference>
<ProjectReference Include="..\..\dep\YBaseLib\Source\YBaseLib.vcxproj">
<Project>{b56ce698-7300-4fa5-9609-942f1d05c5a2}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EE054E08-3799-4A59-A422-18259C105FFD}</ProjectGuid>
@ -226,7 +243,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
<ConformanceMode>true</ConformanceMode>
@ -252,7 +269,7 @@
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;WIN32;_DEBUGFAST;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SupportJustMyCode>false</SupportJustMyCode>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@ -281,7 +298,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
<ConformanceMode>true</ConformanceMode>
@ -307,7 +324,7 @@
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;WIN32;_DEBUGFAST;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SupportJustMyCode>false</SupportJustMyCode>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@ -337,7 +354,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
<WholeProgramOptimization>false</WholeProgramOptimization>
@ -367,7 +384,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OmitFramePointers>true</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -397,7 +414,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
<WholeProgramOptimization>false</WholeProgramOptimization>
@ -427,7 +444,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\libsamplerate\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\libcue\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OmitFramePointers>true</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>

View file

@ -35,6 +35,17 @@
<ClInclude Include="cd_image.h" />
<ClInclude Include="cd_subchannel_replacement.h" />
<ClInclude Include="null_audio_stream.h" />
<ClInclude Include="log.h" />
<ClInclude Include="string.h" />
<ClInclude Include="byte_stream.h" />
<ClInclude Include="timer.h" />
<ClInclude Include="timestamp.h" />
<ClInclude Include="assert.h" />
<ClInclude Include="align.h" />
<ClInclude Include="file_system.h" />
<ClInclude Include="string_util.h" />
<ClInclude Include="md5_digest.h" />
<ClInclude Include="cpu_detect.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="jit_code_buffer.cpp" />
@ -68,6 +79,15 @@
<ClCompile Include="iso_reader.cpp" />
<ClCompile Include="cd_subchannel_replacement.cpp" />
<ClCompile Include="null_audio_stream.cpp" />
<ClCompile Include="string.cpp" />
<ClCompile Include="byte_stream.cpp" />
<ClCompile Include="log.cpp" />
<ClCompile Include="timestamp.cpp" />
<ClCompile Include="timer.cpp" />
<ClCompile Include="assert.cpp" />
<ClCompile Include="file_system.cpp" />
<ClCompile Include="string_util.cpp" />
<ClCompile Include="md5_digest.cpp" />
</ItemGroup>
<ItemGroup>
<Natvis Include="bitfield.natvis" />

31
src/common/cpu_detect.h Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#if defined(_MSC_VER)
#if defined(_M_X64)
#define CPU_X64 1
#elif defined(_M_IX86)
#define CPU_X86 1
#else
#error Unknown architecture.
#endif
#elif defined(__GNUC__) || defined(__clang__)
#if defined(__x86_64__)
#define CPU_X64 1
#elif defined(__i386__)
#define CPU_X86 1
#elif defined(__aarch64__)
#define CPU_AARCH64 1
#elif defined(__arm__)
#define CPU_ARM 1
#else
#error Unknown architecture.
#endif
#else
#error Unknown compiler.
#endif

View file

@ -1,6 +1,6 @@
#include "shader_compiler.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/String.h"
#include "../log.h"
#include "../string_util.h"
#include <array>
#include <d3dcompiler.h>
#include <fstream>
@ -54,33 +54,32 @@ ComPtr<ID3DBlob> CompileShader(Type type, D3D_FEATURE_LEVEL feature_level, std::
D3DCompile(code.data(), code.size(), "0", nullptr, nullptr, "main", target, debug ? flags_debug : flags_non_debug,
0, blob.GetAddressOf(), error_blob.GetAddressOf());
String error_string;
std::string error_string;
if (error_blob)
{
error_string.AppendString(static_cast<const char*>(error_blob->GetBufferPointer()),
static_cast<uint32>(error_blob->GetBufferSize()));
error_string.append(static_cast<const char*>(error_blob->GetBufferPointer()), error_blob->GetBufferSize());
error_blob.Reset();
}
if (FAILED(hr))
{
Log_ErrorPrintf("Failed to compile '%s':\n%s", target, error_string.GetCharArray());
Log_ErrorPrintf("Failed to compile '%s':\n%s", target, error_string.c_str());
std::ofstream ofs(SmallString::FromFormat("bad_shader_%u.txt", s_next_bad_shader_id++),
std::ofstream ofs(StringUtil::StdStringFromFormat("bad_shader_%u.txt", s_next_bad_shader_id++).c_str(),
std::ofstream::out | std::ofstream::binary);
if (ofs.is_open())
{
ofs << code;
ofs << "\n\nCompile as " << target << " failed: " << hr << "\n";
ofs.write(error_string.GetCharArray(), error_string.GetLength());
ofs.write(error_string.c_str(), error_string.size());
ofs.close();
}
return {};
}
if (!error_string.IsEmpty())
Log_WarningPrintf("'%s' compiled with warnings:\n%s", target, error_string.GetCharArray());
if (!error_string.empty())
Log_WarningPrintf("'%s' compiled with warnings:\n%s", target, error_string.c_str());
return blob;
}

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/Windows/WindowsHeaders.h"
#include "../windows_headers.h"
#include <d3d11.h>
#include <string_view>
#include <type_traits>

View file

@ -1,5 +1,6 @@
#include "staging_texture.h"
#include "YBaseLib/Log.h"
#include "../log.h"
#include "../assert.h"
Log_SetChannel(D3D11);
namespace D3D11 {

View file

@ -1,6 +1,6 @@
#pragma once
#include "../types.h"
#include "YBaseLib/Windows/WindowsHeaders.h"
#include "../windows_headers.h"
#include <cstring>
#include <d3d11.h>
#include <wrl/client.h>

View file

@ -1,5 +1,7 @@
#include "stream_buffer.h"
#include "YBaseLib/Log.h"
#include "../align.h"
#include "../assert.h"
#include "../log.h"
Log_SetChannel(D3D11);
namespace D3D11 {

View file

@ -1,6 +1,6 @@
#pragma once
#include "../types.h"
#include "YBaseLib/Windows/WindowsHeaders.h"
#include "../windows_headers.h"
#include <d3d11.h>
#include <wrl/client.h>

View file

@ -1,5 +1,5 @@
#include "texture.h"
#include "YBaseLib/Log.h"
#include "../log.h"
Log_SetChannel(D3D11);
namespace D3D11 {

View file

@ -1,6 +1,6 @@
#pragma once
#include "../types.h"
#include "YBaseLib/Windows/WindowsHeaders.h"
#include "../windows_headers.h"
#include <d3d11.h>
#include <wrl/client.h>

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/Assert.h"
#include "assert.h"
#include "types.h"
#include <algorithm>
#include <cstring>

1275
src/common/file_system.cpp Normal file

File diff suppressed because it is too large Load diff

176
src/common/file_system.h Normal file
View file

@ -0,0 +1,176 @@
#pragma once
#include "timestamp.h"
#include "types.h"
#include <cstdio>
#include <memory>
#include <string>
#include <vector>
class ByteStream;
#ifdef Y_PLATFORM_WINDOWS
#define FS_OSPATH_SEPERATOR_CHARACTER '\\'
#else
#define FS_OSPATH_SEPERATOR_CHARACTER '/'
#endif
enum FILESYSTEM_FILE_ATTRIBUTES
{
FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY = 1,
FILESYSTEM_FILE_ATTRIBUTE_READ_ONLY = 2,
FILESYSTEM_FILE_ATTRIBUTE_COMPRESSED = 4,
};
enum FILESYSTEM_FIND_FLAGS
{
FILESYSTEM_FIND_RECURSIVE = (1 << 0),
FILESYSTEM_FIND_RELATIVE_PATHS = (1 << 1),
FILESYSTEM_FIND_HIDDEN_FILES = (1 << 2),
FILESYSTEM_FIND_FOLDERS = (1 << 3),
FILESYSTEM_FIND_FILES = (1 << 4),
FILESYSTEM_FIND_KEEP_ARRAY = (1 << 5),
};
struct FILESYSTEM_STAT_DATA
{
u32 Attributes;
Timestamp ModificationTime;
u64 Size;
};
struct FILESYSTEM_FIND_DATA
{
std::string FileName;
Timestamp ModificationTime;
u32 Attributes;
u64 Size;
};
struct FILESYSTEM_CHANGE_NOTIFY_DATA
{
String DirectoryPath;
bool RecursiveWatch;
void* pSystemData;
};
namespace FileSystem {
using FindResultsArray = std::vector<FILESYSTEM_FIND_DATA>;
class ChangeNotifier
{
public:
enum ChangeEvent
{
ChangeEvent_FileAdded = (1 << 0),
ChangeEvent_FileRemoved = (1 << 1),
ChangeEvent_FileModified = (1 << 2),
ChangeEvent_RenamedOldName = (1 << 3),
ChangeEvent_RenamedNewName = (1 << 4),
};
struct ChangeInfo
{
const char* Path;
u32 Event;
};
public:
virtual ~ChangeNotifier();
const String& GetDirectoryPath() const { return m_directoryPath; }
const bool GetRecursiveWatch() const { return m_recursiveWatch; }
typedef void (*EnumerateChangesCallback)(const ChangeInfo* pChangeInfo, void* pUserData);
virtual void EnumerateChanges(EnumerateChangesCallback callback, void* pUserData) = 0;
private:
template<typename CALLBACK_TYPE>
static void EnumerateChangesTrampoline(const ChangeInfo* pChangeInfo, void* pUserData)
{
CALLBACK_TYPE* pRealCallback = reinterpret_cast<CALLBACK_TYPE*>(pUserData);
(*pRealCallback)(pChangeInfo);
}
public:
template<typename CALLBACK_TYPE>
void EnumerateChanges(CALLBACK_TYPE callback)
{
CALLBACK_TYPE* pCallback = &callback;
EnumerateChanges(&ChangeNotifier::EnumerateChangesTrampoline<CALLBACK_TYPE>, reinterpret_cast<void*>(pCallback));
}
protected:
ChangeNotifier(const String& directoryPath, bool recursiveWatch);
String m_directoryPath;
bool m_recursiveWatch;
};
// create a change notifier
std::unique_ptr<ChangeNotifier> CreateChangeNotifier(const char* path, bool recursiveWatch);
// appends a path string to the current path string. optionally canonicalizes it.
void AppendPath(char* Path, u32 cbPath, const char* NewPath);
void AppendPath(String& Path, const char* NewPath);
// canonicalize a path string (i.e. replace .. with actual folder name, etc), if OS path is used, on windows, the
// separators will be \, otherwise /
void CanonicalizePath(char* Destination, u32 cbDestination, const char* Path, bool OSPath = true);
void CanonicalizePath(String& Destination, const char* Path, bool OSPath = true);
void CanonicalizePath(String& Destination, bool OSPath = true);
// translates the specified path into a string compatible with the hosting OS
void BuildOSPath(char* Destination, u32 cbDestination, const char* Path);
void BuildOSPath(String& Destination, const char* Path);
void BuildOSPath(String& Destination);
// builds a path relative to the specified file, optionally canonicalizing it
void BuildPathRelativeToFile(char* Destination, u32 cbDestination, const char* CurrentFileName, const char* NewFileName,
bool OSPath = true, bool Canonicalize = true);
void BuildPathRelativeToFile(String& Destination, const char* CurrentFileName, const char* NewFileName,
bool OSPath = true, bool Canonicalize = true);
// sanitizes a filename for use in a filesystem.
void SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes = true);
void SanitizeFileName(String& Destination, const char* FileName, bool StripSlashes = true);
void SanitizeFileName(String& Destination, bool StripSlashes = true);
// search for files
bool FindFiles(const char* Path, const char* Pattern, u32 Flags, FindResultsArray* pResults);
// stat file
bool StatFile(const char* Path, FILESYSTEM_STAT_DATA* pStatData);
// file exists?
bool FileExists(const char* Path);
// directory exists?
bool DirectoryExists(const char* Path);
// delete file
bool DeleteFile(const char* Path);
// reads file name
bool GetFileName(String& Destination, const char* FileName);
bool GetFileName(String& FileName);
// open files
std::unique_ptr<ByteStream> OpenFile(const char* FileName, u32 Flags);
using ManagedCFilePtr = std::unique_ptr<std::FILE, void (*)(std::FILE*)>;
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode);
std::FILE* OpenCFile(const char* filename, const char* mode);
// creates a directory in the local filesystem
// if the directory already exists, the return value will be true.
// if Recursive is specified, all parent directories will be created
// if they do not exist.
bool CreateDirectory(const char* Path, bool Recursive);
// deletes a directory in the local filesystem
// if the directory has files, unless the recursive flag is set, it will fail
bool DeleteDirectory(const char* Path, bool Recursive);
}; // namespace FileSystem

View file

@ -1,6 +1,7 @@
#include "program.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/String.h"
#include "../assert.h"
#include "../log.h"
#include "../string_util.h"
#include <array>
#include <fstream>
Log_SetChannel(GL);
@ -46,7 +47,7 @@ GLuint Program::CompileShader(GLenum type, const std::string_view source)
{
Log_ErrorPrintf("Shader failed to compile:\n%s", info_log.c_str());
std::ofstream ofs(SmallString::FromFormat("bad_shader_%u.txt", s_next_bad_shader_id++),
std::ofstream ofs(StringUtil::StdStringFromFormat("bad_shader_%u.txt", s_next_bad_shader_id++).c_str(),
std::ofstream::out | std::ofstream::binary);
if (ofs.is_open())
{

View file

@ -1,5 +1,6 @@
#include "stream_buffer.h"
#include "YBaseLib/Assert.h"
#include "../assert.h"
#include "../align.h"
#include <array>
#include <cstdio>

View file

@ -1,6 +1,6 @@
#include "texture.h"
#include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h"
#include "../assert.h"
#include "../log.h"
Log_SetChannel(GL);
namespace GL {

View file

@ -1,5 +1,5 @@
#include "iso_reader.h"
#include "YBaseLib/Log.h"
#include "log.h"
#include "cd_image.h"
#include <cctype>
Log_SetChannel(ISOReader);

View file

@ -1,9 +1,12 @@
#include "jit_code_buffer.h"
#include "YBaseLib/Assert.h"
#include "align.h"
#include "assert.h"
#include "cpu_detect.h"
#include <algorithm>
#if defined(Y_PLATFORM_WINDOWS)
#include "YBaseLib/Windows/WindowsHeaders.h"
#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_ANDROID)
#if defined(WIN32)
#include "windows_headers.h"
#else
#include <sys/mman.h>
#endif
@ -11,9 +14,9 @@ JitCodeBuffer::JitCodeBuffer(u32 size /* = 64 * 1024 * 1024 */, u32 far_code_siz
{
m_total_size = size + far_code_size;
#if defined(Y_PLATFORM_WINDOWS)
#if defined(WIN32)
m_code_ptr = static_cast<u8*>(VirtualAlloc(nullptr, m_total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE));
#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_ANDROID)
#elif defined(__linux__) || defined(__ANDROID__)
m_code_ptr = static_cast<u8*>(
mmap(nullptr, m_total_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
#else
@ -34,9 +37,9 @@ JitCodeBuffer::JitCodeBuffer(u32 size /* = 64 * 1024 * 1024 */, u32 far_code_siz
JitCodeBuffer::~JitCodeBuffer()
{
#if defined(Y_PLATFORM_WINDOWS)
#if defined(WIN32)
VirtualFree(m_code_ptr, 0, MEM_RELEASE);
#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_ANDROID)
#elif defined(__linux__) || defined(__ANDROID__)
munmap(m_code_ptr, m_total_size);
#endif
}
@ -46,7 +49,7 @@ void JitCodeBuffer::CommitCode(u32 length)
if (length == 0)
return;
#if defined(Y_CPU_ARM) || defined(Y_CPU_AARCH64)
#if defined(CPU_ARM) || defined(CPU_AARCH64)
// ARM instruction and data caches are not coherent, we need to flush after every block.
FlushInstructionCache(m_free_code_ptr, length);
#endif
@ -61,7 +64,7 @@ void JitCodeBuffer::CommitFarCode(u32 length)
if (length == 0)
return;
#if defined(Y_CPU_ARM) || defined(Y_CPU_AARCH64)
#if defined(CPU_ARM) || defined(CPU_AARCH64)
// ARM instruction and data caches are not coherent, we need to flush after every block.
FlushInstructionCache(m_free_far_code_ptr, length);
#endif
@ -101,9 +104,9 @@ void JitCodeBuffer::Align(u32 alignment, u8 padding_value)
void JitCodeBuffer::FlushInstructionCache(void* address, u32 size)
{
#if defined(Y_PLATFORM_WINDOWS)
#if defined(WIN32)
::FlushInstructionCache(GetCurrentProcess(), address, size);
#elif defined(Y_COMPILER_GCC) || defined(Y_COMPILER_CLANG)
#elif defined(__GNUC__) || defined(__clang__)
__builtin___clear_cache(reinterpret_cast<char*>(address), reinterpret_cast<char*>(address) + size);
#else
#error Unknown platform.

343
src/common/log.cpp Normal file
View file

@ -0,0 +1,343 @@
#include "log.h"
#include "assert.h"
#include "string.h"
#include "timer.h"
#include <mutex>
#include <vector>
#if defined(WIN32)
#include "windows_headers.h"
#elif defined(__ANDROID__)
#include <android/log.h>
#else
#include <unistd.h>
#endif
namespace Log {
struct RegisteredCallback
{
CallbackFunctionType Function;
void* Parameter;
};
std::vector<RegisteredCallback> s_callbacks;
static std::mutex s_callback_mutex;
static LOGLEVEL s_filter_level = LOGLEVEL_TRACE;
static Common::Timer::Value s_startTimeStamp = Common::Timer::GetValue();
static bool s_consoleOutputEnabled = false;
static String s_consoleOutputChannelFilter;
static LOGLEVEL s_consoleOutputLevelFilter = LOGLEVEL_TRACE;
static bool s_debugOutputEnabled = false;
static String s_debugOutputChannelFilter;
static LOGLEVEL s_debugOutputLevelFilter = LOGLEVEL_TRACE;
void RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam)
{
RegisteredCallback Callback;
Callback.Function = callbackFunction;
Callback.Parameter = pUserParam;
std::lock_guard<std::mutex> guard(s_callback_mutex);
s_callbacks.push_back(std::move(Callback));
}
void UnregisterCallback(CallbackFunctionType callbackFunction, void* pUserParam)
{
std::lock_guard<std::mutex> guard(s_callback_mutex);
for (auto iter = s_callbacks.begin(); iter != s_callbacks.end(); ++iter)
{
if (iter->Function == callbackFunction && iter->Parameter == pUserParam)
{
s_callbacks.erase(iter);
break;
}
}
}
static void ExecuteCallbacks(const char* channelName, const char* functionName, LOGLEVEL level, const char* message)
{
std::lock_guard<std::mutex> guard(s_callback_mutex);
for (RegisteredCallback& callback : s_callbacks)
callback.Function(callback.Parameter, channelName, functionName, level, message);
}
static void FormatLogMessageForDisplay(const char* channelName, const char* functionName, LOGLEVEL level,
const char* message, void (*printCallback)(const char*, void*),
void* pCallbackUserData)
{
static const char levelCharacters[LOGLEVEL_COUNT] = {'X', 'E', 'W', 'P', 'S', 'I', 'D', 'R', 'B', 'T'};
// find time since start of process
float messageTime =
static_cast<float>(Common::Timer::ConvertValueToSeconds(Common::Timer::GetValue() - s_startTimeStamp));
// write prefix
#ifndef Y_BUILD_CONFIG_SHIPPING
char prefix[256];
if (level <= LOGLEVEL_PERF)
std::snprintf(prefix, countof(prefix), "[%10.4f] %c(%s): ", messageTime, levelCharacters[level], functionName);
else
std::snprintf(prefix, countof(prefix), "[%10.4f] %c/%s: ", messageTime, levelCharacters[level], channelName);
printCallback(prefix, pCallbackUserData);
#else
char prefix[256];
std::snprintf(prefix, countof(prefix), "[%10.4f] %c/%s: ", messageTime, levelCharacters[level], channelName);
printCallback(prefix, pCallbackUserData);
#endif
// write message
printCallback(message, pCallbackUserData);
}
#if defined(WIN32)
static void ConsoleOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName,
LOGLEVEL level, const char* message)
{
if (!s_consoleOutputEnabled || level > s_consoleOutputLevelFilter ||
s_consoleOutputChannelFilter.Find(channelName) >= 0)
return;
if (level > LOGLEVEL_COUNT)
level = LOGLEVEL_TRACE;
HANDLE hConsole = GetStdHandle((level <= LOGLEVEL_WARNING) ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
if (hConsole != INVALID_HANDLE_VALUE)
{
static const WORD levelColors[LOGLEVEL_COUNT] = {
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, // NONE
FOREGROUND_RED | FOREGROUND_INTENSITY, // ERROR
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // WARNING
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // PERF
FOREGROUND_GREEN | FOREGROUND_INTENSITY, // SUCCESS
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // INFO
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, // DEV
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // PROFILE
FOREGROUND_GREEN, // DEBUG
FOREGROUND_BLUE, // TRACE
};
CONSOLE_SCREEN_BUFFER_INFO oldConsoleScreenBufferInfo;
GetConsoleScreenBufferInfo(hConsole, &oldConsoleScreenBufferInfo);
SetConsoleTextAttribute(hConsole, levelColors[level]);
// write message in the formatted way
FormatLogMessageForDisplay(
channelName, functionName, level, message,
[](const char* text, void* hConsole) {
DWORD written;
WriteConsoleA(static_cast<HANDLE>(hConsole), text, static_cast<DWORD>(std::strlen(text)), &written, nullptr);
},
(void*)hConsole);
// write newline
DWORD written;
WriteConsoleA(hConsole, "\r\n", 2, &written, nullptr);
// restore color
SetConsoleTextAttribute(hConsole, oldConsoleScreenBufferInfo.wAttributes);
}
}
static void DebugOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, LOGLEVEL level,
const char* message)
{
if (!s_debugOutputEnabled || level > s_debugOutputLevelFilter || s_debugOutputChannelFilter.Find(channelName) >= 0)
return;
FormatLogMessageForDisplay(channelName, functionName, level, message,
[](const char* text, void*) { OutputDebugStringA(text); }, nullptr);
OutputDebugStringA("\n");
}
#elif defined(__ANDROID__)
static void ConsoleOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName,
LOGLEVEL level, const char* message)
{
}
static void DebugOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, LOGLEVEL level,
const char* message)
{
if (!s_debugOutputEnabled || level > s_debugOutputLevelFilter || s_debugOutputChannelFilter.Find(functionName) >= 0)
return;
static const int logPriority[LOGLEVEL_COUNT] = {
ANDROID_LOG_INFO, // NONE
ANDROID_LOG_ERROR, // ERROR
ANDROID_LOG_WARN, // WARNING
ANDROID_LOG_INFO, // PERF
ANDROID_LOG_INFO, // SUCCESS
ANDROID_LOG_INFO, // INFO
ANDROID_LOG_DEBUG, // DEV
ANDROID_LOG_DEBUG, // PROFILE
ANDROID_LOG_DEBUG, // DEBUG
ANDROID_LOG_DEBUG, // TRACE
};
__android_log_write(logPriority[level], channelName, message);
}
#else
static void ConsoleOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName,
LOGLEVEL level, const char* message)
{
if (!s_consoleOutputEnabled || level > s_consoleOutputLevelFilter ||
s_consoleOutputChannelFilter.Find(channelName) >= 0)
return;
static const char* colorCodes[LOGLEVEL_COUNT] = {
"\033[0m", // NONE
"\033[1;31m", // ERROR
"\033[1;33m", // WARNING
"\033[1;35m", // PERF
"\033[1;32m", // SUCCESS
"\033[1;37m", // INFO
"\033[0;37m", // DEV
"\033[1;36m", // PROFILE
"\033[0;32m", // DEBUG
"\033[0;34m", // TRACE
};
int outputFd = (level <= LOGLEVEL_WARNING) ? STDERR_FILENO : STDOUT_FILENO;
write(outputFd, colorCodes[level], std::strlen(colorCodes[level]));
Log::FormatLogMessageForDisplay(
channelName, functionName, level, message,
[](const char* text, void* outputFd) { write((int)(intptr_t)outputFd, text, std::strlen(text)); },
(void*)(intptr_t)outputFd);
write(outputFd, colorCodes[0], std::strlen(colorCodes[0]));
write(outputFd, "\n", 1);
}
static void DebugOutputLogCallback(void* pUserParam, const char* channelName, const char* functionName, LOGLEVEL level,
const char* message)
{
}
#endif
void SetConsoleOutputParams(bool Enabled, const char* ChannelFilter, LOGLEVEL LevelFilter)
{
if (s_consoleOutputEnabled != Enabled)
{
s_consoleOutputEnabled = Enabled;
if (Enabled)
RegisterCallback(ConsoleOutputLogCallback, NULL);
else
UnregisterCallback(ConsoleOutputLogCallback, NULL);
#if defined(WIN32)
// On windows, no console is allocated by default on a windows based application
static bool consoleWasAllocated = false;
if (Enabled)
{
if (GetConsoleWindow() == NULL)
{
DebugAssert(!consoleWasAllocated);
consoleWasAllocated = true;
AllocConsole();
std::FILE* fp;
freopen_s(&fp, "CONIN$", "r", stdin);
freopen_s(&fp, "CONOUT$", "w", stdout);
freopen_s(&fp, "CONOUT$", "w", stderr);
}
}
else
{
if (consoleWasAllocated)
{
FreeConsole();
consoleWasAllocated = false;
}
}
#endif
}
s_consoleOutputChannelFilter = (ChannelFilter != NULL) ? ChannelFilter : "";
s_consoleOutputLevelFilter = LevelFilter;
}
void SetDebugOutputParams(bool enabled, const char* channelFilter /* = nullptr */,
LOGLEVEL levelFilter /* = LOGLEVEL_TRACE */)
{
if (s_debugOutputEnabled != enabled)
{
s_debugOutputEnabled = enabled;
if (enabled)
RegisterCallback(DebugOutputLogCallback, nullptr);
else
UnregisterCallback(DebugOutputLogCallback, nullptr);
}
s_debugOutputChannelFilter = (channelFilter != nullptr) ? channelFilter : "";
s_debugOutputLevelFilter = levelFilter;
}
void SetFilterLevel(LOGLEVEL level)
{
DebugAssert(level < LOGLEVEL_COUNT);
s_filter_level = level;
}
void Write(const char* channelName, const char* functionName, LOGLEVEL level, const char* message)
{
if (level > s_filter_level)
return;
ExecuteCallbacks(channelName, functionName, level, message);
}
void Writef(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, ...)
{
if (level > s_filter_level)
return;
va_list ap;
va_start(ap, format);
Writev(channelName, functionName, level, format, ap);
va_end(ap);
}
void Writev(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, va_list ap)
{
if (level > s_filter_level)
return;
va_list apCopy;
va_copy(apCopy, ap);
#ifdef WIN32
u32 requiredSize = static_cast<u32>(_vscprintf(format, ap));
#else
u32 requiredSize = std::vsnprintf(nullptr, 0, format, ap);
#endif
if (requiredSize < 256)
{
char buffer[256];
std::vsnprintf(buffer, countof(buffer), format, ap);
ExecuteCallbacks(channelName, functionName, level, buffer);
}
else
{
char* buffer = new char[requiredSize + 1];
std::vsnprintf(buffer, requiredSize + 1, format, ap);
ExecuteCallbacks(channelName, functionName, level, buffer);
delete[] buffer;
}
}
} // namespace Log

92
src/common/log.h Normal file
View file

@ -0,0 +1,92 @@
#pragma once
#include "types.h"
#include <cinttypes>
#include <mutex>
enum LOGLEVEL
{
LOGLEVEL_NONE = 0, // Silences all log traffic
LOGLEVEL_ERROR = 1, // "ErrorPrint"
LOGLEVEL_WARNING = 2, // "WarningPrint"
LOGLEVEL_PERF = 3, // "PerfPrint"
LOGLEVEL_SUCCESS = 4, // "SuccessPrint"
LOGLEVEL_INFO = 5, // "InfoPrint"
LOGLEVEL_DEV = 6, // "DevPrint"
LOGLEVEL_PROFILE = 7, // "ProfilePrint"
LOGLEVEL_DEBUG = 8, // "DebugPrint"
LOGLEVEL_TRACE = 9, // "TracePrint"
LOGLEVEL_COUNT = 10
};
namespace Log {
// log message callback type
using CallbackFunctionType = void (*)(void* pUserParam, const char* channelName, const char* functionName,
LOGLEVEL level, const char* message);
// registers a log callback
void RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam);
// unregisters a log callback
void UnregisterCallback(CallbackFunctionType callbackFunction, void* pUserParam);
// adds a standard console output
void SetConsoleOutputParams(bool enabled, const char* channelFilter = nullptr, LOGLEVEL levelFilter = LOGLEVEL_TRACE);
// adds a debug console output [win32/android only]
void SetDebugOutputParams(bool enabled, const char* channelFilter = nullptr, LOGLEVEL levelFilter = LOGLEVEL_TRACE);
// Sets global filtering level, messages below this level won't be sent to any of the logging sinks.
void SetFilterLevel(LOGLEVEL level);
// writes a message to the log
void Write(const char* channelName, const char* functionName, LOGLEVEL level, const char* message);
void Writef(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, ...);
void Writev(const char* channelName, const char* functionName, LOGLEVEL level, const char* format, va_list ap);
} // namespace Log
#ifdef Y_BUILD_CONFIG_SHIPPING
#define LOG_MESSAGE_FUNCTION_NAME ""
#else
#define LOG_MESSAGE_FUNCTION_NAME __FUNCTION__
#endif
// log wrappers
#define Log_SetChannel(ChannelName) static const char* ___LogChannel___ = #ChannelName;
#define Log_ErrorPrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_ERROR, msg)
#define Log_ErrorPrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_ERROR, __VA_ARGS__)
#define Log_WarningPrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_WARNING, msg)
#define Log_WarningPrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_WARNING, __VA_ARGS__)
#define Log_SuccessPrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_SUCCESS, msg)
#define Log_SuccessPrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_SUCCESS, __VA_ARGS__)
#define Log_InfoPrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_INFO, msg)
#define Log_InfoPrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_INFO, __VA_ARGS__)
#define Log_PerfPrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_PERF, msg)
#define Log_PerfPrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_PERF, __VA_ARGS__)
#define Log_DevPrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_DEV, msg)
#define Log_DevPrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_DEV, __VA_ARGS__)
#define Log_ProfilePrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_PROFILE, msg)
#define Log_ProfilePrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_PROFILE, __VA_ARGS__)
#ifdef _DEBUG
#define Log_DebugPrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_DEBUG, msg)
#define Log_DebugPrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_DEBUG, __VA_ARGS__)
#define Log_TracePrint(msg) Log::Write(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_TRACE, msg)
#define Log_TracePrintf(...) Log::Writef(___LogChannel___, LOG_MESSAGE_FUNCTION_NAME, LOGLEVEL_TRACE, __VA_ARGS__)
#else
#define Log_DebugPrint(msg) \
do \
{ \
} while (0)
#define Log_DebugPrintf(...) \
do \
{ \
} while (0)
#define Log_TracePrint(msg) \
do \
{ \
} while (0)
#define Log_TracePrintf(...) \
do \
{ \
} while (0)
#endif

226
src/common/md5_digest.cpp Normal file
View file

@ -0,0 +1,226 @@
#include "md5_digest.h"
#ifndef HIGHFIRST
#define byteReverse(buf, len) /* Nothing */
#else
/*
* Note: this code is harmless on little-endian machines.
*/
static void byteReverse(unsigned char* buf, unsigned longs)
{
u32 t;
do
{
t = (u32)((unsigned)buf[3] << 8 | buf[2]) << 16 | ((unsigned)buf[1] << 8 | buf[0]);
*(u32*)buf = t;
buf += 4;
} while (--longs);
}
#endif
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
static void MD5Transform(u32 buf[4], u32 in[16])
{
// register u32 a, b, c, d;
u32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
MD5Digest::MD5Digest()
{
Reset();
}
void MD5Digest::Reset()
{
this->buf[0] = 0x67452301;
this->buf[1] = 0xefcdab89;
this->buf[2] = 0x98badcfe;
this->buf[3] = 0x10325476;
this->bits[0] = 0;
this->bits[1] = 0;
}
void MD5Digest::Update(const void* pData, u32 cbData)
{
u32 t;
const u8* pByteData = reinterpret_cast<const u8*>(pData);
/* Update bitcount */
t = this->bits[0];
if ((this->bits[0] = t + ((u32)cbData << 3)) < t)
this->bits[1]++; /* Carry from low to high */
this->bits[1] += cbData >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if (t)
{
u8* p = (u8*)this->in + t;
t = 64 - t;
if (cbData < t)
{
std::memcpy(p, pByteData, cbData);
return;
}
std::memcpy(p, pByteData, t);
byteReverse(this->in, 16);
MD5Transform(this->buf, (u32*)this->in);
pByteData += t;
cbData -= t;
}
/* Process data in 64-byte chunks */
while (cbData >= 64)
{
std::memcpy(this->in, pByteData, 64);
byteReverse(this->in, 16);
MD5Transform(this->buf, (u32*)this->in);
pByteData += 64;
cbData -= 64;
}
/* Handle any remaining bytes of data. */
std::memcpy(this->in, pByteData, cbData);
}
void MD5Digest::Final(u8 Digest[16])
{
u32 count;
u8* p;
/* Compute number of bytes mod 64 */
count = (this->bits[0] >> 3) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = this->in + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8)
{
/* Two lots of padding: Pad the first block to 64 bytes */
std::memset(p, 0, count);
byteReverse(this->in, 16);
MD5Transform(this->buf, (u32*)this->in);
/* Now fill the next block with 56 bytes */
std::memset(this->in, 0, 56);
}
else
{
/* Pad block to 56 bytes */
std::memset(p, 0, count - 8);
}
byteReverse(this->in, 14);
/* Append length in bits and transform */
((u32*)this->in)[14] = this->bits[0];
((u32*)this->in)[15] = this->bits[1];
MD5Transform(this->buf, (u32*)this->in);
byteReverse((unsigned char*)this->buf, 4);
std::memcpy(Digest, this->buf, 16);
}

20
src/common/md5_digest.h Normal file
View file

@ -0,0 +1,20 @@
#pragma once
#include "types.h"
// based heavily on this implementation:
// http://www.fourmilab.ch/md5/
class MD5Digest
{
public:
MD5Digest();
void Update(const void* pData, u32 cbData);
void Final(u8 Digest[16]);
void Reset();
private:
u32 buf[4];
u32 bits[2];
u8 in[64];
};

View file

@ -1,4 +1,5 @@
#pragma once
#include <algorithm>
#include <limits>
#include <tuple>
#include <type_traits>

View file

@ -1,6 +1,6 @@
#include "state_wrapper.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/String.h"
#include "log.h"
#include "string.h"
#include <cinttypes>
#include <cstring>
Log_SetChannel(StateWrapper);

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/ByteStream.h"
#include "byte_stream.h"
#include "fifo_queue.h"
#include "heap_array.h"
#include "types.h"

1039
src/common/string.cpp Normal file

File diff suppressed because it is too large Load diff

373
src/common/string.h Normal file
View file

@ -0,0 +1,373 @@
#pragma once
#include "types.h"
#include <atomic>
#include <cstdarg>
#include <cstring>
#include <limits>
//
// String
// Implements a UTF-8 string container with copy-on-write behavior.
// The data class is not currently threadsafe (creating a mutex on each container would be overkill),
// so locking is still required when multiple threads are involved.
//
class String
{
public:
// Internal StringData class.
struct StringData
{
// Pointer to memory where the string is located
char* pBuffer;
// Length of the string located in pBuffer (in characters)
u32 StringLength;
// Size of the buffer pointed to by pBuffer
u32 BufferSize;
// Reference count of this data object. If set to -1,
// it is considered noncopyable and any copies of the string
// will always create their own copy.
std::atomic<s32> ReferenceCount;
// Whether the memory pointed to by pBuffer is writable.
bool ReadOnly;
};
public:
// Creates an empty string.
String();
// Creates a string containing the specified text.
// Note that this will incur a heap allocation, even if Text is on the stack.
// For strings that do not allocate any space on the heap, see StaticString.
String(const char* Text);
// Creates a string using the same buffer as another string (copy-on-write).
String(const String& copyString);
// Move constructor, take reference from other string.
String(String&& moveString);
// Destructor. Child classes may not have any destructors, as this is not virtual.
~String();
// manual assignment
void Assign(const String& copyString);
void Assign(const char* copyText);
void Assign(String&& moveString);
// assignment but ensures that we have our own copy.
void AssignCopy(const String& copyString);
// Ensures that the string has its own unique copy of the data.
void EnsureOwnWritableCopy();
// Ensures that we have our own copy of the buffer, and spaceRequired bytes free in the buffer.
void EnsureRemainingSpace(u32 spaceRequired);
// clears the contents of the string
void Clear();
// clear the contents of the string, and free any memory currently being used
void Obliterate();
// swaps strings
void Swap(String& swapString);
// append a single character to this string
void AppendCharacter(char c);
// append a string to this string
void AppendString(const String& appendStr);
void AppendString(const char* appendText);
void AppendString(const char* appendString, u32 Count);
// append a substring of the specified string to this string
void AppendSubString(const String& appendStr, s32 Offset = 0, s32 Count = std::numeric_limits<s32>::max());
void AppendSubString(const char* appendText, s32 Offset = 0, s32 Count = std::numeric_limits<s32>::max());
// append formatted string to this string
void AppendFormattedString(const char* FormatString, ...);
void AppendFormattedStringVA(const char* FormatString, va_list ArgPtr);
// append a single character to this string
void PrependCharacter(char c);
// append a string to this string
void PrependString(const String& appendStr);
void PrependString(const char* appendText);
void PrependString(const char* appendString, u32 Count);
// append a substring of the specified string to this string
void PrependSubString(const String& appendStr, s32 Offset = 0, s32 Count = std::numeric_limits<s32>::max());
void PrependSubString(const char* appendText, s32 Offset = 0, s32 Count = std::numeric_limits<s32>::max());
// append formatted string to this string
void PrependFormattedString(const char* FormatString, ...);
void PrependFormattedStringVA(const char* FormatString, va_list ArgPtr);
// insert a string at the specified offset
void InsertString(s32 offset, const String& appendStr);
void InsertString(s32 offset, const char* appendStr);
void InsertString(s32 offset, const char* appendStr, u32 appendStrLength);
// set to formatted string
void Format(const char* FormatString, ...);
void FormatVA(const char* FormatString, va_list ArgPtr);
// compare one string to another
bool Compare(const String& otherString) const;
bool Compare(const char* otherText) const;
bool SubCompare(const String& otherString, u32 Length) const;
bool SubCompare(const char* otherText, u32 Length) const;
bool CompareInsensitive(const String& otherString) const;
bool CompareInsensitive(const char* otherText) const;
bool SubCompareInsensitive(const String& otherString, u32 Length) const;
bool SubCompareInsensitive(const char* otherText, u32 Length) const;
// numerical compares
int NumericCompare(const String& otherString) const;
int NumericCompare(const char* otherText) const;
int NumericCompareInsensitive(const String& otherString) const;
int NumericCompareInsensitive(const char* otherText) const;
// starts with / ends with
bool StartsWith(const char* compareString, bool caseSensitive = true) const;
bool StartsWith(const String& compareString, bool caseSensitive = true) const;
bool EndsWith(const char* compareString, bool caseSensitive = true) const;
bool EndsWith(const String& compareString, bool caseSensitive = true) const;
// searches for a character inside a string
// rfind is the same except it starts at the end instead of the start
// returns -1 if it is not found, otherwise the offset in the string
s32 Find(char c, u32 Offset = 0) const;
s32 RFind(char c, u32 Offset = 0) const;
// searches for a string inside a string
// rfind is the same except it starts at the end instead of the start
// returns -1 if it is not found, otherwise the offset in the string
s32 Find(const char* str, u32 Offset = 0) const;
// alters the length of the string to be at least len bytes long
void Reserve(u32 newReserve, bool Force = false);
// Cuts characters off the string to reduce it to len bytes long.
void Resize(u32 newSize, char fillerCharacter = ' ', bool skrinkIfSmaller = false);
// updates the internal length counter when the string is externally modified
void UpdateSize();
// shrink the string to the minimum size possible
void Shrink(bool Force = false);
// gets the size of the string
u32 GetLength() const { return m_pStringData->StringLength; }
bool IsEmpty() const { return (m_pStringData->StringLength == 0); }
// gets the maximum number of bytes we can write to the string, currently
u32 GetBufferSize() const { return m_pStringData->BufferSize; }
u32 GetWritableBufferSize()
{
EnsureOwnWritableCopy();
return m_pStringData->BufferSize;
}
// creates a new string using part of this string
String SubString(s32 Offset, s32 Count = std::numeric_limits<s32>::max()) const;
// erase count characters at offset from this string. if count is less than zero, everything past offset is erased
void Erase(s32 Offset, s32 Count = std::numeric_limits<s32>::max());
// replaces all instances of character c with character r in this string
// returns the number of changes
u32 Replace(char searchCharacter, char replaceCharacter);
// replaces all instances of string s with string r in this string
// returns the number of changes
u32 Replace(const char* searchString, const char* replaceString);
// convert string to lowercase
void ToLower();
// convert string to upper
void ToUpper();
// strip characters from start and end of the string
void LStrip(const char* szStripCharacters = " \t\r\n");
void RStrip(const char* szStripCharacters = " \t\r\n");
void Strip(const char* szStripCharacters = " \t\r\n");
// gets a constant pointer to the string
const char* GetCharArray() const { return m_pStringData->pBuffer; }
// gets a writable char array, do not write more than reserve characters to it.
char* GetWriteableCharArray()
{
EnsureOwnWritableCopy();
return m_pStringData->pBuffer;
}
// creates a new string from the specified format
static String FromFormat(const char* FormatString, ...);
// accessor operators
// const char &operator[](u32 i) const { DebugAssert(i < m_pStringData->StringLength); return
// m_pStringData->pBuffer[i]; } char &operator[](u32 i) { DebugAssert(i < m_pStringData->StringLength); return
// m_pStringData->pBuffer[i]; }
operator const char*() const { return GetCharArray(); }
operator char*() { return GetWriteableCharArray(); }
// Will use the string data provided.
String& operator=(const String& copyString)
{
Assign(copyString);
return *this;
}
// Allocates own buffer and copies text.
String& operator=(const char* Text)
{
Assign(Text);
return *this;
}
// Move operator.
String& operator=(String&& moveString)
{
Assign(moveString);
return *this;
}
// comparative operators
bool operator==(const String& compString) const { return Compare(compString); }
bool operator==(const char* compString) const { return Compare(compString); }
bool operator!=(const String& compString) const { return !Compare(compString); }
bool operator!=(const char* compString) const { return !Compare(compString); }
bool operator<(const String& compString) const { return (NumericCompare(compString) < 0); }
bool operator<(const char* compString) const { return (NumericCompare(compString) < 0); }
bool operator>(const String& compString) const { return (NumericCompare(compString) > 0); }
bool operator>(const char* compString) const { return (NumericCompare(compString) > 0); }
protected:
// Hidden constructor for creating string child classes.
// It does not increment the reference count on the string data, therefore dangerous to be public.
String(StringData* pStringData) : m_pStringData(pStringData) {}
// Internal append function.
void InternalPrepend(const char* pString, u32 Length);
void InternalAppend(const char* pString, u32 Length);
// Pointer to string data.
StringData* m_pStringData;
// Empty string data.
static const StringData s_EmptyStringData;
};
// static string, stored in .rodata
class StaticString : public String
{
public:
StaticString(const char* Text)
{
m_sStringData.pBuffer = const_cast<char*>(Text);
m_sStringData.StringLength = static_cast<u32>(std::strlen(Text));
m_sStringData.BufferSize = m_sStringData.StringLength + 1;
m_sStringData.ReadOnly = true;
m_sStringData.ReferenceCount = -1;
}
private:
StringData m_sStringData;
};
// stack-allocated string
template<u32 L>
class StackString : public String
{
public:
StackString() : String(&m_sStringData) { InitStackStringData(); }
StackString(const char* Text) : String(&m_sStringData)
{
InitStackStringData();
Assign(Text);
}
StackString(const String& copyString) : String(&m_sStringData)
{
// force a copy by passing it a string pointer, instead of a string object
InitStackStringData();
Assign(copyString.GetCharArray());
}
StackString(const StackString& copyString) : String(&m_sStringData)
{
// force a copy by passing it a string pointer, instead of a string object
InitStackStringData();
Assign(copyString.GetCharArray());
}
// Override the fromstring method
static StackString FromFormat(const char* FormatString, ...)
{
va_list argPtr;
va_start(argPtr, FormatString);
StackString returnValue;
returnValue.FormatVA(FormatString, argPtr);
va_end(argPtr);
return returnValue;
}
// Will use the string data provided.
StackString& operator=(const StackString& copyString)
{
Assign(copyString.GetCharArray());
return *this;
}
StackString& operator=(const String& copyString)
{
Assign(copyString.GetCharArray());
return *this;
}
// Allocates own buffer and copies text.
StackString& operator=(const char* Text)
{
Assign(Text);
return *this;
}
private:
StringData m_sStringData;
char m_strStackBuffer[L + 1];
inline void InitStackStringData()
{
m_sStringData.pBuffer = m_strStackBuffer;
m_sStringData.StringLength = 0;
m_sStringData.BufferSize = countof(m_strStackBuffer);
m_sStringData.ReadOnly = false;
m_sStringData.ReferenceCount = -1;
#ifdef _DEBUG
std::memset(m_strStackBuffer, 0, sizeof(m_strStackBuffer));
#else
m_strStackBuffer[0] = '\0';
#endif
}
};
// stack string types
typedef StackString<64> TinyString;
typedef StackString<256> SmallString;
typedef StackString<512> LargeString;
typedef StackString<512> PathString;
// empty string global
extern const String EmptyString;

140
src/common/string_util.cpp Normal file
View file

@ -0,0 +1,140 @@
#include "string_util.h"
#include <cstdio>
namespace StringUtil {
std::string StdStringFromFormat(const char* format, ...)
{
std::va_list ap;
va_start(ap, format);
std::string ret = StdStringFromFormatV(format, ap);
va_end(ap);
return ret;
}
std::string StdStringFromFormatV(const char* format, std::va_list ap)
{
#ifdef WIN32
int len = _vscprintf(format, ap);
#else
int len = std::vsnprintf(nullptr, 0, format, ap);
#endif
std::string ret;
ret.resize(len);
std::vsnprintf(ret.data(), ret.size() + 1, format, ap);
return ret;
}
bool WildcardMatch(const char* subject, const char* mask, bool case_sensitive /*= true*/)
{
if (case_sensitive)
{
const char* cp = nullptr;
const char* mp = nullptr;
while ((*subject) && (*mask != '*'))
{
if ((*mask != '?') && (std::tolower(*mask) != std::tolower(*subject)))
return false;
mask++;
subject++;
}
while (*subject)
{
if (*mask == '*')
{
if (*++mask == 0)
return true;
mp = mask;
cp = subject + 1;
}
else
{
if ((*mask == '?') || (std::tolower(*mask) == std::tolower(*subject)))
{
mask++;
subject++;
}
else
{
mask = mp;
subject = cp++;
}
}
}
while (*mask == '*')
{
mask++;
}
return *mask == 0;
}
else
{
const char* cp = nullptr;
const char* mp = nullptr;
while ((*subject) && (*mask != '*'))
{
if ((*mask != *subject) && (*mask != '?'))
return false;
mask++;
subject++;
}
while (*subject)
{
if (*mask == '*')
{
if (*++mask == 0)
return true;
mp = mask;
cp = subject + 1;
}
else
{
if ((*mask == *subject) || (*mask == '?'))
{
mask++;
subject++;
}
else
{
mask = mp;
subject = cp++;
}
}
}
while (*mask == '*')
{
mask++;
}
return *mask == 0;
}
}
std::size_t Strlcpy(char* dst, const char* src, std::size_t size)
{
std::size_t len = std::strlen(src);
if (len < size)
{
std::memcpy(dst, src, len + 1);
}
else
{
std::memcpy(dst, src, size - 1);
dst[size] = '\0';
}
return len;
}
} // namespace StringUtil

29
src/common/string_util.h Normal file
View file

@ -0,0 +1,29 @@
#pragma once
#include <cstddef>
#include <cstdarg>
#include <cstring>
#include <string>
namespace StringUtil {
/// Constructs a std::string from a format string.
std::string StdStringFromFormat(const char* format, ...);
std::string StdStringFromFormatV(const char* format, std::va_list ap);
/// Checks if a wildcard matches a search string.
bool WildcardMatch(const char* subject, const char* mask, bool case_sensitive = true);
/// Safe version of strlcpy.
std::size_t Strlcpy(char* dst, const char* src, std::size_t size);
/// Platform-independent strcasecmp
inline int Strcasecmp(const char* s1, const char* s2)
{
#ifdef _MSC_VER
return _stricmp(s1, s2);
#else
return strcasecmp(s1, s2);
#endif
}
} // namespace StringUtil

127
src/common/timer.cpp Normal file
View file

@ -0,0 +1,127 @@
#include "timer.h"
#ifdef WIN32
#include "windows_headers.h"
#else
#include <sys/time.h>
#include <time.h>
#endif
namespace Common {
#ifdef WIN32
static double s_counter_frequency;
static bool s_counter_initialized = false;
Timer::Value Timer::GetValue()
{
// even if this races, it should still result in the same value..
if (!s_counter_initialized)
{
LARGE_INTEGER Freq;
QueryPerformanceFrequency(&Freq);
s_counter_frequency = static_cast<double>(Freq.QuadPart) / 1000000000.0;
s_counter_initialized = true;
}
Timer::Value ReturnValue;
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&ReturnValue));
return ReturnValue;
}
double Timer::ConvertValueToNanoseconds(Timer::Value value)
{
return (static_cast<double>(value) / s_counter_frequency);
}
double Timer::ConvertValueToMilliseconds(Timer::Value value)
{
return ((static_cast<double>(value) / s_counter_frequency) / 1000000.0);
}
double Timer::ConvertValueToSeconds(Timer::Value value)
{
return ((static_cast<double>(value) / s_counter_frequency) / 1000000000.0);
}
#else
#if 1 // using clock_gettime()
Timer::Value Timer::GetValue()
{
struct timespec tv;
clock_gettime(CLOCK_MONOTONIC, &tv);
return ((Value)tv.tv_nsec + (Value)tv.tv_sec * 1000000000);
}
double Timer::ConvertValueToNanoseconds(Timer::Value value)
{
return static_cast<double>(value);
}
double Timer::ConvertValueToMilliseconds(Timer::Value value)
{
return (static_cast<double>(value) / 1000000.0);
}
double Timer::ConvertValueToSeconds(Timer::Value value)
{
return (static_cast<double>(value) / 1000000000.0);
}
#else // using gettimeofday()
Timer::Value Timer::GetValue()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return ((Value)tv.tv_usec) + ((Value)tv.tv_sec * (Value)1000000);
}
double Timer::ConvertValueToNanoseconds(Timer::Value value)
{
return ((double)value * 1000.0);
}
double Timer::ConvertValueToMilliseconds(Timer::Value value)
{
return ((double)value / 1000.0);
}
double Timer::ConvertValueToSeconds(Timer::Value value)
{
return ((double)value / 1000000.0);
}
#endif
#endif
Timer::Timer()
{
Reset();
}
void Timer::Reset()
{
m_tvStartValue = GetValue();
}
double Timer::GetTimeSeconds() const
{
return ConvertValueToSeconds(GetValue() - m_tvStartValue);
}
double Timer::GetTimeMilliseconds() const
{
return ConvertValueToMilliseconds(GetValue() - m_tvStartValue);
}
double Timer::GetTimeNanoseconds() const
{
return ConvertValueToNanoseconds(GetValue() - m_tvStartValue);
}
} // namespace Common

29
src/common/timer.h Normal file
View file

@ -0,0 +1,29 @@
#pragma once
#include "types.h"
#include <cstdint>
namespace Common {
class Timer
{
public:
using Value = u64;
Timer();
static Value GetValue();
static double ConvertValueToSeconds(Value value);
static double ConvertValueToMilliseconds(Value value);
static double ConvertValueToNanoseconds(Value value);
void Reset();
double GetTimeSeconds() const;
double GetTimeMilliseconds() const;
double GetTimeNanoseconds() const;
private:
Value m_tvStartValue;
};
} // namespace Common

518
src/common/timestamp.cpp Normal file
View file

@ -0,0 +1,518 @@
#include "timestamp.h"
#include <cstring>
#include <ctime>
#if defined(WIN32)
static void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst);
static time_t SystemTimeToUnixTime(const SYSTEMTIME* pst);
#endif
Timestamp::Timestamp()
{
#if defined(WIN32)
m_value.wYear = 1970;
m_value.wMonth = 1;
m_value.wDayOfWeek = 0;
m_value.wDay = 1;
m_value.wHour = 0;
m_value.wMinute = 0;
m_value.wSecond = 0;
m_value.wMilliseconds = 0;
#else
m_value.tv_sec = 0;
m_value.tv_usec = 0;
#endif
}
Timestamp::Timestamp(const Timestamp& copy)
{
#if defined(WIN32)
std::memcpy(&m_value, &copy.m_value, sizeof(m_value));
#else
std::memcpy(&m_value, &copy.m_value, sizeof(m_value));
#endif
}
double Timestamp::DifferenceInSeconds(Timestamp& other) const
{
#if defined(WIN32)
FILETIME lft, rft;
SystemTimeToFileTime(&m_value, &lft);
SystemTimeToFileTime(&other.m_value, &rft);
u64 lval = ((u64)lft.dwHighDateTime) << 32 | (u64)lft.dwLowDateTime;
u64 rval = ((u64)rft.dwHighDateTime) << 32 | (u64)rft.dwLowDateTime;
s64 diff = ((s64)lval - (s64)rval);
return double(diff / 10000000ULL) + (double(diff % 10000000ULL) / 10000000.0);
#else
return (double)(m_value.tv_sec - other.m_value.tv_sec) +
(((double)(m_value.tv_usec - other.m_value.tv_usec)) / 1000000.0);
#endif
}
s64 Timestamp::DifferenceInSecondsInt(Timestamp& other) const
{
#if defined(WIN32)
FILETIME lft, rft;
SystemTimeToFileTime(&m_value, &lft);
SystemTimeToFileTime(&other.m_value, &rft);
u64 lval = ((u64)lft.dwHighDateTime) << 32 | (u64)lft.dwLowDateTime;
u64 rval = ((u64)rft.dwHighDateTime) << 32 | (u64)rft.dwLowDateTime;
s64 diff = ((s64)lval - (s64)rval);
return diff / 10000000ULL;
#else
return static_cast<s64>(m_value.tv_sec - other.m_value.tv_sec);
#endif
}
Timestamp::UnixTimestampValue Timestamp::AsUnixTimestamp() const
{
#if defined(WIN32)
return (UnixTimestampValue)SystemTimeToUnixTime(&m_value);
#else
return (UnixTimestampValue)m_value.tv_sec;
#endif
}
Timestamp::ExpandedTime Timestamp::AsExpandedTime() const
{
ExpandedTime et;
#if defined(WIN32)
et.Year = m_value.wYear;
et.Month = m_value.wMonth;
et.DayOfMonth = m_value.wDay;
et.DayOfWeek = m_value.wDayOfWeek;
et.Hour = m_value.wHour;
et.Minute = m_value.wMinute;
et.Second = m_value.wSecond;
et.Milliseconds = m_value.wMilliseconds;
#else
struct tm t;
time_t unixTime = (time_t)m_value.tv_sec;
gmtime_r(&unixTime, &t);
et.Year = t.tm_year + 1900;
et.Month = t.tm_mon + 1;
et.DayOfMonth = t.tm_mday;
et.DayOfWeek = t.tm_wday;
et.Hour = t.tm_hour;
et.Minute = t.tm_min;
et.Second = t.tm_sec;
et.Milliseconds = m_value.tv_usec / 1000;
#endif
return et;
}
void Timestamp::SetNow()
{
#if defined(WIN32)
GetSystemTime(&m_value);
#else
gettimeofday(&m_value, NULL);
#endif
}
void Timestamp::SetUnixTimestamp(UnixTimestampValue value)
{
#if defined(WIN32)
UnixTimeToSystemTime((time_t)value, &m_value);
#else
m_value.tv_sec = (time_t)value;
m_value.tv_usec = 0;
#endif
}
void Timestamp::SetExpandedTime(const ExpandedTime& value)
{
#if defined(WIN32)
// bit of a hacky way to fill in the missing fields
SYSTEMTIME st;
st.wYear = (WORD)value.Year;
st.wMonth = (WORD)value.Month;
st.wDay = (WORD)value.DayOfMonth;
st.wDayOfWeek = (WORD)0;
st.wHour = (WORD)value.Hour;
st.wMinute = (WORD)value.Minute;
st.wSecond = (WORD)value.Second;
st.wMilliseconds = (WORD)value.Milliseconds;
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
FileTimeToSystemTime(&ft, &m_value);
#else
struct tm t;
std::memset(&t, 0, sizeof(t));
t.tm_sec = value.Second;
t.tm_min = value.Minute;
t.tm_hour = value.Hour;
t.tm_mday = value.DayOfMonth;
t.tm_mon = value.Month - 1;
t.tm_year = value.Year - 1900;
time_t unixTime = mktime(&t);
SetUnixTimestamp((UnixTimestampValue)unixTime);
#endif
}
String Timestamp::ToString(const char* format) const
{
SmallString destination;
ToString(destination, format);
return String(destination);
}
void Timestamp::ToString(String& destination, const char* format) const
{
time_t unixTime = (time_t)AsUnixTimestamp();
tm localTime;
#if defined(WIN32)
localtime_s(&localTime, &unixTime);
#else
localtime_r(&unixTime, &localTime);
#endif
char buffer[256];
strftime(buffer, countof(buffer) - 1, format, &localTime);
buffer[countof(buffer) - 1] = 0;
destination.Clear();
destination.AppendString(buffer);
}
Timestamp Timestamp::Now()
{
Timestamp t;
t.SetNow();
return t;
}
Timestamp Timestamp::FromUnixTimestamp(UnixTimestampValue value)
{
Timestamp t;
t.SetUnixTimestamp(value);
return t;
}
Timestamp Timestamp::FromExpandedTime(const ExpandedTime& value)
{
Timestamp t;
t.SetExpandedTime(value);
return t;
}
bool Timestamp::operator==(const Timestamp& other) const
{
#if defined(WIN32)
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) == 0;
#else
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) == 0;
#endif
}
bool Timestamp::operator!=(const Timestamp& other) const
{
#if defined(WIN32)
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) != 0;
#else
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) != 0;
#endif
}
bool Timestamp::operator<(const Timestamp& other) const
{
#if defined(WIN32)
if (m_value.wYear > other.m_value.wYear)
return false;
else if (m_value.wYear < other.m_value.wYear)
return true;
if (m_value.wMonth > other.m_value.wMonth)
return false;
else if (m_value.wMonth < other.m_value.wMonth)
return true;
if (m_value.wDay > other.m_value.wDay)
return false;
else if (m_value.wDay < other.m_value.wDay)
return true;
if (m_value.wHour > other.m_value.wHour)
return false;
else if (m_value.wHour < other.m_value.wHour)
return true;
if (m_value.wMinute > other.m_value.wMinute)
return false;
else if (m_value.wMinute < other.m_value.wMinute)
return true;
if (m_value.wHour > other.m_value.wHour)
return false;
else if (m_value.wHour < other.m_value.wHour)
return true;
if (m_value.wSecond > other.m_value.wSecond)
return false;
else if (m_value.wSecond < other.m_value.wSecond)
return true;
return false;
#else
if (m_value.tv_sec > other.m_value.tv_sec)
return false;
else if (m_value.tv_sec < other.m_value.tv_sec)
return true;
if (m_value.tv_usec > other.m_value.tv_usec)
return false;
else if (m_value.tv_usec < other.m_value.tv_usec)
return true;
return false;
#endif
}
bool Timestamp::operator<=(const Timestamp& other) const
{
#if defined(WIN32)
if (m_value.wYear > other.m_value.wYear)
return false;
else if (m_value.wYear < other.m_value.wYear)
return true;
if (m_value.wMonth > other.m_value.wMonth)
return false;
else if (m_value.wMonth < other.m_value.wMonth)
return true;
if (m_value.wDay > other.m_value.wDay)
return false;
else if (m_value.wDay < other.m_value.wDay)
return true;
if (m_value.wHour > other.m_value.wHour)
return false;
else if (m_value.wHour < other.m_value.wHour)
return true;
if (m_value.wMinute > other.m_value.wMinute)
return false;
else if (m_value.wMinute < other.m_value.wMinute)
return true;
if (m_value.wHour > other.m_value.wHour)
return false;
else if (m_value.wHour < other.m_value.wHour)
return true;
if (m_value.wSecond > other.m_value.wSecond)
return false;
else if (m_value.wSecond <= other.m_value.wSecond)
return true;
return false;
#else
if (m_value.tv_sec > other.m_value.tv_sec)
return false;
else if (m_value.tv_sec < other.m_value.tv_sec)
return true;
if (m_value.tv_usec > other.m_value.tv_usec)
return false;
else if (m_value.tv_usec <= other.m_value.tv_usec)
return true;
return false;
#endif
}
bool Timestamp::operator>(const Timestamp& other) const
{
#if defined(WIN32)
if (m_value.wYear < other.m_value.wYear)
return false;
else if (m_value.wYear > other.m_value.wYear)
return true;
if (m_value.wMonth < other.m_value.wMonth)
return false;
else if (m_value.wMonth > other.m_value.wMonth)
return true;
if (m_value.wDay < other.m_value.wDay)
return false;
else if (m_value.wDay > other.m_value.wDay)
return true;
if (m_value.wHour < other.m_value.wHour)
return false;
else if (m_value.wHour > other.m_value.wHour)
return true;
if (m_value.wMinute < other.m_value.wMinute)
return false;
else if (m_value.wMinute > other.m_value.wMinute)
return true;
if (m_value.wHour < other.m_value.wHour)
return false;
else if (m_value.wHour > other.m_value.wHour)
return true;
if (m_value.wSecond < other.m_value.wSecond)
return false;
else if (m_value.wSecond > other.m_value.wSecond)
return true;
return false;
#else
if (m_value.tv_sec < other.m_value.tv_sec)
return false;
else if (m_value.tv_sec > other.m_value.tv_sec)
return true;
if (m_value.tv_usec < other.m_value.tv_usec)
return false;
else if (m_value.tv_usec > other.m_value.tv_usec)
return true;
return false;
#endif
}
bool Timestamp::operator>=(const Timestamp& other) const
{
#if defined(WIN32)
if (m_value.wYear < other.m_value.wYear)
return false;
else if (m_value.wYear > other.m_value.wYear)
return true;
if (m_value.wMonth < other.m_value.wMonth)
return false;
else if (m_value.wMonth > other.m_value.wMonth)
return true;
if (m_value.wDay < other.m_value.wDay)
return false;
else if (m_value.wDay > other.m_value.wDay)
return true;
if (m_value.wHour < other.m_value.wHour)
return false;
else if (m_value.wHour > other.m_value.wHour)
return true;
if (m_value.wMinute < other.m_value.wMinute)
return false;
else if (m_value.wMinute > other.m_value.wMinute)
return true;
if (m_value.wHour < other.m_value.wHour)
return false;
else if (m_value.wHour > other.m_value.wHour)
return true;
if (m_value.wSecond < other.m_value.wSecond)
return false;
else if (m_value.wSecond >= other.m_value.wSecond)
return true;
return false;
#else
if (m_value.tv_sec < other.m_value.tv_sec)
return false;
else if (m_value.tv_sec > other.m_value.tv_sec)
return true;
if (m_value.tv_usec < other.m_value.tv_usec)
return false;
else if (m_value.tv_usec >= other.m_value.tv_usec)
return true;
return false;
#endif
}
Timestamp& Timestamp::operator=(const Timestamp& other)
{
#if defined(WIN32)
std::memcpy(&m_value, &other.m_value, sizeof(m_value));
#else
std::memcpy(&m_value, &other.m_value, sizeof(m_value));
#endif
return *this;
}
#if defined(WIN32)
// http://support.microsoft.com/kb/167296
static void UnixTimeToFileTime(time_t t, LPFILETIME pft)
{
LONGLONG ll;
ll = Int32x32To64(t, 10000000ULL) + 116444736000000000ULL;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
static void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst)
{
FILETIME ft;
UnixTimeToFileTime(t, &ft);
FileTimeToSystemTime(&ft, pst);
}
static time_t FileTimeToUnixTime(const FILETIME* pft)
{
LONGLONG ll = ((LONGLONG)pft->dwHighDateTime) << 32 | (LONGLONG)pft->dwLowDateTime;
ll -= 116444736000000000ULL;
ll /= 10000000ULL;
return (time_t)ll;
}
static time_t SystemTimeToUnixTime(const SYSTEMTIME* pst)
{
FILETIME ft;
SystemTimeToFileTime(pst, &ft);
return FileTimeToUnixTime(&ft);
}
FILETIME Timestamp::AsFileTime()
{
FILETIME ft;
SystemTimeToFileTime(&m_value, &ft);
return ft;
}
void Timestamp::SetWindowsFileTime(const FILETIME* pFileTime)
{
FileTimeToSystemTime(pFileTime, &m_value);
}
Timestamp Timestamp::FromWindowsFileTime(const FILETIME* pFileTime)
{
Timestamp ts;
ts.SetWindowsFileTime(pFileTime);
return ts;
}
#endif

75
src/common/timestamp.h Normal file
View file

@ -0,0 +1,75 @@
#pragma once
#include "types.h"
#include "string.h"
#if defined(WIN32)
#include "windows_headers.h"
#else
#include <sys/time.h>
#endif
class Timestamp
{
public:
using UnixTimestampValue = u64;
struct ExpandedTime
{
u32 Year; // 0-...
u32 Month; // 1-12
u32 DayOfMonth; // 1-31
u32 DayOfWeek; // 0-6, starting at Sunday
u32 Hour; // 0-23
u32 Minute; // 0-59
u32 Second; // 0-59
u32 Milliseconds; // 0-999
};
public:
Timestamp();
Timestamp(const Timestamp& copy);
// readers
UnixTimestampValue AsUnixTimestamp() const;
ExpandedTime AsExpandedTime() const;
// calculators
double DifferenceInSeconds(Timestamp& other) const;
s64 DifferenceInSecondsInt(Timestamp& other) const;
// setters
void SetNow();
void SetUnixTimestamp(UnixTimestampValue value);
void SetExpandedTime(const ExpandedTime& value);
// string conversion
String ToString(const char* format) const;
void ToString(String& destination, const char* format) const;
// creators
static Timestamp Now();
static Timestamp FromUnixTimestamp(UnixTimestampValue value);
static Timestamp FromExpandedTime(const ExpandedTime& value);
// windows-specific
#ifdef WIN32
FILETIME AsFileTime();
void SetWindowsFileTime(const FILETIME* pFileTime);
static Timestamp FromWindowsFileTime(const FILETIME* pFileTime);
#endif
// operators
bool operator==(const Timestamp& other) const;
bool operator!=(const Timestamp& other) const;
bool operator<(const Timestamp& other) const;
bool operator<=(const Timestamp& other) const;
bool operator>(const Timestamp& other) const;
bool operator>=(const Timestamp& other) const;
Timestamp& operator=(const Timestamp& other);
private:
#if defined(WIN32)
SYSTEMTIME m_value;
#else
struct timeval m_value;
#endif
};

View file

@ -1,8 +1,7 @@
#pragma once
#include "YBaseLib/Common.h"
#include <cstdint>
#include <cstring>
#include <limits>
#include <type_traits>
// Force inline helper
@ -16,6 +15,41 @@
#endif
#endif
// unreferenced parameter macro
#ifndef UNREFERENCED_VARIABLE
#if defined(_MSC_VER)
#define UNREFERENCED_VARIABLE(P) (P)
#elif defined(__GNUC__) || defined(__clang__) || defined(__EMSCRIPTEN__)
#define UNREFERENCED_VARIABLE(P) (void)(P)
#else
#define UNREFERENCED_VARIABLE(P) (P)
#endif
#endif
// countof macro
#ifndef countof
#ifdef _countof
#define countof _countof
#else
template<typename T, size_t N>
char (&__countof_ArraySizeHelper(T (&array)[N]))[N];
#define countof(array) (sizeof(__countof_ArraySizeHelper(array)))
#endif
#endif
// offsetof macro
#ifndef offsetof
#define offsetof(st, m) ((size_t)((char*)&((st*)(0))->m - (char*)0))
#endif
// disable warnings that show up at warning level 4
// TODO: Move to build system instead
#ifdef _MSC_VER
#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union
#pragma warning(disable : 4100) // warning C4100: 'Platform' : unreferenced formal parameter
#pragma warning(disable : 4355) // warning C4355: 'this' : used in base member initializer list
#endif
using s8 = int8_t;
using u8 = uint8_t;
using s16 = int16_t;
@ -202,38 +236,38 @@ ALWAYS_INLINE constexpr T SignExtendN(T value)
// Enum class bitwise operators
#define IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(type_) \
ALWAYS_INLINE constexpr type_ operator&(type_ lhs, type_ rhs) \
ALWAYS_INLINE constexpr type_ operator&(type_ lhs, type_ rhs) \
{ \
return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) & \
static_cast<std::underlying_type<type_>::type>(rhs)); \
} \
ALWAYS_INLINE constexpr type_ operator|(type_ lhs, type_ rhs) \
ALWAYS_INLINE constexpr type_ operator|(type_ lhs, type_ rhs) \
{ \
return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) | \
static_cast<std::underlying_type<type_>::type>(rhs)); \
} \
ALWAYS_INLINE constexpr type_ operator^(type_ lhs, type_ rhs) \
ALWAYS_INLINE constexpr type_ operator^(type_ lhs, type_ rhs) \
{ \
return static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) ^ \
static_cast<std::underlying_type<type_>::type>(rhs)); \
} \
ALWAYS_INLINE constexpr type_ operator~(type_ val) \
ALWAYS_INLINE constexpr type_ operator~(type_ val) \
{ \
return static_cast<type_>(~static_cast<std::underlying_type<type_>::type>(val)); \
} \
ALWAYS_INLINE constexpr type_& operator&=(type_& lhs, type_ rhs) \
ALWAYS_INLINE constexpr type_& operator&=(type_& lhs, type_ rhs) \
{ \
lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) & \
static_cast<std::underlying_type<type_>::type>(rhs)); \
return lhs; \
} \
ALWAYS_INLINE constexpr type_& operator|=(type_& lhs, type_ rhs) \
ALWAYS_INLINE constexpr type_& operator|=(type_& lhs, type_ rhs) \
{ \
lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) | \
static_cast<std::underlying_type<type_>::type>(rhs)); \
return lhs; \
} \
ALWAYS_INLINE constexpr type_& operator^=(type_& lhs, type_ rhs) \
ALWAYS_INLINE constexpr type_& operator^=(type_& lhs, type_ rhs) \
{ \
lhs = static_cast<type_>(static_cast<std::underlying_type<type_>::type>(lhs) ^ \
static_cast<std::underlying_type<type_>::type>(rhs)); \

View file

@ -0,0 +1,39 @@
#pragma once
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#ifndef NOMINMAX
#define NOMINMAX 1
#endif
// require vista+
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <windows.h>
// hurr i'm windows, i like to conflict, fixme properly later please...
#if defined(FindTexture)
#undef FindTexture
#endif
#if defined(DrawText)
#undef DrawText
#endif
#if defined(CreateDirectory)
#undef CreateDirectory
#endif
#if defined(CopyFile)
#undef CopyFile
#endif
#if defined(DeleteFile)
#undef DeleteFile
#endif
#if defined(Yield)
#undef Yield
#endif
#if defined(LoadIcon)
#undef LoadIcon
#endif

View file

@ -79,7 +79,7 @@ set(RECOMPILER_SRCS
target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_link_libraries(core PUBLIC Threads::Threads YBaseLib common imgui tinyxml2)
target_link_libraries(core PUBLIC Threads::Threads common imgui tinyxml2)
target_link_libraries(core PRIVATE glad stb)
if(WIN32)

View file

@ -1,5 +1,5 @@
#include "analog_controller.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/state_wrapper.h"
Log_SetChannel(AnalogController);
@ -133,7 +133,7 @@ void AnalogController::SetMotorState(u8 motor, u8 value)
bool AnalogController::Transfer(const u8 data_in, u8* data_out)
{
bool ack;
#ifdef Y_BUILD_CONFIG_DEBUG
#ifdef _DEBUG
u8 old_state = static_cast<u8>(m_state);
#endif

View file

@ -1,6 +1,7 @@
#include "bios.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/MD5Digest.h"
#include "common/log.h"
#include "common/assert.h"
#include "common/md5_digest.h"
#include "cpu_disasm.h"
#include <cerrno>
Log_SetChannel(BIOS);

View file

@ -1,9 +1,8 @@
#include "bus.h"
#include "YBaseLib/ByteStream.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/MD5Digest.h"
#include "YBaseLib/String.h"
#include "cdrom.h"
#include "common/align.h"
#include "common/assert.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "cpu_code_cache.h"
#include "cpu_core.h"
@ -344,19 +343,19 @@ void Bus::DoWriteEXP2(MemoryAccessSize size, u32 offset, u32 value)
if (value == '\n')
{
if (!m_tty_line_buffer.IsEmpty())
if (!m_tty_line_buffer.empty())
{
Log_InfoPrintf("TTY: %s", m_tty_line_buffer.GetCharArray());
Log_InfoPrintf("TTY: %s", m_tty_line_buffer.c_str());
#ifdef _DEBUG
if (CPU::LOG_EXECUTION)
CPU::WriteToExecutionLog("TTY: %s\n", m_tty_line_buffer.GetCharArray());
CPU::WriteToExecutionLog("TTY: %s\n", m_tty_line_buffer.c_str());
#endif
}
m_tty_line_buffer.Clear();
m_tty_line_buffer.clear();
}
else
{
m_tty_line_buffer.AppendCharacter(Truncate8(value));
m_tty_line_buffer += static_cast<char>(Truncate8(value));
}
return;

View file

@ -1,10 +1,9 @@
#pragma once
#include "YBaseLib/String.h"
#include "common/bitfield.h"
#include "types.h"
#include <array>
#include <bitset>
#include <string>
#include <vector>
class StateWrapper;
@ -270,7 +269,7 @@ private:
MEMCTRL m_MEMCTRL = {};
u32 m_ram_size_reg = 0;
String m_tty_line_buffer;
std::string m_tty_line_buffer;
};
#include "bus.inl"

View file

@ -1,5 +1,5 @@
#include "cdrom.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/cd_image.h"
#include "common/state_wrapper.h"
#include "dma.h"
@ -1421,7 +1421,7 @@ static void ResampleXAADPCM(const s16* samples_in, u32 num_samples_in, SPU* spu,
if constexpr (!STEREO)
{
UNREFERENCED_PARAMETER(right);
UNREFERENCED_VARIABLE(right);
}
for (u32 sample_dup = 0; sample_dup < (SAMPLE_RATE ? 2 : 1); sample_dup++)

View file

@ -129,9 +129,6 @@
<ProjectReference Include="..\..\dep\tinyxml2\tinyxml2.vcxproj">
<Project>{933118a9-68c5-47b4-b151-b03c93961623}</Project>
</ProjectReference>
<ProjectReference Include="..\..\dep\YBaseLib\Source\YBaseLib.vcxproj">
<Project>{b56ce698-7300-4fa5-9609-942f1d05c5a2}</Project>
</ProjectReference>
<ProjectReference Include="..\common\common.vcxproj">
<Project>{ee054e08-3799-4a59-a422-18259c105ffd}</Project>
</ProjectReference>
@ -284,7 +281,7 @@
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -306,7 +303,7 @@
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -328,7 +325,7 @@
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
@ -353,7 +350,7 @@
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
@ -377,7 +374,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -400,7 +397,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -424,7 +421,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -447,7 +444,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_RECOMPILER=1;TINYXML2_IMPORT;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>

View file

@ -1,5 +1,5 @@
#include "cpu_code_cache.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "cpu_core.h"
#include "cpu_disasm.h"
#include "system.h"

View file

@ -1,6 +1,7 @@
#include "cpu_core.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "common/align.h"
#include "cpu_disasm.h"
#include <cstdio>
Log_SetChannel(CPU::Core);

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/Assert.h"
#include "common/align.h"
#include "bus.h"
#include "cpu_core.h"

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/String.h"
#include "common/string.h"
#include "cpu_types.h"
namespace CPU {

View file

@ -1,5 +1,5 @@
#include "cpu_recompiler_code_generator.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "cpu_core.h"
#include "cpu_disasm.h"
Log_SetChannel(CPU::Recompiler);
@ -12,7 +12,7 @@ namespace CPU::Recompiler {
u32 CodeGenerator::CalculateRegisterOffset(Reg reg)
{
return uint32(offsetof(Core, m_regs.r[0]) + (static_cast<u32>(reg) * sizeof(u32)));
return u32(offsetof(Core, m_regs.r[0]) + (static_cast<u32>(reg) * sizeof(u32)));
}
bool CodeGenerator::CompileBlock(const CodeBlock* block, CodeBlock::HostCodePointer* out_host_code,
@ -837,7 +837,7 @@ void CodeGenerator::BlockPrologue()
void CodeGenerator::BlockEpilogue()
{
#if defined(_DEBUG) && defined(Y_CPU_X64)
#if defined(_DEBUG) && defined(CPU_X64)
m_emit->nop();
#endif
@ -851,7 +851,7 @@ void CodeGenerator::BlockEpilogue()
void CodeGenerator::InstructionPrologue(const CodeBlockInstruction& cbi, TickCount cycles,
bool force_sync /* = false */)
{
#if defined(_DEBUG) && defined(Y_CPU_X64)
#if defined(_DEBUG) && defined(CPU_X64)
m_emit->nop();
#endif

View file

@ -11,17 +11,6 @@
#include "cpu_recompiler_types.h"
#include "cpu_types.h"
// ABI selection
#if defined(Y_CPU_X64)
#if defined(Y_PLATFORM_WINDOWS)
#define ABI_WIN64 1
#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_OSX) || defined(Y_PLATFORM_ANDROID)
#define ABI_SYSV 1
#else
#error Unknown ABI.
#endif
#endif
namespace CPU::Recompiler {
class CodeGenerator

View file

@ -1,4 +1,4 @@
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "cpu_recompiler_code_generator.h"
#include "cpu_recompiler_thunks.h"
#include "cpu_core.h"

View file

@ -1,5 +1,5 @@
#include "cpu_recompiler_register_cache.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "cpu_recompiler_code_generator.h"
#include <cinttypes>
Log_SetChannel(CPU::Recompiler);

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/Assert.h"
#include "common/assert.h"
#include "cpu_recompiler_types.h"
#include "cpu_types.h"

View file

@ -1,12 +1,22 @@
#pragma once
#include "common/cpu_detect.h"
#include "cpu_types.h"
#if defined(Y_CPU_X64)
#if defined(CPU_X64)
// We need to include windows.h before xbyak does..
#ifdef WIN32
#include "common/windows_headers.h"
#endif
#define XBYAK_NO_OP_NAMES 1
#include "xbyak.h"
#elif defined(Y_CPU_AARCH64)
#elif defined(CPU_AARCH64)
#include <vixl/aarch64/constants-aarch64.h>
#include <vixl/aarch64/macro-assembler-aarch64.h>
#endif
namespace CPU {
@ -48,7 +58,7 @@ enum class Condition : u8
Zero
};
#if defined(Y_CPU_X64)
#if defined(CPU_X64)
using HostReg = Xbyak::Operand::Code;
using CodeEmitter = Xbyak::CodeGenerator;
@ -67,14 +77,23 @@ constexpr u32 MAX_FAR_HOST_BYTES_PER_INSTRUCTION = 128;
// Are shifts implicitly masked to 0..31?
constexpr bool SHIFTS_ARE_IMPLICITLY_MASKED = true;
#elif defined(Y_CPU_AARCH64)
// ABI selection
#if defined(WIN32)
#define ABI_WIN64 1
#elif defined(__linux__) || defined(__ANDROID__)
#define ABI_SYSV 1
#else
#error Unknown ABI.
#endif
#elif defined(CPU_AARCH64)
using HostReg = unsigned;
using CodeEmitter = vixl::aarch64::MacroAssembler;
using LabelType = vixl::aarch64::Label;
enum : u32
{
HostReg_Count = vixl::aarch64::kNumberOfRegisters
HostReg_Count = vixl::aarch64::kNumberOfRegisters
};
constexpr HostReg HostReg_Invalid = static_cast<HostReg>(HostReg_Count);
constexpr RegSize HostPointerSize = RegSize_64;

View file

@ -1,5 +1,5 @@
#include "cpu_types.h"
#include "YBaseLib/Assert.h"
#include "common/assert.h"
#include <array>
namespace CPU {

View file

@ -1,5 +1,5 @@
#include "digital_controller.h"
#include "YBaseLib/Assert.h"
#include "common/assert.h"
DigitalController::DigitalController() = default;

View file

@ -1,5 +1,5 @@
#include "dma.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "bus.h"
#include "cdrom.h"
#include "common/state_wrapper.h"

View file

@ -1,13 +1,12 @@
#include "game_list.h"
#include "YBaseLib/AutoReleasePtr.h"
#include "YBaseLib/BinaryReader.h"
#include "YBaseLib/BinaryWriter.h"
#include "YBaseLib/ByteStream.h"
#include "YBaseLib/FileSystem.h"
#include "YBaseLib/Log.h"
#include "bios.h"
#include "common/assert.h"
#include "common/byte_stream.h"
#include "common/cd_image.h"
#include "common/file_system.h"
#include "common/iso_reader.h"
#include "common/log.h"
#include "common/string_util.h"
#include "settings.h"
#include <algorithm>
#include <array>
@ -17,12 +16,6 @@
#include <utility>
Log_SetChannel(GameList);
#ifdef _MSC_VER
#define CASE_COMPARE _stricmp
#else
#define CASE_COMPARE strcasecmp
#endif
GameList::GameList() = default;
GameList::~GameList() = default;
@ -91,7 +84,7 @@ std::string GameList::GetGameCodeForImage(CDImage* cdi)
// Find the BOOT line
auto iter = std::find_if(lines.begin(), lines.end(),
[](const auto& it) { return CASE_COMPARE(it.first.c_str(), "boot") == 0; });
[](const auto& it) { return StringUtil::Strcasecmp(it.first.c_str(), "boot") == 0; });
if (iter == lines.end())
return {};
@ -203,7 +196,8 @@ std::optional<ConsoleRegion> GameList::GetRegionForPath(const char* image_path)
bool GameList::IsExeFileName(const char* path)
{
const char* extension = std::strrchr(path, '.');
return (extension && (CASE_COMPARE(extension, ".exe") == 0 || CASE_COMPARE(extension, ".psexe") == 0));
return (extension &&
(StringUtil::Strcasecmp(extension, ".exe") == 0 || StringUtil::Strcasecmp(extension, ".psexe") == 0));
}
static std::string_view GetFileNameFromPath(const char* path)
@ -340,45 +334,93 @@ void GameList::LoadCache()
if (m_cache_filename.empty())
return;
ByteStream* stream = FileSystem::OpenFile(m_cache_filename.c_str(), BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
std::unique_ptr<ByteStream> stream =
FileSystem::OpenFile(m_cache_filename.c_str(), BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
if (!stream)
return;
if (!LoadEntriesFromCache(stream))
if (!LoadEntriesFromCache(stream.get()))
{
Log_WarningPrintf("Deleting corrupted cache file '%s'", m_cache_filename.c_str());
stream->Release();
stream.reset();
m_cache_map.clear();
DeleteCacheFile();
return;
}
}
stream->Release();
static bool ReadString(ByteStream* stream, std::string* dest)
{
u32 size;
if (!stream->Read2(&size, sizeof(size)))
return false;
dest->resize(size);
if (!stream->Read2(dest->data(), size))
return false;
return true;
}
static bool ReadU8(ByteStream* stream, u8* dest)
{
return stream->Read2(dest, sizeof(u8));
}
static bool ReadU32(ByteStream* stream, u32* dest)
{
return stream->Read2(dest, sizeof(u32));
}
static bool ReadU64(ByteStream* stream, u64* dest)
{
return stream->Read2(dest, sizeof(u64));
}
static bool WriteString(ByteStream* stream, const std::string& str)
{
const u32 size = static_cast<u32>(str.size());
return (stream->Write2(&size, sizeof(size)) && (size == 0 || stream->Write2(str.data(), size)));
}
static bool WriteU8(ByteStream* stream, u8 dest)
{
return stream->Write2(&dest, sizeof(u8));
}
static bool WriteU32(ByteStream* stream, u32 dest)
{
return stream->Write2(&dest, sizeof(u32));
}
static bool WriteU64(ByteStream* stream, u64 dest)
{
return stream->Write2(&dest, sizeof(u64));
}
bool GameList::LoadEntriesFromCache(ByteStream* stream)
{
BinaryReader reader(stream);
if (reader.ReadUInt32() != GAME_LIST_CACHE_SIGNATURE || reader.ReadUInt32() != GAME_LIST_CACHE_VERSION)
u32 file_signature, file_version;
if (!ReadU32(stream, &file_signature) || !ReadU32(stream, &file_version) ||
file_signature != GAME_LIST_CACHE_SIGNATURE || file_version != GAME_LIST_CACHE_VERSION)
{
Log_WarningPrintf("Game list cache is corrupted");
return false;
}
String path;
TinyString code;
SmallString title;
u64 total_size;
u64 last_modified_time;
u8 region;
u8 type;
while (stream->GetPosition() != stream->GetSize())
{
if (!reader.SafeReadSizePrefixedString(&path) || !reader.SafeReadSizePrefixedString(&code) ||
!reader.SafeReadSizePrefixedString(&title) || !reader.SafeReadUInt64(&total_size) ||
!reader.SafeReadUInt64(&last_modified_time) || !reader.SafeReadUInt8(&region) ||
region >= static_cast<u8>(ConsoleRegion::Count) || !reader.SafeReadUInt8(&type) ||
std::string path;
std::string code;
std::string title;
u64 total_size;
u64 last_modified_time;
u8 region;
u8 type;
if (!ReadString(stream, &path) || !ReadString(stream, &code) || !ReadString(stream, &title) ||
!ReadU64(stream, &total_size) || !ReadU64(stream, &last_modified_time) || !ReadU8(stream, &region) ||
region >= static_cast<u8>(ConsoleRegion::Count) || !ReadU8(stream, &type) ||
type > static_cast<u8>(EntryType::PSExe))
{
Log_WarningPrintf("Game list cache entry is corrupted");
@ -386,9 +428,9 @@ bool GameList::LoadEntriesFromCache(ByteStream* stream)
}
GameListEntry ge;
ge.path = path;
ge.code = code;
ge.title = title;
ge.path = std::move(path);
ge.code = std::move(code);
ge.title = std::move(title);
ge.total_size = total_size;
ge.last_modified_time = last_modified_time;
ge.region = static_cast<ConsoleRegion>(region);
@ -419,12 +461,11 @@ bool GameList::OpenCacheForWriting()
if (m_cache_write_stream->GetPosition() == 0)
{
// new cache file, write header
BinaryWriter writer(m_cache_write_stream);
if (!writer.SafeWriteUInt32(GAME_LIST_CACHE_SIGNATURE) || !writer.SafeWriteUInt32(GAME_LIST_CACHE_VERSION))
if (!WriteU32(m_cache_write_stream.get(), GAME_LIST_CACHE_SIGNATURE) ||
!WriteU32(m_cache_write_stream.get(), GAME_LIST_CACHE_VERSION))
{
Log_ErrorPrintf("Failed to write game list cache header");
m_cache_write_stream->Release();
m_cache_write_stream = nullptr;
m_cache_write_stream.reset();
FileSystem::DeleteFile(m_cache_filename.c_str());
return false;
}
@ -435,14 +476,13 @@ bool GameList::OpenCacheForWriting()
bool GameList::WriteEntryToCache(const GameListEntry* entry, ByteStream* stream)
{
BinaryWriter writer(stream);
bool result = writer.SafeWriteSizePrefixedString(entry->path.c_str());
result &= writer.SafeWriteSizePrefixedString(entry->code.c_str());
result &= writer.SafeWriteSizePrefixedString(entry->title.c_str());
result &= writer.SafeWriteUInt64(entry->total_size);
result &= writer.SafeWriteUInt64(entry->last_modified_time);
result &= writer.SafeWriteUInt8(static_cast<u8>(entry->region));
result &= writer.SafeWriteUInt8(static_cast<u8>(entry->type));
bool result = WriteString(stream, entry->path);
result &= WriteString(stream, entry->code);
result &= WriteString(stream, entry->title);
result &= WriteU64(stream, entry->total_size);
result &= WriteU64(stream, entry->last_modified_time);
result &= WriteU8(stream, static_cast<u8>(entry->region));
result &= WriteU8(stream, static_cast<u8>(entry->type));
return result;
}
@ -452,8 +492,7 @@ void GameList::CloseCacheFileStream()
return;
m_cache_write_stream->Commit();
m_cache_write_stream->Release();
m_cache_write_stream = nullptr;
m_cache_write_stream.reset();
}
void GameList::DeleteCacheFile()
@ -479,14 +518,14 @@ void GameList::ScanDirectory(const char* path, bool recursive)
for (const FILESYSTEM_FIND_DATA& ffd : files)
{
// if this is a .bin, check if we have a .cue. if there is one, skip it
const char* extension = std::strrchr(ffd.FileName, '.');
if (extension && CASE_COMPARE(extension, ".bin") == 0)
const char* extension = std::strrchr(ffd.FileName.c_str(), '.');
if (extension && StringUtil::Strcasecmp(extension, ".bin") == 0)
{
#if 0
std::string temp(ffd.FileName, extension - ffd.FileName);
temp += ".cue";
if (std::any_of(files.begin(), files.end(),
[&temp](const FILESYSTEM_FIND_DATA& it) { return CASE_COMPARE(it.FileName, temp.c_str()) == 0; }))
[&temp](const FILESYSTEM_FIND_DATA& it) { return StringUtil::Strcasecmp(it.FileName, temp.c_str()) == 0; }))
{
Log_DebugPrintf("Skipping due to '%s' existing", temp.c_str());
continue;
@ -512,7 +551,7 @@ void GameList::ScanDirectory(const char* path, bool recursive)
{
if (m_cache_write_stream || OpenCacheForWriting())
{
if (!WriteEntryToCache(&entry, m_cache_write_stream))
if (!WriteEntryToCache(&entry, m_cache_write_stream.get()))
Log_WarningPrintf("Failed to write entry '%s' to cache", entry.path.c_str());
}
}
@ -554,10 +593,10 @@ public:
bool VisitEnter(const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute* firstAttribute) override
{
// recurse into gamelist
if (CASE_COMPARE(element.Name(), "datafile") == 0)
if (StringUtil::Strcasecmp(element.Name(), "datafile") == 0)
return true;
if (CASE_COMPARE(element.Name(), "game") != 0)
if (StringUtil::Strcasecmp(element.Name(), "game") != 0)
return false;
const char* name = element.Attribute("name");

View file

@ -1,5 +1,6 @@
#pragma once
#include "types.h"
#include <memory>
#include <optional>
#include <string>
#include <string_view>
@ -48,6 +49,9 @@ public:
static const char* EntryTypeToString(EntryType type);
/// Returns true if the filename is a PlayStation executable we can inject.
static bool IsExeFileName(const char* path);
static std::string GetGameCodeForImage(CDImage* cdi);
static std::string GetGameCodeForPath(const char* image_path);
static std::optional<ConsoleRegion> GetRegionForCode(std::string_view code);
@ -76,7 +80,6 @@ private:
bool recursive;
};
static bool IsExeFileName(const char* path);
static bool GetExeListEntry(const char* path, GameListEntry* entry);
bool GetGameListEntry(const std::string& path, GameListEntry* entry);
@ -96,7 +99,7 @@ private:
DatabaseMap m_database;
EntryList m_entries;
CacheMap m_cache_map;
ByteStream* m_cache_write_stream = nullptr;
std::unique_ptr<ByteStream> m_cache_write_stream;
std::vector<DirectoryEntry> m_search_directories;
std::string m_cache_filename;

View file

@ -1,5 +1,5 @@
#include "gpu.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/heap_array.h"
#include "common/state_wrapper.h"
#include "dma.h"

View file

@ -3,6 +3,7 @@
#include "common/rectangle.h"
#include "timers.h"
#include "types.h"
#include <algorithm>
#include <array>
#include <deque>
#include <memory>

View file

@ -1,5 +1,6 @@
#include "YBaseLib/Log.h"
#include "YBaseLib/String.h"
#include "common/assert.h"
#include "common/log.h"
#include "common/string_util.h"
#include "gpu.h"
#include "interrupt_controller.h"
#include "system.h"
@ -356,8 +357,8 @@ bool GPU::HandleCopyRectangleCPUToVRAMCommand(const u32*& command_ptr, u32 comma
if (m_system->GetSettings().debugging.dump_cpu_to_vram_copies)
{
DumpVRAMToFile(SmallString::FromFormat("cpu_to_vram_copy_%u.png", s_cpu_to_vram_dump_id++), copy_width, copy_height,
sizeof(u16) * copy_width, &command_ptr[3], true);
DumpVRAMToFile(StringUtil::StdStringFromFormat("cpu_to_vram_copy_%u.png", s_cpu_to_vram_dump_id++).c_str(),
copy_width, copy_height, sizeof(u16) * copy_width, &command_ptr[3], true);
}
FlushRender();
@ -390,8 +391,8 @@ bool GPU::HandleCopyRectangleVRAMToCPUCommand(const u32*& command_ptr, u32 comma
if (m_system->GetSettings().debugging.dump_vram_to_cpu_copies)
{
DumpVRAMToFile(SmallString::FromFormat("vram_to_cpu_copy_%u.png", s_vram_to_cpu_dump_id++), m_vram_transfer.width,
m_vram_transfer.height, sizeof(u16) * VRAM_WIDTH,
DumpVRAMToFile(StringUtil::StdStringFromFormat("vram_to_cpu_copy_%u.png", s_vram_to_cpu_dump_id++).c_str(),
m_vram_transfer.width, m_vram_transfer.height, sizeof(u16) * VRAM_WIDTH,
&m_vram_ptr[m_vram_transfer.y * VRAM_WIDTH + m_vram_transfer.x], true);
}

View file

@ -1,6 +1,6 @@
#include "gpu_hw.h"
#include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h"
#include "common/assert.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "settings.h"
#include "system.h"

View file

@ -1,7 +1,6 @@
#include "gpu_hw_d3d11.h"
#include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/String.h"
#include "common/assert.h"
#include "common/log.h"
#include "common/d3d11/shader_compiler.h"
#include "gpu_hw_shadergen.h"
#include "host_display.h"

View file

@ -1,7 +1,6 @@
#include "gpu_hw_opengl.h"
#include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/String.h"
#include "common/assert.h"
#include "common/log.h"
#include "gpu_hw_shadergen.h"
#include "host_display.h"
#include "system.h"

View file

@ -1,7 +1,6 @@
#include "gpu_hw_opengl_es.h"
#include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/String.h"
#include "common/assert.h"
#include "common/log.h"
#include "gpu_hw_shadergen.h"
#include "host_display.h"
#include "system.h"

View file

@ -1,6 +1,6 @@
#include "gpu_hw_shadergen.h"
#include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h"
#include "common/assert.h"
#include "common/log.h"
#include <cstdio>
#include <glad.h>
Log_SetChannel(GPU_HW_ShaderGen);

View file

@ -1,5 +1,5 @@
#include "gpu_sw.h"
#include "YBaseLib/Assert.h"
#include "common/assert.h"
#include "host_display.h"
#include "system.h"
#include <algorithm>
@ -593,7 +593,7 @@ void GPU_SW::ShadePixel(u32 x, u32 y, u8 color_r, u8 color_g, u8 color_b, u8 tex
}
else
{
UNREFERENCED_PARAMETER(transparent);
UNREFERENCED_VARIABLE(transparent);
}
const u16 mask_and = m_GPUSTAT.GetMaskAND();

View file

@ -1,10 +1,12 @@
#include "host_interface.h"
#include "YBaseLib/ByteStream.h"
#include "YBaseLib/Log.h"
#include "YBaseLib/Timer.h"
#include "bios.h"
#include "cdrom.h"
#include "common/audio_stream.h"
#include "common/byte_stream.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/string_util.h"
#include "common/timer.h"
#include "dma.h"
#include "gpu.h"
#include "host_display.h"
@ -18,7 +20,7 @@
Log_SetChannel(HostInterface);
#ifdef _WIN32
#include "YBaseLib/Windows/WindowsHeaders.h"
#include "common/windows_headers.h"
#else
#include <time.h>
#endif
@ -50,7 +52,7 @@ static std::string GetRelativePath(const std::string& path, const char* new_file
HostInterface::HostInterface()
{
m_settings.SetDefaults();
m_last_throttle_time = Y_TimerGetValue();
m_last_throttle_time = Common::Timer::GetValue();
}
HostInterface::~HostInterface() = default;
@ -104,6 +106,26 @@ void HostInterface::ReportMessage(const char* message)
Log_InfoPrintf(message);
}
void HostInterface::ReportFormattedError(const char* format, ...)
{
std::va_list ap;
va_start(ap, format);
std::string message = StringUtil::StdStringFromFormatV(format, ap);
va_end(ap);
ReportError(message.c_str());
}
void HostInterface::ReportFormattedMessage(const char* format, ...)
{
std::va_list ap;
va_start(ap, format);
std::string message = StringUtil::StdStringFromFormatV(format, ap);
va_end(ap);
ReportMessage(message.c_str());
}
void HostInterface::DrawFPSWindow()
{
const bool show_fps = true;
@ -183,6 +205,21 @@ void HostInterface::AddOSDMessage(const char* message, float duration /*= 2.0f*/
m_osd_messages.push_back(std::move(msg));
}
void HostInterface::AddFormattedOSDMessage(float duration, const char* format, ...)
{
std::va_list ap;
va_start(ap, format);
std::string message = StringUtil::StdStringFromFormatV(format, ap);
va_end(ap);
OSDMessage msg;
msg.text = std::move(message);
msg.duration = duration;
std::unique_lock<std::mutex> lock(m_osd_messages_lock);
m_osd_messages.push_back(std::move(msg));
}
void HostInterface::DrawOSDMessages()
{
constexpr ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs |
@ -213,7 +250,10 @@ void HostInterface::DrawOSDMessages()
ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, opacity);
if (ImGui::Begin(SmallString::FromFormat("osd_%u", index++), nullptr, window_flags))
char buf[64];
std::snprintf(buf, sizeof(buf), "osd_%u", index++);
if (ImGui::Begin(buf, nullptr, window_flags))
{
ImGui::TextUnformatted(msg.text.c_str());
position_y += ImGui::GetWindowSize().y + (4.0f * scale);
@ -339,47 +379,42 @@ void HostInterface::Throttle()
bool HostInterface::LoadState(const char* filename)
{
ByteStream* stream;
if (!ByteStream_OpenFileStream(filename, BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED, &stream))
std::unique_ptr<ByteStream> stream = FileSystem::OpenFile(filename, BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
if (!stream)
return false;
AddOSDMessage(SmallString::FromFormat("Loading state from %s...", filename));
AddFormattedOSDMessage(2.0f, "Loading state from %s...", filename);
const bool result = m_system->LoadState(stream);
const bool result = m_system->LoadState(stream.get());
if (!result)
{
ReportError(SmallString::FromFormat("Loading state from %s failed. Resetting.", filename));
ReportFormattedError("Loading state from %s failed. Resetting.", filename);
m_system->Reset();
}
stream->Release();
return result;
}
bool HostInterface::SaveState(const char* filename)
{
ByteStream* stream;
if (!ByteStream_OpenFileStream(filename,
BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE | BYTESTREAM_OPEN_TRUNCATE |
BYTESTREAM_OPEN_ATOMIC_UPDATE | BYTESTREAM_OPEN_STREAMED,
&stream))
{
std::unique_ptr<ByteStream> stream =
FileSystem::OpenFile(filename, BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE | BYTESTREAM_OPEN_TRUNCATE |
BYTESTREAM_OPEN_ATOMIC_UPDATE | BYTESTREAM_OPEN_STREAMED);
if (!stream)
return false;
}
const bool result = m_system->SaveState(stream);
const bool result = m_system->SaveState(stream.get());
if (!result)
{
ReportError(SmallString::FromFormat("Saving state to %s failed.", filename));
ReportFormattedError("Saving state to %s failed.", filename);
stream->Discard();
}
else
{
AddOSDMessage(SmallString::FromFormat("State saved to %s.", filename));
ReportFormattedError("State saved to %s.", filename);
stream->Commit();
}
stream->Release();
return result;
}

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/Timer.h"
#include "common/timer.h"
#include "settings.h"
#include "types.h"
#include <chrono>
@ -41,8 +41,12 @@ public:
virtual void ReportError(const char* message);
virtual void ReportMessage(const char* message);
void ReportFormattedError(const char* format, ...);
void ReportFormattedMessage(const char* format, ...);
/// Adds OSD messages, duration is in seconds.
void AddOSDMessage(const char* message, float duration = 2.0f);
void AddFormattedOSDMessage(float duration, const char* format, ...);
/// Loads the BIOS image for the specified region.
virtual std::optional<std::vector<u8>> GetBIOSImage(ConsoleRegion region);
@ -64,7 +68,7 @@ protected:
struct OSDMessage
{
std::string text;
Timer time;
Common::Timer time;
float duration;
};
@ -88,8 +92,8 @@ protected:
u64 m_last_throttle_time = 0;
s64 m_throttle_period = INT64_C(1000000000) / 60;
Timer m_throttle_timer;
Timer m_speed_lost_time_timestamp;
Common::Timer m_throttle_timer;
Common::Timer m_speed_lost_time_timestamp;
float m_vps = 0.0f;
float m_fps = 0.0f;
@ -97,7 +101,7 @@ protected:
u32 m_last_frame_number = 0;
u32 m_last_internal_frame_number = 0;
u32 m_last_global_tick_counter = 0;
Timer m_fps_timer;
Common::Timer m_fps_timer;
std::deque<OSDMessage> m_osd_messages;
std::mutex m_osd_messages_lock;

View file

@ -1,5 +1,5 @@
#include "interrupt_controller.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "cpu_core.h"
Log_SetChannel(InterruptController);

View file

@ -1,5 +1,5 @@
#include "mdec.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "dma.h"
#include "interrupt_controller.h"

View file

@ -1,8 +1,7 @@
#include "memory_card.h"
#include "YBaseLib/AutoReleasePtr.h"
#include "YBaseLib/ByteStream.h"
#include "YBaseLib/FileSystem.h"
#include "YBaseLib/Log.h"
#include "common/byte_stream.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "host_interface.h"
#include "system.h"
@ -328,7 +327,7 @@ u8* MemoryCard::GetSectorPtr(u32 sector)
bool MemoryCard::LoadFromFile()
{
AutoReleasePtr<ByteStream> stream =
std::unique_ptr<ByteStream> stream =
FileSystem::OpenFile(m_filename.c_str(), BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
if (!stream)
return false;
@ -348,7 +347,7 @@ bool MemoryCard::SaveToFile()
if (m_filename.empty())
return false;
AutoReleasePtr<ByteStream> stream =
std::unique_ptr<ByteStream> stream =
FileSystem::OpenFile(m_filename.c_str(), BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_TRUNCATE | BYTESTREAM_OPEN_WRITE |
BYTESTREAM_OPEN_ATOMIC_UPDATE | BYTESTREAM_OPEN_STREAMED);
if (!stream)

View file

@ -1,5 +1,5 @@
#include "pad.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "controller.h"
#include "host_interface.h"
@ -42,9 +42,9 @@ bool Pad::DoState(StateWrapper& sw)
if (controller_type != state_controller_type)
{
m_system->GetHostInterface()->AddOSDMessage(SmallString::FromFormat(
"Save state contains controller type %s in port %u, but %s is used. Switching.",
Settings::GetControllerTypeName(state_controller_type), i, Settings::GetControllerTypeName(controller_type)));
m_system->GetHostInterface()->AddFormattedOSDMessage(
2.0f, "Save state contains controller type %s in port %u, but %s is used. Switching.",
Settings::GetControllerTypeName(state_controller_type), i, Settings::GetControllerTypeName(controller_type));
m_controllers[i].reset();
if (state_controller_type != ControllerType::None)
@ -62,20 +62,14 @@ bool Pad::DoState(StateWrapper& sw)
if (card_present && !m_memory_cards[i])
{
const TinyString message = TinyString::FromFormat(
"Memory card %c present in save state but not in system. Creating temporary card.", 'A' + i);
m_system->GetHostInterface()->AddOSDMessage(message);
Log_WarningPrint(message);
m_system->GetHostInterface()->AddFormattedOSDMessage(
2.0f, "Memory card %c present in save state but not in system. Creating temporary card.", 'A' + i);
m_memory_cards[i] = MemoryCard::Create(m_system);
}
else if (!card_present && m_memory_cards[i])
{
const TinyString message =
TinyString::FromFormat("Memory card %u present system but not save state. Removing card.", 'A' + i);
m_system->GetHostInterface()->AddOSDMessage(message);
Log_WarningPrint(message);
m_system->GetHostInterface()->AddFormattedOSDMessage(
2.0f, "Memory card %u present system but not save state. Removing card.", 'A' + i);
m_memory_cards[i].reset();
}

View file

@ -1,10 +1,6 @@
#include "settings.h"
#include "common/string_util.h"
#include <array>
#include <string.h>
#ifdef _MSC_VER
#define strcasecmp stricmp
#endif
Settings::Settings() = default;
@ -132,7 +128,7 @@ std::optional<ConsoleRegion> Settings::ParseConsoleRegionName(const char* str)
int index = 0;
for (const char* name : s_console_region_names)
{
if (strcasecmp(name, str) == 0)
if (StringUtil::Strcasecmp(name, str) == 0)
return static_cast<ConsoleRegion>(index);
index++;
@ -160,7 +156,7 @@ std::optional<CPUExecutionMode> Settings::ParseCPUExecutionMode(const char* str)
u8 index = 0;
for (const char* name : s_cpu_execution_mode_names)
{
if (strcasecmp(name, str) == 0)
if (StringUtil::Strcasecmp(name, str) == 0)
return static_cast<CPUExecutionMode>(index);
index++;
@ -195,7 +191,7 @@ std::optional<GPURenderer> Settings::ParseRendererName(const char* str)
int index = 0;
for (const char* name : s_gpu_renderer_names)
{
if (strcasecmp(name, str) == 0)
if (StringUtil::Strcasecmp(name, str) == 0)
return static_cast<GPURenderer>(index);
index++;
@ -222,7 +218,7 @@ std::optional<AudioBackend> Settings::ParseAudioBackend(const char* str)
int index = 0;
for (const char* name : s_audio_backend_names)
{
if (strcasecmp(name, str) == 0)
if (StringUtil::Strcasecmp(name, str) == 0)
return static_cast<AudioBackend>(index);
index++;
@ -250,7 +246,7 @@ std::optional<ControllerType> Settings::ParseControllerTypeName(const char* str)
int index = 0;
for (const char* name : s_controller_type_names)
{
if (strcasecmp(name, str) == 0)
if (StringUtil::Strcasecmp(name, str) == 0)
return static_cast<ControllerType>(index);
index++;

View file

@ -1,5 +1,5 @@
#include "sio.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "host_interface.h"
#include "interrupt_controller.h"

View file

@ -1,5 +1,5 @@
#include "spu.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/audio_stream.h"
#include "common/state_wrapper.h"
#include "dma.h"

View file

@ -1,9 +1,8 @@
#include "system.h"
#include "YBaseLib/AutoReleasePtr.h"
#include "YBaseLib/Log.h"
#include "bios.h"
#include "bus.h"
#include "cdrom.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "controller.h"
#include "cpu_code_cache.h"
@ -43,12 +42,6 @@ System::System(HostInterface* host_interface) : m_host_interface(host_interface)
System::~System() = default;
bool System::IsPSExe(const char* filename)
{
const StaticString filename_str(filename);
return filename_str.EndsWith(".psexe", false) || filename_str.EndsWith(".exe", false);
}
std::unique_ptr<System> System::Create(HostInterface* host_interface)
{
std::unique_ptr<System> system(new System(host_interface));
@ -61,8 +54,8 @@ std::unique_ptr<System> System::Create(HostInterface* host_interface)
bool System::RecreateGPU()
{
// save current state
AutoReleasePtr<ByteStream> state_stream = ByteStream_CreateGrowableMemoryStream();
StateWrapper sw(state_stream, StateWrapper::Mode::Write);
std::unique_ptr<ByteStream> state_stream = ByteStream_CreateGrowableMemoryStream();
StateWrapper sw(state_stream.get(), StateWrapper::Mode::Write);
const bool state_valid = m_gpu->DoState(sw);
if (!state_valid)
Log_ErrorPrintf("Failed to save old GPU state when switching renderers");
@ -92,7 +85,7 @@ bool System::Boot(const char* filename)
bool exe_boot = false;
if (filename)
{
exe_boot = IsPSExe(filename);
exe_boot = GameList::IsExeFileName(filename);
if (exe_boot)
{
if (m_region == ConsoleRegion::Auto)
@ -107,7 +100,7 @@ bool System::Boot(const char* filename)
media = CDImage::Open(filename);
if (!media)
{
m_host_interface->ReportError(SmallString::FromFormat("Failed to load CD image '%s'", filename));
m_host_interface->ReportFormattedError("Failed to load CD image '%s'", filename);
return false;
}
@ -139,8 +132,7 @@ bool System::Boot(const char* filename)
std::optional<BIOS::Image> bios_image = m_host_interface->GetBIOSImage(m_region);
if (!bios_image)
{
m_host_interface->ReportError(
TinyString::FromFormat("Failed to load %s BIOS", Settings::GetConsoleRegionName(m_region)));
m_host_interface->ReportFormattedError("Failed to load %s BIOS", Settings::GetConsoleRegionName(m_region));
return false;
}
@ -158,7 +150,7 @@ bool System::Boot(const char* filename)
// Load EXE late after BIOS.
if (exe_boot && !LoadEXE(filename, *bios_image))
{
m_host_interface->ReportError(SmallString::FromFormat("Failed to load EXE file '%s'", filename));
m_host_interface->ReportFormattedError("Failed to load EXE file '%s'", filename);
return false;
}
@ -457,11 +449,13 @@ Controller* System::GetController(u32 slot) const
void System::UpdateControllers()
{
const Settings& settings = m_host_interface->GetSettings();
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++) {
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
{
m_pad->SetController(i, nullptr);
const ControllerType type = settings.controller_types[i];
if (type != ControllerType::None) {
if (type != ControllerType::None)
{
std::unique_ptr<Controller> controller = Controller::Create(type);
if (controller)
m_pad->SetController(i, std::move(controller));

View file

@ -30,9 +30,6 @@ class System
public:
~System();
/// Returns true if the filename is a PlayStation executable we can inject.
static bool IsPSExe(const char* filename);
/// Creates a new System.
static std::unique_ptr<System> Create(HostInterface* host_interface);

View file

@ -1,5 +1,5 @@
#include "timers.h"
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "common/state_wrapper.h"
#include "interrupt_controller.h"
#include "system.h"

View file

@ -12,6 +12,9 @@ add_executable(duckstation-qt
gamelistsettingswidget.ui
gamelistwidget.cpp
gamelistwidget.h
gpusettingswidget.cpp
gpusettingswidget.h
gpusettingswidget.ui
hotkeysettingswidget.cpp
hotkeysettingswidget.h
inputbindingwidgets.cpp
@ -24,8 +27,6 @@ add_executable(duckstation-qt
opengldisplaywindow.h
portsettingswidget.cpp
portsettingswidget.h
qtaudiostream.cpp
qtaudiostream.h
qtdisplaywindow.cpp
qtdisplaywindow.h
qthostinterface.cpp
@ -39,7 +40,7 @@ add_executable(duckstation-qt
settingsdialog.ui
)
target_link_libraries(duckstation-qt PRIVATE YBaseLib core common imgui glad Qt5::Core Qt5::Gui Qt5::Widgets)
target_link_libraries(duckstation-qt PRIVATE core common imgui glad Qt5::Core Qt5::Gui Qt5::Widgets)
if(WIN32)
target_sources(duckstation-qt PRIVATE

View file

@ -1,6 +1,7 @@
#include "d3d11displaywindow.h"
#include "YBaseLib/Log.h"
#include "common/assert.h"
#include "common/d3d11/shader_compiler.h"
#include "common/log.h"
#include <array>
#include <imgui.h>
#include <imgui_impl_dx11.h>

View file

@ -1,5 +1,5 @@
#pragma once
#include "YBaseLib/Windows/WindowsHeaders.h"
#include "common/windows_headers.h"
#include "common/d3d11/stream_buffer.h"
#include "common/d3d11/texture.h"
#include "core/host_display.h"

View file

@ -79,9 +79,6 @@
<ProjectReference Include="..\..\dep\imgui\imgui.vcxproj">
<Project>{bb08260f-6fbc-46af-8924-090ee71360c6}</Project>
</ProjectReference>
<ProjectReference Include="..\..\dep\YBaseLib\Source\YBaseLib.vcxproj">
<Project>{b56ce698-7300-4fa5-9609-942f1d05c5a2}</Project>
</ProjectReference>
<ProjectReference Include="..\common\common.vcxproj">
<Project>{ee054e08-3799-4a59-a422-18259c105ffd}</Project>
</ProjectReference>
@ -277,7 +274,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -298,7 +295,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -319,7 +316,7 @@
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
@ -342,7 +339,7 @@
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
@ -364,7 +361,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -386,7 +383,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -410,7 +407,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>
@ -432,7 +429,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard>

View file

@ -1,4 +1,4 @@
#include "YBaseLib/Log.h"
#include "common/log.h"
#include "mainwindow.h"
#include "qthostinterface.h"
#include <QtWidgets/QApplication>
@ -8,11 +8,11 @@ static void InitLogging()
{
// set log flags
#ifdef Y_BUILD_CONFIG_DEBUG
g_pLog->SetConsoleOutputParams(true, nullptr, LOGLEVEL_DEBUG);
g_pLog->SetFilterLevel(LOGLEVEL_DEBUG);
Log::SetConsoleOutputParams(true, nullptr, LOGLEVEL_DEBUG);
Log::SetFilterLevel(LOGLEVEL_DEBUG);
#else
g_pLog->SetConsoleOutputParams(true, nullptr, LOGLEVEL_INFO);
g_pLog->SetFilterLevel(LOGLEVEL_INFO);
Log::SetConsoleOutputParams(true, nullptr, LOGLEVEL_INFO);
Log::SetFilterLevel(LOGLEVEL_INFO);
#endif
}

View file

@ -1,6 +1,6 @@
#include "opengldisplaywindow.h"
#include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h"
#include "common/assert.h"
#include "common/log.h"
#include "imgui.h"
#include "qthostinterface.h"
#include <QtGui/QKeyEvent>
@ -21,7 +21,7 @@ static void* GetProcAddressCallback(const char* name)
}
#ifdef WIN32
#include "YBaseLib/Windows/WindowsHeaders.h"
#include "common/windows_headers.h"
#endif
/// Changes the swap interval on a window. Since Qt doesn't expose this functionality, we need to change it manually

Some files were not shown because too many files have changed in this diff Show more