diff options
author | Jeremy Kescher | 2022-11-13 09:51:32 +0100 |
---|---|---|
committer | Jeremy Kescher | 2022-11-13 09:51:32 +0100 |
commit | 08694c60886039ad7b705cf70c2232c1c081b4ad (patch) | |
tree | 1a9a12d4b01580d4d9318fc2bf29e8f3f26d236e | |
parent | 8cd836d25d663ca55effa58e33834cdf0ec1e869 (diff) | |
download | aur-08694c60886039ad7b705cf70c2232c1c081b4ad.tar.gz |
2.0-15 + online PR
-rw-r--r-- | .SRCINFO | 10 | ||||
-rw-r--r-- | PKGBUILD | 17 | ||||
-rw-r--r-- | gui.diff | 94 | ||||
-rw-r--r-- | online.diff | 643 | ||||
-rw-r--r-- | overlay.diff | 330 |
5 files changed, 932 insertions, 162 deletions
@@ -1,6 +1,6 @@ pkgbase = cemu pkgdesc = Software to emulate Wii U games and applications on PC (with cutting edge Linux patches) - pkgver = 2.0.223 + pkgver = 2.0.234 pkgrel = 1 url = https://cemu.info install = cemu.install @@ -25,21 +25,21 @@ pkgbase = cemu optdepends = alsa-lib: Audio output optdepends = vulkan-driver: Vulkan graphics options = !strip - source = git+https://github.com/cemu-project/Cemu#commit=138510106c63ff697d31fe8e57391e245e477b5c + source = git+https://github.com/cemu-project/Cemu#commit=e9d10a95810d1c5f21f976000c93d37238d5b4da source = git+https://github.com/mozilla/cubeb#commit=dc511c6b3597b6384d28949285b9289e009830ea source = git+https://github.com/ocornut/imgui#commit=8a44c31c95c8e0217f6e1fc814cbbbcca4981f14 source = git+https://github.com/Exzap/ZArchive#commit=d2c717730092c7bf8cbb033b12fd4001b7c4d932 source = git+https://github.com/arsenm/sanitizers-cmake#commit=aab6948fa863bc1cbe5d0850bc46b9ef02ed4c1a source = git+https://github.com/google/googletest#commit=800f5422ac9d9e0ad59cd860a2ef3a679588acb4 source = overlay.diff - source = gui.diff + source = online.diff sha256sums = SKIP sha256sums = SKIP sha256sums = SKIP sha256sums = SKIP sha256sums = SKIP sha256sums = SKIP - sha256sums = f25d13fe76cc6a0b475f0131211a951288160ddae92cd7a815f5aea61d7cfc0f - sha256sums = dcb405fd9b77d73eee4a9591c606a5b7d121999b936920520518e70dcb16ea0e + sha256sums = f0ebf654e94461a82409860ae83e8ffee1095fc51b5748aefd7bc5cb58b54225 + sha256sums = c7da958b6c53c62477e1b52dabf6b736ac813bb4cb37a85a37c9bfa08e9ff963 pkgname = cemu @@ -1,7 +1,7 @@ # Maintainer: Jeremy Kescher <jeremy@kescher.at> pkgname=cemu -pkgver=2.0.223 +pkgver=2.0.234 pkgrel=1 pkgdesc='Software to emulate Wii U games and applications on PC (with cutting edge Linux patches)' arch=(x86_64) @@ -31,7 +31,7 @@ optdepends=( ) install=cemu.install source=( - git+https://github.com/cemu-project/Cemu#commit=138510106c63ff697d31fe8e57391e245e477b5c # v2.0-14 + git+https://github.com/cemu-project/Cemu#commit=e9d10a95810d1c5f21f976000c93d37238d5b4da # v2.0-15 # submodules git+https://github.com/mozilla/cubeb#commit=dc511c6b3597b6384d28949285b9289e009830ea git+https://github.com/ocornut/imgui#commit=8a44c31c95c8e0217f6e1fc814cbbbcca4981f14 @@ -40,8 +40,8 @@ source=( git+https://github.com/arsenm/sanitizers-cmake#commit=aab6948fa863bc1cbe5d0850bc46b9ef02ed4c1a git+https://github.com/google/googletest#commit=800f5422ac9d9e0ad59cd860a2ef3a679588acb4 # upstream proposed patches - overlay.diff # 6aa7a0c7b2003f625bfecd64f6143a10605234b2 (https://github.com/cemu-project/Cemu/pull/142) - gui.diff # ffed93a69bb8f38a7c81624411bf8be0b45b8646 (https://github.com/cemu-project/Cemu/pull/439) + overlay.diff # f1e964bf02baadc3f6af86e4f38dcef7ea5c081c (https://github.com/cemu-project/Cemu/pull/480) + online.diff # 68d39331deaa47c812ea3624dc41be3003e5d104 (https://github.com/cemu-project/Cemu/pull/486) ) sha256sums=('SKIP' 'SKIP' @@ -49,8 +49,8 @@ sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' - 'f25d13fe76cc6a0b475f0131211a951288160ddae92cd7a815f5aea61d7cfc0f' - 'dcb405fd9b77d73eee4a9591c606a5b7d121999b936920520518e70dcb16ea0e') + 'f0ebf654e94461a82409860ae83e8ffee1095fc51b5748aefd7bc5cb58b54225' + 'c7da958b6c53c62477e1b52dabf6b736ac813bb4cb37a85a37c9bfa08e9ff963') pkgver() { cd Cemu @@ -93,10 +93,7 @@ prepare() { sed -i '/InsertColumn/s/kListIconWidth/&+8/;/SetColumnWidth/s/last_col_width/&-1/' src/gui/components/wxGameList.cpp rm -rf src/util/SystemInfo - git apply "$srcdir/overlay.diff" - sed -i '/add_library/aSystemInfo/SystemInfo.cpp SystemInfo/SystemInfoLinux.cpp' src/util/CMakeLists.txt - - git apply "$srcdir/gui.diff" + git apply --whitespace=nowarn "$srcdir/overlay.diff" "$srcdir/online.diff" } build() { diff --git a/gui.diff b/gui.diff deleted file mode 100644 index 4e7d0de71c65..000000000000 --- a/gui.diff +++ /dev/null @@ -1,94 +0,0 @@ ---- a/src/gui/MainWindow.cpp -+++ b/src/gui/MainWindow.cpp -@@ -1692,8 +1692,6 @@ class CemuAboutDialog : public wxDialog - { - SetIcon(wxICON(M_WND_ICON128)); - -- this->SetBackgroundColour(wxColour(0xFFFFFFFF)); -- - wxScrolledWindow* scrolledWindow = new wxScrolledWindow(this); - - wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); ---- a/src/gui/components/wxGameList.cpp -+++ b/src/gui/components/wxGameList.cpp -@@ -358,16 +358,9 @@ long wxGameList::GetStyleFlags(Style style) const - void wxGameList::UpdateItemColors(sint32 startIndex) - { - wxWindowUpdateLocker lock(this); -- // get the background color so we can determine the theme in use -- wxColour bgColour = GetBackgroundColour(); -- uint32 bgLightness = (bgColour.GetRed() + bgColour.GetGreen() + bgColour.GetBlue()) / 3; -- bool isDarkTheme = bgLightness < 128; -- wxColour bgColourPrimary = bgColour; // color for odd rows -- wxColour bgColourSecondary = bgColour.ChangeLightness(isDarkTheme ? 110 : 90); // color for even rows - -- // for very light themes we'll use a blue tint to match the older Windows Cemu look -- if (bgLightness > 250) -- bgColourSecondary = wxColour(bgColour.Red() - 13, bgColour.Green() - 6, bgColour.Blue() - 2); -+ wxColour bgColourPrimary = GetBackgroundColour(); -+ wxColour bgColourSecondary = wxHelper::CalculateAccentColour(bgColourPrimary); - - for (int i = startIndex; i < GetItemCount(); ++i) - { -@@ -1143,4 +1136,4 @@ bool wxGameList::QueryIconForTitle(TitleId titleId, int& icon, int& iconSmall) - void wxGameList::DeleteCachedStrings() - { - m_name_cache.clear(); --} -\ No newline at end of file -+} ---- a/src/gui/components/wxTitleManagerList.cpp -+++ b/src/gui/components/wxTitleManagerList.cpp -@@ -172,10 +172,11 @@ wxString wxTitleManagerList::OnGetItemText(long item, long column) const - - wxItemAttr* wxTitleManagerList::OnGetItemAttr(long item) const - { -- const auto entry = GetTitleEntry(item); -- const wxColour kSecondColor{ 0xFDF9F2 }; -- static wxListItemAttr s_coloured_attr(GetTextColour(), kSecondColor, GetFont()); -- return item % 2 == 0 ? nullptr : &s_coloured_attr; -+ static wxColour bgColourPrimary = GetBackgroundColour(); -+ static wxColour bgColourSecondary = wxHelper::CalculateAccentColour(bgColourPrimary); -+ static wxListItemAttr s_primary_attr(GetTextColour(), bgColourPrimary, GetFont()); -+ static wxListItemAttr s_secondary_attr(GetTextColour(), bgColourSecondary, GetFont()); -+ return item % 2 == 0 ? &s_primary_attr : &s_secondary_attr; - } - - boost::optional<wxTitleManagerList::TitleEntry&> wxTitleManagerList::GetTitleEntry(long item) -@@ -1274,4 +1275,4 @@ void wxTitleManagerList::ClearItems() - void wxTitleManagerList::AutosizeColumns() - { - wxAutosizeColumns(this, ColumnTitleId, ColumnMAX - 1); --} -\ No newline at end of file -+} ---- a/src/gui/input/panels/InputPanel.h -+++ b/src/gui/input/panels/InputPanel.h -@@ -12,7 +12,7 @@ class wxComboBox; - class InputPanel : public wxPanel - { - public: -- const wxColour kKeyColourNormalMode = 0xfafafa; -+ const wxColour kKeyColourNormalMode = GetBackgroundColour(); - const wxColour kKeyColourEditMode = 0x99ccff; - const wxColour kKeyColourActiveMode = 0xE0E0E0; - ---- a/src/gui/wxHelper.h -+++ b/src/gui/wxHelper.h -@@ -22,5 +22,16 @@ namespace wxHelper - return wxString::FromUTF8(str.data(), str.size()); - } - -+ inline wxColour CalculateAccentColour(const wxColour& bgColour) -+ { -+ wxColour bgColourSecondary; -+ const uint32 bgLightness = (bgColour.GetRed() + bgColour.GetGreen() + bgColour.GetBlue()) / 3; -+ const bool isDarkTheme = bgLightness < 128; -+ bgColourSecondary = bgColour.ChangeLightness(isDarkTheme ? 110 : 90); // color for even rows -+ // for very light themes we'll use a blue tint to match the older Windows Cemu look -+ if (bgLightness > 250) -+ bgColourSecondary = wxColour(bgColour.Red() - 13, bgColour.Green() - 6, bgColour.Blue() - 2); -+ return bgColourSecondary; -+ } - - }; diff --git a/online.diff b/online.diff new file mode 100644 index 000000000000..cfac0e3fd8fe --- /dev/null +++ b/online.diff @@ -0,0 +1,643 @@ +diff --git a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp +index 5ec75e6b..d32c51f2 100644 +--- a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp ++++ b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp +@@ -455,11 +455,6 @@ void export_curl_multi_fdset(PPCInterpreter_t* hCPU) + ppcDefineParamMEMPTR(exceptionFd, wu_fd_set, 3); + ppcDefineParamU32BEPtr(maxFd, 4); + +-#if BOOST_OS_LINUX || BOOST_OS_MACOS +- cemuLog_log(LogType::Force, "curl_multi_fdset(...) - todo"); +- +- osLib_returnFromFunction(hCPU, 0); +-#else + fd_set h_readFd; + fd_set h_writeFd; + fd_set h_exceptionFd; +@@ -475,17 +470,36 @@ void export_curl_multi_fdset(PPCInterpreter_t* hCPU) + nsysnet::wuResetFD(exceptionFd.GetPtr()); + + sint32 c_maxFD = -1; +- // fd read set +- for (uint32 i = 0; i < h_readFd.fd_count; i++) ++ ++ auto hostFdSet = [&](SOCKET s, wu_fd_set* fds) + { +- sint32 wuSocket = nsysnet_getVirtualSocketHandleFromHostHandle(h_readFd.fd_array[i]); ++ sint32 wuSocket = nsysnet_getVirtualSocketHandleFromHostHandle(s); + if (wuSocket < 0) +- wuSocket = nsysnet_createVirtualSocketFromExistingSocket(h_readFd.fd_array[i]); ++ wuSocket = nsysnet_createVirtualSocketFromExistingSocket(s); + if (wuSocket >= 0) + { + c_maxFD = std::max(wuSocket, c_maxFD); +- nsysnet::wuSetFD(readFd.GetPtr(), wuSocket); ++ nsysnet::wuSetFD(fds, wuSocket); + } ++ }; ++ ++#if BOOST_OS_UNIX ++ for (int s = 0; s < h_maxFd + 1; s++) ++ { ++ if(FD_ISSET(s, &h_readFd)) ++ hostFdSet(s, readFd.GetPtr()); ++ ++ if(FD_ISSET(s, &h_writeFd)) ++ hostFdSet(s, writeFd.GetPtr()); ++ ++ if(FD_ISSET(s, &h_exceptionFd)) ++ hostFdSet(s, exceptionFd.GetPtr()); ++ } ++#else ++ // fd read set ++ for (uint32 i = 0; i < h_readFd.fd_count; i++) ++ { ++ hostFdSet(h_readFd.fd_array[i], readFd.GetPtr()); + } + // fd write set + for (uint32 i = 0; i < h_writeFd.fd_count; i++) +@@ -497,11 +511,10 @@ void export_curl_multi_fdset(PPCInterpreter_t* hCPU) + { + cemu_assert_debug(false); + } ++#endif + + *maxFd = c_maxFD; + osLib_returnFromFunction(hCPU, result); +-#endif +- + } + + void export_curl_multi_setopt(PPCInterpreter_t* hCPU) +diff --git a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp +index ade207f9..5a8081e2 100644 +--- a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp ++++ b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp +@@ -6,8 +6,24 @@ + + #include "Common/socket.h" + ++#if BOOST_OS_UNIX ++ ++#define WSAEWOULDBLOCK EWOULDBLOCK ++#define WSAEINPROGRESS EINPROGRESS ++#define WSAESHUTDOWN ESHUTDOWN ++#define WSAECONNABORTED ECONNABORTED ++#define WSAHOST_NOT_FOUND EAI_NONAME ++ ++#define GETLASTERR errno ++ ++#endif // BOOST_OS_UNIX ++ + #if BOOST_OS_WINDOWS + ++#define GETLASTERR WSAGetLastError() ++ ++#endif //BOOST_OS_WINDOWS ++ + #define WU_AF_INET 2 + + #define WU_SOCK_STREAM 1 +@@ -50,8 +66,10 @@ bool sockLibReady = false; + void nsysnetExport_socket_lib_init(PPCInterpreter_t* hCPU) + { + sockLibReady = true; ++#if BOOST_OS_WINDOWS + WSADATA wsa; + WSAStartup(MAKEWORD(2, 2), &wsa); ++#endif // BOOST_OS_WINDOWS + osLib_returnFromFunction(hCPU, 0); // 0 -> Success + } + +@@ -200,7 +218,9 @@ sint32 _getFreeSocketHandle() + return 0; + } + ++#if BOOST_OS_WINDOWS + #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) ++#endif // BOOST_OS_WINDOWS + + WUSOCKET nsysnet_createVirtualSocket(sint32 family, sint32 type, sint32 protocol) + { +@@ -219,6 +239,7 @@ WUSOCKET nsysnet_createVirtualSocket(sint32 family, sint32 type, sint32 protocol + virtualSocketTable[s - 1] = vs; + // init host socket + vs->s = socket(family, type, protocol); ++ #if BOOST_OS_WINDOWS + // disable reporting of PORT_UNREACHABLE for UDP sockets + if (protocol == IPPROTO_UDP) + { +@@ -226,21 +247,14 @@ WUSOCKET nsysnet_createVirtualSocket(sint32 family, sint32 type, sint32 protocol + DWORD dwBytesReturned = 0; + WSAIoctl(vs->s, SIO_UDP_CONNRESET, &bNewBehavior, sizeof bNewBehavior, NULL, 0, &dwBytesReturned, NULL, NULL); + } ++ #endif // BOOST_OS_WINDOWS + return vs->handle; + } + + WUSOCKET nsysnet_createVirtualSocketFromExistingSocket(SOCKET existingSocket) + { + forceLogDebug_printf("nsysnet_createVirtualSocketFromExistingSocket - incomplete"); +- // SO_TYPE -> type +- // SO_BSP_STATE -> protocol + other info +- // SO_PROTOCOL_INFO -> protocol + type? +- +- WSAPROTOCOL_INFO protocolInfo = { 0 }; +- int optLen = sizeof(protocolInfo); +- getsockopt(existingSocket, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&protocolInfo, &optLen); + +- // todo - translate protocolInfo + + sint32 s = _getFreeSocketHandle(); + if (s == 0) +@@ -250,9 +264,34 @@ WUSOCKET nsysnet_createVirtualSocketFromExistingSocket(SOCKET existingSocket) + } + virtualSocket_t* vs = (virtualSocket_t*)malloc(sizeof(virtualSocket_t)); + memset(vs, 0, sizeof(virtualSocket_t)); ++#if BOOST_OS_WINDOWS ++ // SO_TYPE -> type ++ // SO_BSP_STATE -> protocol + other info ++ // SO_PROTOCOL_INFO -> protocol + type? ++ ++ WSAPROTOCOL_INFO protocolInfo = { 0 }; ++ int optLen = sizeof(protocolInfo); ++ getsockopt(existingSocket, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&protocolInfo, &optLen); ++ // todo - translate protocolInfo + vs->family = protocolInfo.iAddressFamily; + vs->type = protocolInfo.iSocketType; + vs->protocol = protocolInfo.iSocketType; ++#else ++ { ++ int type; ++ socklen_t optlen; ++ getsockopt(vs->s, SOL_SOCKET, SO_TYPE, &type, &optlen); ++ vs->type = type; ++ vs->protocol = type; ++ } ++ { ++ sockaddr saddr; ++ socklen_t len; ++ getsockname(vs->s, &saddr, &len); ++ vs->family = saddr.sa_family; ++ } ++#endif ++ + vs->handle = s; + virtualSocketTable[s - 1] = vs; + vs->s = existingSocket; +@@ -395,7 +434,19 @@ void nsysnetExport_socketclose(PPCInterpreter_t* hCPU) + } + osLib_returnFromFunction(hCPU, 0); + } +- ++sint32 _socket_nonblock(SOCKET s, u_long mode) ++{ ++#if BOOST_OS_WINDOWS ++ return ioctlsocket(s, FIONBIO, &mode); ++#else ++ int flags = fcntl(s, F_GETFL); ++ if(mode) ++ flags |= O_NONBLOCK; ++ else ++ flags &= ~O_NONBLOCK; ++ return fcntl(s, F_SETFL, flags); ++#endif ++} + void nsysnetExport_setsockopt(PPCInterpreter_t* hCPU) + { + socketLog_printf("setsockopt(%d,0x%x,0x%05x,0x%08x,%d)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6], hCPU->gpr[7]); +@@ -441,7 +492,7 @@ void nsysnetExport_setsockopt(PPCInterpreter_t* hCPU) + else + cemu_assert_suspicious(); + u_long mode = 1; +- ioctlsocket(vs->s, FIONBIO, &mode); ++ _socket_nonblock(vs->s, mode); + vs->isNonBlocking = true; + } + else if (optname == WU_SO_NONBLOCK) +@@ -450,16 +501,16 @@ void nsysnetExport_setsockopt(PPCInterpreter_t* hCPU) + assert_dbg(); + sint32 optvalLE = _swapEndianU32(*(uint32*)optval); + u_long mode = optvalLE; // 1 -> enable, 0 -> disable +- ioctlsocket(vs->s, FIONBIO, &mode); ++ _socket_nonblock(vs->s, mode); + vs->isNonBlocking = mode != 0; + } + else if (optname == WU_SO_KEEPALIVE) + { +- // todo ++ cemuLog_logDebug(LogType::Socket, "todo: setsockopt() for WU_SO_KEEPALIVE"); + } + else if (optname == WU_SO_WINSCALE) + { +- // todo ++ cemuLog_logDebug(LogType::Socket, "todo: setsockopt() for WU_SO_WINSCALE"); + } + else if (optname == WU_SO_RCVBUF) + { +@@ -549,9 +600,9 @@ void nsysnetExport_getsockopt(PPCInterpreter_t* hCPU) + if (optname == WU_SO_LASTERROR) + { + int optvalLE = 0; +- int optlenLE = 4; ++ socklen_t optlenLE = 4; + r = getsockopt(vs->s, hostLevel, SO_ERROR, (char*)&optvalLE, &optlenLE); +- r = _translateError(r, WSAGetLastError()); ++ r = _translateError(r, GETLASTERR); + if (memory_readU32(optlenMPTR) != 4) + assert_dbg(); + memory_writeU32(optlenMPTR, 4); +@@ -563,9 +614,9 @@ void nsysnetExport_getsockopt(PPCInterpreter_t* hCPU) + else if (optname == WU_SO_RCVBUF) + { + int optvalLE = 0; +- int optlenLE = 4; ++ socklen_t optlenLE = 4; + r = getsockopt(vs->s, hostLevel, SO_RCVBUF, (char*)&optvalLE, &optlenLE); +- r = _translateError(r, WSAGetLastError()); ++ r = _translateError(r, GETLASTERR); + if (memory_readU32(optlenMPTR) != 4) + assert_dbg(); + memory_writeU32(optlenMPTR, 4); +@@ -575,9 +626,9 @@ void nsysnetExport_getsockopt(PPCInterpreter_t* hCPU) + else if (optname == WU_SO_SNDBUF) + { + int optvalLE = 0; +- int optlenLE = 4; ++ socklen_t optlenLE = 4; + r = getsockopt(vs->s, hostLevel, SO_SNDBUF, (char*)&optvalLE, &optlenLE); +- r = _translateError(r, WSAGetLastError()); ++ r = _translateError(r, GETLASTERR); + if (memory_readU32(optlenMPTR) != 4) + assert_dbg(); + memory_writeU32(optlenMPTR, 4); +@@ -737,7 +788,7 @@ void nsysnetExport_bind(PPCInterpreter_t* hCPU) + hostAddr.sa_family = _swapEndianU16(addr->sa_family); + memcpy(hostAddr.sa_data, addr->sa_data, 14); + sint32 hr = bind(vs->s, &hostAddr, sizeof(sockaddr)); +- r = _translateError(hr, WSAGetLastError()); ++ r = _translateError(hr, GETLASTERR); + + + socketLog_printf("bind address: %d.%d.%d.%d:%d result: %d", addr->sa_data[2], addr->sa_data[3], addr->sa_data[4], addr->sa_data[5], _swapEndianU16(*(uint16*)addr->sa_data), hr); +@@ -797,7 +848,7 @@ void nsysnetExport_accept(PPCInterpreter_t* hCPU) + if (vs->isNonBlocking) + { + sockaddr hostAddr; +- int hostLen = sizeof(sockaddr); ++ socklen_t hostLen = sizeof(sockaddr); + SOCKET hr = accept(vs->s, &hostAddr, &hostLen); + if (hr != SOCKET_ERROR) + { +@@ -806,7 +857,7 @@ void nsysnetExport_accept(PPCInterpreter_t* hCPU) + } + else + { +- r = _translateError((sint32)hr, (sint32)WSAGetLastError(), _ERROR_MODE_ACCEPT); ++ r = _translateError((sint32)hr, (sint32)GETLASTERR, _ERROR_MODE_ACCEPT); + } + sockaddr_host2guest(&hostAddr, addr); + } +@@ -820,7 +871,6 @@ void nsysnetExport_accept(PPCInterpreter_t* hCPU) + osLib_returnFromFunction(hCPU, r); + } + +- + void nsysnetExport_connect(PPCInterpreter_t* hCPU) + { + socketLog_printf("connect(%d,0x%08x,%d)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]); +@@ -844,7 +894,7 @@ void nsysnetExport_connect(PPCInterpreter_t* hCPU) + sint32 hr = connect(vs->s, &hostAddr, sizeof(sockaddr)); + forceLog_printf("Attempt connect to %d.%d.%d.%d:%d", (sint32)(uint8)hostAddr.sa_data[2], (sint32)(uint8)hostAddr.sa_data[3], (sint32)(uint8)hostAddr.sa_data[4], (sint32)(uint8)hostAddr.sa_data[5], _swapEndianU16(*(uint16*)hostAddr.sa_data+0)); + +- r = _translateError(hr, WSAGetLastError(), _ERROR_MODE_CONNECT); ++ r = _translateError(hr, GETLASTERR, _ERROR_MODE_CONNECT); + + osLib_returnFromFunction(hCPU, r); + } +@@ -852,7 +902,7 @@ void nsysnetExport_connect(PPCInterpreter_t* hCPU) + void _setSocketSendRecvNonBlockingMode(SOCKET s, bool isNonBlocking) + { + u_long mode = isNonBlocking ? 1 : 0; +- sint32 r = ioctlsocket(s, FIONBIO, &mode); ++ sint32 r = _socket_nonblock(s, mode); + } + + void nsysnetExport_send(PPCInterpreter_t* hCPU) +@@ -881,7 +931,7 @@ void nsysnetExport_send(PPCInterpreter_t* hCPU) + + sint32 hr = send(vs->s, msg, len, hostFlags); + socketLog_printf("Sent %d bytes", hr); +- _translateError(hr <= 0 ? -1 : 0, WSAGetLastError()); ++ _translateError(hr <= 0 ? -1 : 0, GETLASTERR); + r = hr; + + osLib_returnFromFunction(hCPU, r); +@@ -930,7 +980,7 @@ void nsysnetExport_recv(PPCInterpreter_t* hCPU) + break; + if (tr == 0) + break; // connection closed +- if (tr < 0 && WSAGetLastError() != WSAEWOULDBLOCK) ++ if (tr < 0 && GETLASTERR != WSAEWOULDBLOCK) + break; + // yield thread + coreinit::OSSleepTicks(coreinit::EspressoTime::GetTimerClock() / 5000); // let thread wait 0.2ms to give other threads CPU time +@@ -940,7 +990,7 @@ void nsysnetExport_recv(PPCInterpreter_t* hCPU) + } + // receive + sint32 hr = recv(vs->s, msg, len, hostFlags); +- _translateError(hr <= 0 ? -1 : 0, WSAGetLastError()); ++ _translateError(hr <= 0 ? -1 : 0, GETLASTERR); + if (requestIsNonBlocking != vs->isNonBlocking) + _setSocketSendRecvNonBlockingMode(vs->s, vs->isNonBlocking); + socketLog_printf("Received %d bytes", hr); +@@ -955,11 +1005,20 @@ struct wu_timeval + uint32 tv_usec; + }; + +-void _translateFDSet(fd_set* hostSet, struct wu_fd_set* fdset, sint32 nfds) ++void _translateFDSet(fd_set* hostSet, struct wu_fd_set* fdset, sint32 nfds, int *hostnfds) + { +- hostSet->fd_count = 0; ++ FD_ZERO(hostSet); + if (fdset == NULL) + return; ++ ++#if BOOST_OS_UNIX ++ int maxfd; ++ if(hostnfds) ++ maxfd = *hostnfds; ++ else ++ maxfd = -1; ++#endif ++ + uint32 mask = fdset->mask; + for (sint32 i = 0; i < nfds; i++) + { +@@ -969,9 +1028,19 @@ void _translateFDSet(fd_set* hostSet, struct wu_fd_set* fdset, sint32 nfds) + virtualSocket_t* vs = nsysnet_getVirtualSocketObject(socketHandle); + if(vs == NULL) + continue; // socket invalid +- hostSet->fd_array[hostSet->fd_count] = vs->s; +- hostSet->fd_count++; ++ ++#if BOOST_OS_UNIX ++ if(vs->s > maxfd) ++ maxfd = vs->s; ++#endif ++ ++ FD_SET(vs->s, hostSet); + } ++ ++#if BOOST_OS_UNIX ++ if(hostnfds) ++ *hostnfds = maxfd; ++#endif + } + + void _translateFDSetRev(struct wu_fd_set* fdset, fd_set* hostSet, sint32 nfds) +@@ -979,6 +1048,7 @@ void _translateFDSetRev(struct wu_fd_set* fdset, fd_set* hostSet, sint32 nfds) + if (fdset == NULL) + return; + uint32 mask = _swapEndianU32(0); ++#if BOOST_OS_WINDOWS + for (sint32 i = 0; i < (sint32)hostSet->fd_count; i++) + { + sint32 virtualSocketHandle = nsysnet_getVirtualSocketHandleFromHostHandle(hostSet->fd_array[i]); +@@ -986,7 +1056,15 @@ void _translateFDSetRev(struct wu_fd_set* fdset, fd_set* hostSet, sint32 nfds) + cemu_assert_debug(false); + mask |= (1<<virtualSocketHandle); + } ++#else ++ for (sint32 i = 0; i < WU_SOCKET_LIMIT; i++) ++ { ++ if (virtualSocketTable[i] && virtualSocketTable[i]->s && FD_ISSET(virtualSocketTable[i]->s, hostSet)) ++ mask |= (1 << virtualSocketTable[i]->handle); ++ } ++#endif + fdset->mask = mask; ++ + } + + void nsysnetExport_select(PPCInterpreter_t* hCPU) +@@ -1025,8 +1103,10 @@ void nsysnetExport_select(PPCInterpreter_t* hCPU) + // when fd sets are empty but timeout is set, then just wait and do nothing? + // Lost Reavers seems to expect this case to return 0 (it hardcodes empty fd sets and timeout comes from curl_multi_timeout) + +- //_setSockError(WU_SO_EINVAL); +- // todo - sleep here ++ timeval tv; ++ tv.tv_sec = timeOut->tv_sec; ++ tv.tv_usec = timeOut->tv_usec; ++ select(0, nullptr, nullptr, nullptr, &tv); + socketLog_printf("select returned 0 because of empty fdsets with timeout"); + osLib_returnFromFunction(hCPU, 0); + +@@ -1042,15 +1122,16 @@ void nsysnetExport_select(PPCInterpreter_t* hCPU) + uint32 startTime = GetTickCount(); + while (true) + { +- _translateFDSet(&_readfds, readfds, nfds); +- _translateFDSet(&_writefds, writefds, nfds); +- _translateFDSet(&_exceptfds, exceptfds, nfds); +- r = select(0, readfds ? &_readfds : NULL, writefds ? &_writefds : NULL, exceptfds ? &_exceptfds : NULL, &tv); ++ int hostnfds = -1; ++ _translateFDSet(&_readfds, readfds, nfds, &hostnfds); ++ _translateFDSet(&_writefds, writefds, nfds, &hostnfds); ++ _translateFDSet(&_exceptfds, exceptfds, nfds, &hostnfds); ++ r = select(hostnfds + 1, readfds ? &_readfds : NULL, writefds ? &_writefds : NULL, exceptfds ? &_exceptfds : NULL, &tv); + if (r < 0) + { + forceLogDebug_printf("select() failed"); + // timeout +- _translateError(r, WSAGetLastError()); ++ _translateError(r, GETLASTERR); + //_setSockError(WU_SO_SUCCESS); + // in case of error, clear all FD sets (?) + if (readfds) +@@ -1083,7 +1164,9 @@ void nsysnetExport_select(PPCInterpreter_t* hCPU) + } + else + { +- socketLog_printf("select returned %d. Read %d Write %d Except %d", r, _readfds.fd_count, _writefds.fd_count, _exceptfds.fd_count); ++ // socketLog_printf("select returned %d. Read %d Write %d Except %d", r, _readfds.fd_count, _writefds.fd_count, _exceptfds.fd_count); ++ socketLog_printf("select returned %d.", r); ++ + _translateFDSetRev(readfds, &_readfds, nfds); + _translateFDSetRev(writefds, &_writefds, nfds); + _translateFDSetRev(exceptfds, &_exceptfds, nfds); +@@ -1116,7 +1199,7 @@ void nsysnetExport_getsockname(PPCInterpreter_t* hCPU) + else + { + struct sockaddr hostAddr; +- sint32 hostLen = sizeof(struct sockaddr); ++ socklen_t hostLen = sizeof(struct sockaddr); + sint32 hr = getsockname(vs->s, &hostAddr, &hostLen); + if (hr == 0) + { +@@ -1151,13 +1234,13 @@ void nsysnetExport_getpeername(PPCInterpreter_t* hCPU) + } + + sockaddr saddr; +- int saddrLen = sizeof(sockaddr); ++ socklen_t saddrLen = sizeof(sockaddr); + + if (*nameLen < (uint32be)16) + assert_dbg(); + + sint32 r = getpeername(vs->s, &saddr, &saddrLen); +- r = _translateError(r, WSAGetLastError()); ++ r = _translateError(r, GETLASTERR); + + name->sa_family = _swapEndianU16(saddr.sa_family); + memcpy(name->sa_data, saddr.sa_data, 14); +@@ -1432,7 +1515,7 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU) + if (vs->isNonBlocking) + requestIsNonBlocking = vs->isNonBlocking; + +- sint32 fromLenHost = *fromLen; ++ socklen_t fromLenHost = *fromLen; + sockaddr fromAddrHost; + sint32 wsaError = 0; + +@@ -1447,16 +1530,20 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU) + return; + } + // use select to check for exceptions and read data +- FD_SET fd_read; +- FD_SET fd_exceptions; ++ fd_set fd_read; ++ fd_set fd_exceptions; + FD_ZERO(&fd_read); + FD_ZERO(&fd_exceptions); + FD_SET(vs->s, &fd_read); + FD_SET(vs->s, &fd_exceptions); +- TIMEVAL t; ++ timeval t; + t.tv_sec = 0; + t.tv_usec = 0; +- sint32 count = select(0, &fd_read, NULL, &fd_exceptions, &t); ++ int nfds = 0; ++#if BOOST_OS_UNIX ++ nfds = vs->s + 1; ++#endif ++ sint32 count = select(nfds, &fd_read, NULL, &fd_exceptions, &t); + if (count > 0) + { + if (FD_ISSET(vs->s, &fd_exceptions)) +@@ -1467,7 +1554,7 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU) + { + // data available + r = recvfrom(vs->s, msg, len, hostFlags, &fromAddrHost, &fromLenHost); +- wsaError = WSAGetLastError(); ++ wsaError = GETLASTERR; + if (r < 0) + cemu_assert_debug(false); + forceLogDebug_printf("recvfrom returned %d bytes", r); +@@ -1504,7 +1591,7 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU) + while (true) + { + r = recvfrom(vs->s, msg, len, hostFlags, &fromAddrHost, &fromLenHost); +- wsaError = WSAGetLastError(); ++ wsaError = GETLASTERR; + if (r < 0) + { + if (wsaError != WSAEWOULDBLOCK) +@@ -1576,7 +1663,7 @@ void nsysnetExport_recvfrom_ex(PPCInterpreter_t* hCPU) + if (vs->isNonBlocking) + requestIsNonBlocking = vs->isNonBlocking; + +- sint32 fromLenHost = *fromLen; ++ socklen_t fromLenHost = *fromLen; + sockaddr fromAddrHost; + sint32 wsaError = 0; + +@@ -1591,16 +1678,20 @@ void nsysnetExport_recvfrom_ex(PPCInterpreter_t* hCPU) + return; + } + // use select to check for exceptions and read data +- FD_SET fd_read; +- FD_SET fd_exceptions; ++ fd_set fd_read; ++ fd_set fd_exceptions; + FD_ZERO(&fd_read); + FD_ZERO(&fd_exceptions); + FD_SET(vs->s, &fd_read); + FD_SET(vs->s, &fd_exceptions); +- TIMEVAL t; ++ timeval t; + t.tv_sec = 0; + t.tv_usec = 0; +- sint32 count = select(0, &fd_read, NULL, &fd_exceptions, &t); ++ int nfds = 0; ++#if BOOST_OS_UNIX ++ nfds = vs->s + 1; ++#endif ++ sint32 count = select(nfds, &fd_read, NULL, &fd_exceptions, &t); + if (count > 0) + { + if (FD_ISSET(vs->s, &fd_exceptions)) +@@ -1611,7 +1702,7 @@ void nsysnetExport_recvfrom_ex(PPCInterpreter_t* hCPU) + { + // data available + r = recvfrom(vs->s, msg, len, hostFlags, &fromAddrHost, &fromLenHost); +- wsaError = WSAGetLastError(); ++ wsaError = GETLASTERR; + if (r < 0) + { + cemu_assert_debug(false); +@@ -1693,7 +1784,7 @@ void nsysnetExport_sendto(PPCInterpreter_t* hCPU) + while (true) + { + r = sendto(vs->s, msg, len, hostFlags, &toAddrHost, toLen); +- wsaError = WSAGetLastError(); ++ wsaError = GETLASTERR; + if (r < 0) + { + if (wsaError != WSAEWOULDBLOCK) +@@ -1711,7 +1802,7 @@ void nsysnetExport_sendto(PPCInterpreter_t* hCPU) + // non blocking + _setSocketSendRecvNonBlockingMode(vs->s, true); + r = sendto(vs->s, msg, len, hostFlags, &toAddrHost, toLen); +- wsaError = WSAGetLastError(); ++ wsaError = GETLASTERR; + _setSocketSendRecvNonBlockingMode(vs->s, vs->isNonBlocking); + } + +@@ -1818,8 +1909,6 @@ void nsysnetExport_sendto_multi_ex(PPCInterpreter_t* hCPU) + osLib_returnFromFunction(hCPU, sendLenSum); // return value correct? + } + +-#endif +- + namespace nsysnet + { + std::vector<NSSLInternalState_t> g_nsslInternalStates; +@@ -2030,7 +2119,6 @@ namespace nsysnet + void nsysnet_load() + { + +- #if BOOST_OS_WINDOWS + osLib_addFunction("nsysnet", "socket_lib_init", nsysnetExport_socket_lib_init); + + // socket API +@@ -2071,7 +2159,6 @@ void nsysnet_load() + osLib_addFunction("nsysnet", "sendto_multi", nsysnetExport_sendto_multi); + osLib_addFunction("nsysnet", "sendto_multi_ex", nsysnetExport_sendto_multi_ex); + +-#endif + + // NSSL API + osLib_addFunction("nsysnet", "NSSLCreateContext", nsysnet::export_NSSLCreateContext); +@@ -2084,10 +2171,3 @@ void nsysnet_load() + osLib_addFunction("nsysnet", "NSSLExportInternalServerCertificate", nsysnet::export_NSSLExportInternalServerCertificate); + osLib_addFunction("nsysnet", "NSSLExportInternalClientCertificate", nsysnet::export_NSSLExportInternalClientCertificate); + } +- +-#if BOOST_OS_LINUX || BOOST_OS_MACOS +-void nsysnet_notifyCloseSharedSocket(SOCKET existingSocket) +-{ +- +-} +-#endif +\ No newline at end of file diff --git a/overlay.diff b/overlay.diff index 7ef31cf81880..947843be01a7 100644 --- a/overlay.diff +++ b/overlay.diff @@ -1,3 +1,5 @@ +diff --git a/src/Cafe/HW/Latte/Core/LatteOverlay.cpp b/src/Cafe/HW/Latte/Core/LatteOverlay.cpp +index 21b70d25..441ec169 100644 --- a/src/Cafe/HW/Latte/Core/LatteOverlay.cpp +++ b/src/Cafe/HW/Latte/Core/LatteOverlay.cpp @@ -12,30 +12,16 @@ @@ -33,7 +35,7 @@ std::vector<ProcessorTime> processor_times; double fps{}; -@@ -565,83 +551,52 @@ void LatteOverlay_render(bool pad_view) +@@ -562,83 +548,52 @@ void LatteOverlay_render(bool pad_view) } } @@ -60,10 +62,10 @@ - return; + ProcessorTime now; + QueryProcTime(now); -+ ++ + double cpu = ProcessorTime::Compare(g_state.processor_time_cemu, now); + cpu /= g_state.processor_count; -+ ++ + g_state.cpu_usage = cpu * 100; + g_state.processor_time_cemu = now; +} @@ -73,7 +75,7 @@ +static void UpdateStats_CpuPerCore() +{ + std::vector<ProcessorTime> now(g_state.processor_count); -+ QueryCoreTimes(g_state.processor_count, now.data()); ++ QueryCoreTimes(g_state.processor_count, now); -#if BOOST_OS_WINDOWS - // update cemu cpu @@ -147,6 +149,160 @@ // update vram g_renderer->GetVRAMInfo(g_state.vramUsage, g_state.vramTotal); +diff --git a/src/Cafe/HW/Latte/Core/LattePerformanceMonitor.cpp b/src/Cafe/HW/Latte/Core/LattePerformanceMonitor.cpp +index 7104dbd9..714758e9 100644 +--- a/src/Cafe/HW/Latte/Core/LattePerformanceMonitor.cpp ++++ b/src/Cafe/HW/Latte/Core/LattePerformanceMonitor.cpp +@@ -98,7 +98,10 @@ void LattePerformanceMonitor_frameEnd() + performanceMonitor.cycle[nextCycleIndex].recompilerLeaveCount = 0; + performanceMonitor.cycle[nextCycleIndex].threadLeaveCount = 0; + performanceMonitor.cycleIndex = nextCycleIndex; +- ++ ++ // next update in 1 second ++ performanceMonitor.cycle[performanceMonitor.cycleIndex].lastUpdate = GetTickCount(); ++ + if (isFirstUpdate) + { + LatteOverlay_updateStats(0.0, 0); +@@ -109,8 +112,6 @@ void LattePerformanceMonitor_frameEnd() + LatteOverlay_updateStats(fps, drawCallCounter / elapsedFrames); + gui_updateWindowTitles(false, false, fps); + } +- // next update in 1 second +- performanceMonitor.cycle[performanceMonitor.cycleIndex].lastUpdate = GetTickCount(); + + // prevent hibernation and screen saver/monitor off + #if BOOST_OS_WINDOWS +@@ -124,4 +125,4 @@ void LattePerformanceMonitor_frameBegin() + { + performanceMonitor.vk.numDrawBarriersPerFrame.reset(); + performanceMonitor.vk.numBeginRenderpassPerFrame.reset(); +-} +\ No newline at end of file ++} +diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt +index 06c8f857..5af88176 100644 +--- a/src/util/CMakeLists.txt ++++ b/src/util/CMakeLists.txt +@@ -16,8 +16,6 @@ add_library(CemuUtil + DXGIWrapper/DXGIWrapper.h + EventService.h + Fiber/Fiber.h +- Fiber/FiberUnix.cpp +- Fiber/FiberWin.cpp + helpers/ClassWrapper.h + helpers/ConcurrentQueue.h + helpers/enum_array.hpp +@@ -50,8 +48,8 @@ add_library(CemuUtil + math/vector2.h + math/vector3.h + MemMapper/MemMapper.h +- MemMapper/MemMapperUnix.cpp +- MemMapper/MemMapperWin.cpp ++ SystemInfo/SystemInfo.cpp ++ SystemInfo/SystemInfo.h + ThreadPool/ThreadPool.cpp + ThreadPool/ThreadPool.h + tinyxml2/tinyxml2.cpp +@@ -71,6 +69,23 @@ add_library(CemuUtil + Zir/Passes/ZpIRRegisterAllocator.cpp + ) + ++if(WIN32) ++ target_sources(CemuUtil PRIVATE Fiber/FiberWin.cpp) ++ target_sources(CemuUtil PRIVATE MemMapper/MemMapperWin.cpp) ++ target_sources(CemuUtil PRIVATE SystemInfo/SystemInfoWin.cpp) ++elseif(UNIX) ++ target_sources(CemuUtil PRIVATE Fiber/FiberUnix.cpp) ++ target_sources(CemuUtil PRIVATE MemMapper/MemMapperUnix.cpp) ++ target_sources(CemuUtil PRIVATE SystemInfo/SystemInfoUnix.cpp) ++ if(NOT APPLE) ++ target_sources(CemuUtil PRIVATE SystemInfo/SystemInfoLinux.cpp) ++ else() ++ target_sources(CemuUtil PRIVATE SystemInfo/SystemInfoMac.cpp) ++ endif() ++else() ++ target_sources(CemuUtil PRIVATE SystemInfo/SystemInfoStub.cpp) ++endif() ++ + set_property(TARGET CemuUtil PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") + + target_include_directories(CemuUtil PUBLIC "../") +diff --git a/src/util/Fiber/FiberUnix.cpp b/src/util/Fiber/FiberUnix.cpp +index c2ced28b..7d3bf05a 100644 +--- a/src/util/Fiber/FiberUnix.cpp ++++ b/src/util/Fiber/FiberUnix.cpp +@@ -1,5 +1,4 @@ + #include "Fiber.h" +-#if BOOST_OS_LINUX || BOOST_OS_MACOS + #include <ucontext.h> + + thread_local Fiber* sCurrentFiber{}; +@@ -52,5 +51,3 @@ void* Fiber::GetFiberPrivateData() + { + return sCurrentFiber->m_privateData; + } +- +-#endif +\ No newline at end of file +diff --git a/src/util/Fiber/FiberWin.cpp b/src/util/Fiber/FiberWin.cpp +index af7df700..ae5da517 100644 +--- a/src/util/Fiber/FiberWin.cpp ++++ b/src/util/Fiber/FiberWin.cpp +@@ -1,5 +1,4 @@ + #include "Fiber.h" +-#if BOOST_OS_WINDOWS + #include <Windows.h> + + thread_local Fiber* sCurrentFiber{}; +@@ -39,5 +38,3 @@ void* Fiber::GetFiberPrivateData() + { + return sCurrentFiber->m_privateData; + } +- +-#endif +\ No newline at end of file +diff --git a/src/util/MemMapper/MemMapperUnix.cpp b/src/util/MemMapper/MemMapperUnix.cpp +index 0ea52aa0..0ade291d 100644 +--- a/src/util/MemMapper/MemMapperUnix.cpp ++++ b/src/util/MemMapper/MemMapperUnix.cpp +@@ -1,6 +1,5 @@ + #include "util/MemMapper/MemMapper.h" + +-#if BOOST_OS_LINUX || BOOST_OS_MACOS + #include <unistd.h> + #include <sys/mman.h> + +@@ -65,5 +64,3 @@ namespace MemMapper + } + + }; +- +-#endif +\ No newline at end of file +diff --git a/src/util/MemMapper/MemMapperWin.cpp b/src/util/MemMapper/MemMapperWin.cpp +index 5c07949f..0e8d3496 100644 +--- a/src/util/MemMapper/MemMapperWin.cpp ++++ b/src/util/MemMapper/MemMapperWin.cpp +@@ -1,7 +1,5 @@ + #include "util/MemMapper/MemMapper.h" + +-#if BOOST_OS_WINDOWS +- + #include <Windows.h> + + namespace MemMapper +@@ -63,5 +61,3 @@ namespace MemMapper + } + + }; +- +-#endif +\ No newline at end of file +diff --git a/src/util/SystemInfo/SystemInfo.cpp b/src/util/SystemInfo/SystemInfo.cpp +new file mode 100644 +index 00000000..afda4e8b --- /dev/null +++ b/src/util/SystemInfo/SystemInfo.cpp @@ -0,0 +1,34 @@ @@ -185,6 +341,9 @@ + out.user = user; +} \ No newline at end of file +diff --git a/src/util/SystemInfo/SystemInfo.h b/src/util/SystemInfo/SystemInfo.h +new file mode 100644 +index 00000000..72ce98db --- /dev/null +++ b/src/util/SystemInfo/SystemInfo.h @@ -0,0 +1,17 @@ @@ -193,7 +352,7 @@ +struct ProcessorTime +{ + uint64 idle{}, kernel{}, user{}; -+ ++ + uint64 work(); + uint64 total(); + @@ -204,21 +363,18 @@ +uint64 QueryRamUsage(); +void QueryProcTime(uint64 &out_now, uint64 &out_user, uint64 &out_kernel); +void QueryProcTime(ProcessorTime &out); -+void QueryCoreTimes(uint32 count, ProcessorTime out[]); -\ No newline at end of file ++void QueryCoreTimes(uint32 count, std::vector<ProcessorTime>& out); +diff --git a/src/util/SystemInfo/SystemInfoLinux.cpp b/src/util/SystemInfo/SystemInfoLinux.cpp +new file mode 100644 +index 00000000..d147893b --- /dev/null +++ b/src/util/SystemInfo/SystemInfoLinux.cpp -@@ -0,0 +1,67 @@ -+#if BOOST_OS_LINUX -+ +@@ -0,0 +1,46 @@ +#include "util/SystemInfo/SystemInfo.h" + -+#include <unistd.h> -+#include <sys/times.h> -+ +uint64 QueryRamUsage() +{ -+ long page_size = sysconf(_SC_PAGESIZE); ++ static long page_size = sysconf(_SC_PAGESIZE); + if (page_size == -1) + { + return 0; @@ -228,36 +384,22 @@ + if (file) + { + file.ignore(std::numeric_limits<std::streamsize>::max(), ' '); -+ uint64 no_pages; -+ file >> no_pages; ++ uint64 pages; ++ file >> pages; + -+ return no_pages * page_size; ++ return pages * page_size; + } -+ else -+ { -+ return 0; -+ } -+} -+ -+void QueryProcTime(uint64 &out_now, uint64 &out_user, uint64 &out_kernel) -+{ -+ struct tms time_info; -+ clock_t clock_now = times(&time_info); -+ clock_t clock_user = time_info.tms_utime; -+ clock_t clock_kernel = time_info.tms_stime; -+ out_now = static_cast<uint64>(clock_now); -+ out_user = static_cast<uint64>(clock_user); -+ out_kernel = static_cast<uint64>(clock_kernel); ++ return 0; +} + -+void QueryCoreTimes(uint32 count, ProcessorTime out[]) ++void QueryCoreTimes(uint32 count, std::vector<ProcessorTime>& out) +{ + std::ifstream file("/proc/stat"); + if (file) + { + file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); + -+ for (auto i = 0; i < count; ++i) ++ for (auto i = 0; i < out.size(); ++i) + { + uint64 user, nice, kernel, idle; + file.ignore(std::numeric_limits<std::streamsize>::max(), ' '); @@ -274,14 +416,80 @@ + for (auto i = 0; i < count; ++i) out[i] = { }; + } +} +diff --git a/src/util/SystemInfo/SystemInfoMac.cpp b/src/util/SystemInfo/SystemInfoMac.cpp +new file mode 100644 +index 00000000..608f1ffc +--- /dev/null ++++ b/src/util/SystemInfo/SystemInfoMac.cpp +@@ -0,0 +1,62 @@ ++#include "util/SystemInfo/SystemInfo.h" + -+#endif -\ No newline at end of file ++#include <unistd.h> ++#include <sys/resource.h> ++#include <sys/sysctl.h> ++#include <sys/types.h> ++#include <mach/mach.h> ++ ++#include <mach/processor_info.h> ++#include <mach/mach_host.h> ++#include <mach/kern_return.h> ++ ++// borrowed from https://en.wikichip.org/wiki/resident_set_size#OS_X ++uint64 QueryRamUsage() ++{ ++ mach_task_basic_info info; ++ mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT; ++ if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count) == KERN_SUCCESS) ++ return info.resident_size; ++ return 0; ++} ++ ++// apple official documentation is non-existsent. ++// based on https://github.com/giampaolo/psutil/blob/master/psutil/_psutil_osx.c#L623 ++void QueryCoreTimes(uint32 count, std::vector<ProcessorTime>& out) ++{ ++ // initialize default ++ for (auto i = 0; i < out.size(); ++i) ++ { ++ out[i] = {}; ++ } ++ ++ natural_t cpu_count; ++ processor_info_array_t info_array; ++ mach_msg_type_number_t info_count; ++ kern_return_t error; ++ ++ mach_port_t host_port = mach_host_self(); ++ error = host_processor_info(host_port, PROCESSOR_CPU_LOAD_INFO, &cpu_count, &info_array, &info_count); ++ mach_port_deallocate(mach_task_self(), host_port); ++ ++ if (error != KERN_SUCCESS) ++ return; ++ ++ processor_cpu_load_info_data_t* cpuLoad = (processor_cpu_load_info_data_t*) info_array; ++ ++ for (auto i = 0; i < cpu_count; ++i) ++ { ++ uint64 system = cpuLoad[i].cpu_ticks[CPU_STATE_SYSTEM]; ++ uint64 user = cpuLoad[i].cpu_ticks[CPU_STATE_USER] + cpuLoad[i].cpu_ticks[CPU_STATE_NICE]; ++ uint64 idle = cpuLoad[i].cpu_ticks[CPU_STATE_IDLE]; ++ ++ out[i].idle = idle; ++ out[i].kernel = system; ++ out[i].user = user; ++ } ++ ++ int ret = vm_deallocate(mach_task_self(), (vm_address_t) info_array, ++ info_count * sizeof(int)); ++ if (ret != KERN_SUCCESS) ++ cemuLog_force("vm_deallocate() failed"); ++} +diff --git a/src/util/SystemInfo/SystemInfoStub.cpp b/src/util/SystemInfo/SystemInfoStub.cpp +new file mode 100644 +index 00000000..b6d1fc84 --- /dev/null +++ b/src/util/SystemInfo/SystemInfoStub.cpp -@@ -0,0 +1,25 @@ -+#if !BOOST_OS_WINDOWS && !BOOST_OS_LINUX -+ +@@ -0,0 +1,21 @@ +#include "util/SystemInfo/SystemInfo.h" + +uint64 QueryRamUsage() @@ -296,21 +504,40 @@ + out_kernel = 0; +} + -+void QueryCoreTimes(uint32 count, ProcessorTime out[]) ++void QueryCoreTimes(uint32 count, std::vector<ProcessorTime>& out) +{ -+ for (auto i = 0; i < count; ++i) ++ for (auto i = 0; i < out.size(); ++i) + { + out[i] = { }; + } +} +diff --git a/src/util/SystemInfo/SystemInfoUnix.cpp b/src/util/SystemInfo/SystemInfoUnix.cpp +new file mode 100644 +index 00000000..87bd9f8c +--- /dev/null ++++ b/src/util/SystemInfo/SystemInfoUnix.cpp +@@ -0,0 +1,15 @@ ++#include "util/SystemInfo/SystemInfo.h" + -+#endif -\ No newline at end of file ++#include <sys/times.h> ++ ++void QueryProcTime(uint64 &out_now, uint64 &out_user, uint64 &out_kernel) ++{ ++ struct tms time_info; ++ clock_t clock_now = times(&time_info); ++ clock_t clock_user = time_info.tms_utime; ++ clock_t clock_kernel = time_info.tms_stime; ++ out_now = static_cast<uint64>(clock_now); ++ out_user = static_cast<uint64>(clock_user); ++ out_kernel = static_cast<uint64>(clock_kernel); ++} ++ +diff --git a/src/util/SystemInfo/SystemInfoWin.cpp b/src/util/SystemInfo/SystemInfoWin.cpp +new file mode 100644 +index 00000000..375608ce --- /dev/null +++ b/src/util/SystemInfo/SystemInfoWin.cpp -@@ -0,0 +1,72 @@ -+#if BOOST_OS_WINDOWS -+ +@@ -0,0 +1,68 @@ +#include "util/SystemInfo/SystemInfo.h" + +#include <Psapi.h> @@ -340,7 +567,7 @@ + now.HighPart = ftime.dwHighDateTime; + + if (GetProcessTimes(GetCurrentProcess(), &ftime, &ftime, &fkernel, &fuser)) -+ { ++ { + kernel.LowPart = fkernel.dwLowDateTime; + kernel.HighPart = fkernel.dwHighDateTime; + @@ -359,14 +586,14 @@ + } +} + -+void QueryCoreTimes(uint32 count, ProcessorTime out[]) ++void QueryCoreTimes(uint32 count, std::vector<ProcessorTime>& out) +{ + std::vector<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION> sppi(count); + if (NT_SUCCESS(NtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi.data(), sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * count, nullptr))) + { -+ for (auto i = 0; i < count; ++i) ++ for (auto i = 0; i < out.size(); ++i) + { -+ out[i].idle = sppi[i].IdleTime.QuadPart; ++ out[i].idle = sppi[i].IdleTime.QuadPart; + out[i].kernel = sppi[i].KernelTime.QuadPart; + out[i].user = sppi[i].UserTime.QuadPart; + } @@ -379,6 +606,3 @@ + } + } +} -+ -+#endif -\ No newline at end of file |