Compare commits
35 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87d5427e2e | ||
|
|
1a14c9faa4 | ||
|
|
3e8a085055 | ||
|
|
f28410645d | ||
|
|
d17c199880 | ||
|
|
cff69aeb08 | ||
|
|
2c9b8e6d09 | ||
|
|
e727360fad | ||
|
|
bff7f49cea | ||
|
|
c8e4cd456a | ||
|
|
7517610a1c | ||
|
|
7d0f573110 | ||
|
|
c94ac092b5 | ||
|
|
0deeecd33f | ||
|
|
22347e8844 | ||
|
|
af1ca87be1 | ||
|
|
2678dbfbe6 | ||
|
|
b1712b8312 | ||
|
|
92801b1c34 | ||
|
|
f3264dd78d | ||
|
|
ebd613c2cc | ||
|
|
2adde6ae8b | ||
|
|
554cc9488f | ||
|
|
71eeab257f | ||
|
|
7bedea73a8 | ||
|
|
d81a984d4a | ||
|
|
2e8246a02c | ||
|
|
7a50d56d0e | ||
|
|
f4a3d28224 | ||
|
|
979483c7dd | ||
|
|
b20dfb357b | ||
|
|
115d3e133f | ||
|
|
22659afcd0 | ||
|
|
974362bc12 | ||
|
|
bd58c5470c |
@@ -8,7 +8,7 @@ COMPRESSION_FLAGS="-cJvf"
|
||||
|
||||
mkdir "$REV_NAME"
|
||||
|
||||
cp build/bin/yuzu-cmd "$REV_NAME"
|
||||
cp build/bin/yuzu "$REV_NAME"
|
||||
cp build/src/yuzu_cmd/yuzu-cmd "$REV_NAME"
|
||||
cp build/src/yuzu/yuzu "$REV_NAME"
|
||||
|
||||
. .travis/common/post-upload.sh
|
||||
|
||||
@@ -8,8 +8,8 @@ COMPRESSION_FLAGS="-czvf"
|
||||
|
||||
mkdir "$REV_NAME"
|
||||
|
||||
cp build/bin/yuzu-cmd "$REV_NAME"
|
||||
cp -r build/bin/yuzu.app "$REV_NAME"
|
||||
cp build/src/yuzu_cmd/yuzu-cmd "$REV_NAME"
|
||||
cp -r build/src/yuzu/yuzu.app "$REV_NAME"
|
||||
|
||||
# move qt libs into app bundle for deployment
|
||||
$(brew --prefix)/opt/qt5/bin/macdeployqt "${REV_NAME}/yuzu.app"
|
||||
|
||||
@@ -7,10 +7,10 @@ include(DownloadExternals)
|
||||
project(yuzu)
|
||||
|
||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||
option(CITRA_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF)
|
||||
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF)
|
||||
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF)
|
||||
option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" OFF)
|
||||
|
||||
option(YUZU_USE_BUNDLED_UNICORN "Download bundled Unicorn binaries" OFF)
|
||||
|
||||
@@ -134,6 +134,12 @@ else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
# Fix GCC C++17 and Boost.ICL incompatibility (needed to build dynarmic)
|
||||
# See https://bugzilla.redhat.com/show_bug.cgi?id=1485641#c1
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-new-ttp-matching")
|
||||
endif()
|
||||
|
||||
# Set file offset size to 64 bits.
|
||||
#
|
||||
# On modern Unixes, this is typically already the case. The lone exception is
|
||||
@@ -160,15 +166,12 @@ if (NOT Boost_FOUND)
|
||||
find_package(Boost QUIET REQUIRED)
|
||||
endif()
|
||||
|
||||
# Output binaries to bin/
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
# Prefer the -pthread flag on Linux.
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if (ENABLE_SDL2)
|
||||
if (CITRA_USE_BUNDLED_SDL2)
|
||||
if (YUZU_USE_BUNDLED_SDL2)
|
||||
# Detect toolchain and platform
|
||||
if (MSVC14 AND ARCHITECTURE_x86_64)
|
||||
set(SDL2_VER "SDL2-2.0.5")
|
||||
@@ -229,7 +232,7 @@ if (UNICORN_FOUND)
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT)
|
||||
if (CITRA_USE_BUNDLED_QT)
|
||||
if (YUZU_USE_BUNDLED_QT)
|
||||
if (MSVC14 AND ARCHITECTURE_x86_64)
|
||||
set(QT_VER qt-5.7-msvc2015_64)
|
||||
else()
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
yuzu emulator
|
||||
=============
|
||||
[](https://travis-ci.org/yuzu-emu/yuzu)
|
||||
|
||||
yuzu is an experimental open-source emulator for the Nintendo Switch from the creators of [Citra](https://citra-emu.org/).
|
||||
|
||||
It is written in C++ with portability in mind, with builds actively maintained for Windows, Linux and macOS. The emulator is currently only useful for homebrew development and research purposes.
|
||||
|
||||
@@ -13,7 +13,7 @@ environment:
|
||||
# Tell msys2 to inherit the current directory when starting the shell
|
||||
CHERE_INVOKING: 1
|
||||
matrix:
|
||||
- BUILD_TYPE: mingw
|
||||
#- BUILD_TYPE: mingw
|
||||
- BUILD_TYPE: msvc
|
||||
|
||||
platform:
|
||||
@@ -36,6 +36,12 @@ install:
|
||||
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S $dependencies" 2> $null
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
$dependecies = "SDL2-2.0.5"
|
||||
"unicorn-yuzu"
|
||||
"qt-5.7-msvc2015_64"
|
||||
}
|
||||
before_build:
|
||||
- mkdir %BUILD_TYPE%_build
|
||||
- cd %BUILD_TYPE%_build
|
||||
|
||||
8
externals/microprofile/microprofileui.h
vendored
8
externals/microprofile/microprofileui.h
vendored
@@ -1853,7 +1853,7 @@ void MicroProfileDrawBarView(uint32_t nScreenWidth, uint32_t nScreenHeight)
|
||||
{
|
||||
if(nMetaIndex < MICROPROFILE_META_MAX && S.MetaCounters[nMetaIndex].pName)
|
||||
{
|
||||
uint32_t nStrWidth = strlen(S.MetaCounters[nMetaIndex].pName);
|
||||
uint32_t nStrWidth = static_cast<uint32_t>(strlen(S.MetaCounters[nMetaIndex].pName));
|
||||
if(S.nBars & MP_DRAW_TIMERS)
|
||||
nWidth += 6 + (1+MICROPROFILE_TEXT_WIDTH) * (nStrWidth);
|
||||
if(S.nBars & MP_DRAW_AVERAGE)
|
||||
@@ -1907,7 +1907,7 @@ void MicroProfileDrawBarView(uint32_t nScreenWidth, uint32_t nScreenHeight)
|
||||
{
|
||||
if(0 != (S.nBars & (MP_DRAW_META_FIRST<<i)) && S.MetaCounters[i].pName)
|
||||
{
|
||||
uint32_t nBufferSize = strlen(S.MetaCounters[i].pName) + 32;
|
||||
uint32_t nBufferSize = static_cast<uint32_t>(strlen(S.MetaCounters[i].pName) + 32);
|
||||
char* buffer = (char*)alloca(nBufferSize);
|
||||
if(S.nBars & MP_DRAW_TIMERS)
|
||||
nX += MicroProfileDrawBarMetaCount(nX, nY, &S.MetaCounters[i].nCounters[0], S.MetaCounters[i].pName, nTotalHeight) + 1;
|
||||
@@ -2599,7 +2599,7 @@ void MicroProfileDrawCustom(uint32_t nWidth, uint32_t nHeight)
|
||||
nOffsetY = nOffsetYBase;
|
||||
float* pMs = pCustom->nFlags & MICROPROFILE_CUSTOM_BAR_SOURCE_MAX ? pTimeMax : pTimeAvg;
|
||||
const char* pString = pCustom->nFlags & MICROPROFILE_CUSTOM_BAR_SOURCE_MAX ? "Max" : "Avg";
|
||||
MicroProfileDrawText(nMaxOffsetX, nOffsetY, (uint32_t)-1, pString, strlen(pString));
|
||||
MicroProfileDrawText(nMaxOffsetX, nOffsetY, (uint32_t)-1, pString, static_cast<uint32_t>(strlen(pString)));
|
||||
int nSize = snprintf(Buffer, sizeof(Buffer)-1, "%6.2fms", fReference);
|
||||
MicroProfileDrawText(nReducedWidth - (1+nSize) * (MICROPROFILE_TEXT_WIDTH+1), nOffsetY, (uint32_t)-1, Buffer, nSize);
|
||||
for(uint32_t i = 0; i < nCount; ++i)
|
||||
@@ -2613,7 +2613,7 @@ void MicroProfileDrawCustom(uint32_t nWidth, uint32_t nHeight)
|
||||
{
|
||||
nOffsetY += 2*(1+MICROPROFILE_TEXT_HEIGHT);
|
||||
const char* pString = pCustom->nFlags & MICROPROFILE_CUSTOM_STACK_SOURCE_MAX ? "Max" : "Avg";
|
||||
MicroProfileDrawText(MICROPROFILE_CUSTOM_PADDING, nOffsetY, (uint32_t)-1, pString, strlen(pString));
|
||||
MicroProfileDrawText(MICROPROFILE_CUSTOM_PADDING, nOffsetY, (uint32_t)-1, pString, static_cast<uint32_t>(strlen(pString)));
|
||||
int nSize = snprintf(Buffer, sizeof(Buffer)-1, "%6.2fms", fReference);
|
||||
MicroProfileDrawText(nReducedWidth - (1+nSize) * (MICROPROFILE_TEXT_WIDTH+1), nOffsetY, (uint32_t)-1, Buffer, nSize);
|
||||
nOffsetY += (1+MICROPROFILE_TEXT_HEIGHT);
|
||||
|
||||
@@ -41,6 +41,8 @@ set(SRCS
|
||||
hle/service/am/applet_oe.cpp
|
||||
hle/service/aoc/aoc_u.cpp
|
||||
hle/service/apm/apm.cpp
|
||||
hle/service/audio/audio.cpp
|
||||
hle/service/audio/audout_u.cpp
|
||||
hle/service/hid/hid.cpp
|
||||
hle/service/lm/lm.cpp
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.cpp
|
||||
@@ -53,6 +55,8 @@ set(SRCS
|
||||
hle/service/service.cpp
|
||||
hle/service/sm/controller.cpp
|
||||
hle/service/sm/sm.cpp
|
||||
hle/service/time/time.cpp
|
||||
hle/service/time/time_s.cpp
|
||||
hle/service/vi/vi.cpp
|
||||
hle/service/vi/vi_m.cpp
|
||||
hle/shared_page.cpp
|
||||
@@ -124,6 +128,8 @@ set(HEADERS
|
||||
hle/service/am/applet_oe.h
|
||||
hle/service/aoc/aoc_u.h
|
||||
hle/service/apm/apm.h
|
||||
hle/service/audio/audio.h
|
||||
hle/service/audio/audout_u.h
|
||||
hle/service/hid/hid.h
|
||||
hle/service/lm/lm.h
|
||||
hle/service/nvdrv/devices/nvdevice.h
|
||||
@@ -137,6 +143,8 @@ set(HEADERS
|
||||
hle/service/service.h
|
||||
hle/service/sm/controller.h
|
||||
hle/service/sm/sm.h
|
||||
hle/service/time/time.h
|
||||
hle/service/time/time_s.h
|
||||
hle/service/vi/vi.h
|
||||
hle/service/vi/vi_m.h
|
||||
hle/shared_page.h
|
||||
|
||||
@@ -35,7 +35,7 @@ enum class HandleType : u32 {
|
||||
};
|
||||
|
||||
enum {
|
||||
DEFAULT_STACK_SIZE = 0x4000,
|
||||
DEFAULT_STACK_SIZE = 0x10000,
|
||||
};
|
||||
|
||||
enum class ResetType {
|
||||
|
||||
@@ -106,14 +106,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
|
||||
// Error out if the requested permissions don't match what the creator process allows.
|
||||
if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
// Heap-backed memory blocks can not be mapped with other_permissions = DontCare
|
||||
if (base_address != 0 && other_permissions == MemoryPermission::DontCare) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
// Error out if the provided permissions are not compatible with what the creator process needs.
|
||||
if (other_permissions != MemoryPermission::DontCare &&
|
||||
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_WRONG_PERMISSION;
|
||||
}
|
||||
@@ -136,8 +136,8 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
// can not map it in its own address space unless it was created with addr=0, result 0xD900182C.
|
||||
|
||||
if (address != 0) {
|
||||
if (address < Memory::HEAP_VADDR || address + size >= Memory::SHARED_MEMORY_VADDR_END) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, invalid address",
|
||||
if (address < Memory::HEAP_VADDR) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, invalid address",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
if (result.Failed()) {
|
||||
LOG_ERROR(
|
||||
Kernel,
|
||||
"cannot map id=%u, target_address=0x%08X name=%s, error mapping to virtual memory",
|
||||
"cannot map id=%u, target_address=0x%llx name=%s, error mapping to virtual memory",
|
||||
GetObjectId(), target_address, name.c_str());
|
||||
return result.Code();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "core/hle/kernel/object_address_table.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/resource_limit.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/kernel/svc.h"
|
||||
#include "core/hle/kernel/svc_wrap.h"
|
||||
#include "core/hle/kernel/sync_object.h"
|
||||
@@ -384,6 +385,37 @@ static u32 GetCurrentProcessorNumber() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size,
|
||||
u32 permissions) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X",
|
||||
shared_memory_handle, addr, size, permissions);
|
||||
|
||||
SharedPtr<SharedMemory> shared_memory =
|
||||
Kernel::g_handle_table.Get<SharedMemory>(shared_memory_handle);
|
||||
if (!shared_memory) {
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
MemoryPermission permissions_type = static_cast<MemoryPermission>(permissions);
|
||||
switch (permissions_type) {
|
||||
case MemoryPermission::Read:
|
||||
case MemoryPermission::Write:
|
||||
case MemoryPermission::ReadWrite:
|
||||
case MemoryPermission::Execute:
|
||||
case MemoryPermission::ReadExecute:
|
||||
case MemoryPermission::WriteExecute:
|
||||
case MemoryPermission::ReadWriteExecute:
|
||||
case MemoryPermission::DontCare:
|
||||
return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type,
|
||||
MemoryPermission::DontCare);
|
||||
default:
|
||||
LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Query process memory
|
||||
static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/,
|
||||
Handle process_handle, u64 addr) {
|
||||
@@ -707,7 +739,7 @@ static const FunctionDef SVC_Table[] = {
|
||||
{0x10, SvcWrap<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"},
|
||||
{0x11, nullptr, "SignalEvent"},
|
||||
{0x12, nullptr, "ClearEvent"},
|
||||
{0x13, nullptr, "MapSharedMemory"},
|
||||
{0x13, SvcWrap<MapSharedMemory>, "MapSharedMemory"},
|
||||
{0x14, nullptr, "UnmapSharedMemory"},
|
||||
{0x15, SvcWrap<CreateTransferMemory>, "CreateTransferMemory"},
|
||||
{0x16, SvcWrap<CloseHandle>, "CloseHandle"},
|
||||
|
||||
@@ -86,6 +86,11 @@ void SvcWrap() {
|
||||
FuncReturn(func(PARAM(0), PARAM(1), PARAM(2)).raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(u32, u64, u64, u32)>
|
||||
void SvcWrap() {
|
||||
FuncReturn(func((u32)PARAM(0), PARAM(1), PARAM(2), (u32)PARAM(3)).raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(u32*, u64, u64, s64)>
|
||||
void SvcWrap() {
|
||||
u32 param_1 = 0;
|
||||
|
||||
@@ -81,7 +81,7 @@ private:
|
||||
void ReceiveMessage(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(1);
|
||||
rb.Push<u32>(15);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
16
src/core/hle/service/audio/audio.cpp
Normal file
16
src/core/hle/service/audio/audio.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/audio/audio.h"
|
||||
#include "core/hle/service/audio/audout_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<AudOutU>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
16
src/core/hle/service/audio/audio.h
Normal file
16
src/core/hle/service/audio/audio.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
/// Registers all Audio services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
26
src/core/hle/service/audio/audout_u.cpp
Normal file
26
src/core/hle/service/audio/audout_u.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/audio/audout_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
AudOutU::AudOutU() : ServiceFramework("audout:u") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &AudOutU::ListAudioOuts, "ListAudioOuts"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
23
src/core/hle/service/audio/audout_u.h
Normal file
23
src/core/hle/service/audio/audout_u.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
class AudOutU final : public ServiceFramework<AudOutU> {
|
||||
public:
|
||||
AudOutU();
|
||||
~AudOutU() = default;
|
||||
|
||||
private:
|
||||
void ListAudioOuts(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
@@ -1,19 +1,74 @@
|
||||
// Copyright 2015 Citra Emulator Project
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace HID {
|
||||
|
||||
void Init() {}
|
||||
class IAppletResource final : public ServiceFramework<IAppletResource> {
|
||||
public:
|
||||
IAppletResource() : ServiceFramework("IAppletResource") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
void Shutdown() {}
|
||||
shared_mem = Kernel::SharedMemory::Create(
|
||||
nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read,
|
||||
0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
|
||||
}
|
||||
|
||||
private:
|
||||
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(shared_mem);
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
// Handle to shared memory region designated to HID service
|
||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
|
||||
};
|
||||
|
||||
class Hid final : public ServiceFramework<Hid> {
|
||||
public:
|
||||
Hid() : ServiceFramework("hid") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &Hid::CreateAppletResource, "CreateAppletResource"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
~Hid() = default;
|
||||
|
||||
private:
|
||||
void CreateAppletResource(Kernel::HLERequestContext& ctx) {
|
||||
auto client_port = std::make_shared<IAppletResource>()->CreatePort();
|
||||
auto session = client_port->Connect();
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service, "called, initialized IAppletResource -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void ReloadInputDevices() {}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<Hid>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace HID
|
||||
} // namespace Service
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
// Copyright 2015 Citra Emulator Project
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace HID {
|
||||
|
||||
/// Initialize HID service
|
||||
void Init();
|
||||
|
||||
/// Shutdown HID service
|
||||
void Shutdown();
|
||||
|
||||
/// Reload input devices. Used when input configuration changed
|
||||
void ReloadInputDevices();
|
||||
|
||||
/// Registers all HID services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace HID
|
||||
} // namespace Service
|
||||
|
||||
@@ -144,7 +144,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service_SM, "called, initialized logger -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 1, 0, 1};
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
registered_loggers.emplace_back(std::move(client_port));
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "core/hle/service/am/am.h"
|
||||
#include "core/hle/service/aoc/aoc_u.h"
|
||||
#include "core/hle/service/apm/apm.h"
|
||||
#include "core/hle/service/audio/audio.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/lm/lm.h"
|
||||
#include "core/hle/service/nvdrv/nvdrv.h"
|
||||
@@ -24,6 +25,7 @@
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/controller.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "core/hle/service/time/time.h"
|
||||
#include "core/hle/service/vi/vi.h"
|
||||
|
||||
using Kernel::ClientPort;
|
||||
@@ -78,7 +80,8 @@ Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
|
||||
ASSERT(port == nullptr);
|
||||
Kernel::SharedPtr<Kernel::ServerPort> server_port;
|
||||
Kernel::SharedPtr<Kernel::ClientPort> client_port;
|
||||
std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, service_name);
|
||||
std::tie(server_port, client_port) =
|
||||
Kernel::ServerPort::CreatePortPair(max_sessions, service_name);
|
||||
port = MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)).Unwrap();
|
||||
port->SetHleHandler(shared_from_this());
|
||||
return client_port;
|
||||
@@ -164,20 +167,19 @@ void Init() {
|
||||
AM::InstallInterfaces(*SM::g_service_manager);
|
||||
AOC::InstallInterfaces(*SM::g_service_manager);
|
||||
APM::InstallInterfaces(*SM::g_service_manager);
|
||||
Audio::InstallInterfaces(*SM::g_service_manager);
|
||||
HID::InstallInterfaces(*SM::g_service_manager);
|
||||
LM::InstallInterfaces(*SM::g_service_manager);
|
||||
NVDRV::InstallInterfaces(*SM::g_service_manager);
|
||||
PCTL::InstallInterfaces(*SM::g_service_manager);
|
||||
Time::InstallInterfaces(*SM::g_service_manager);
|
||||
VI::InstallInterfaces(*SM::g_service_manager);
|
||||
|
||||
HID::Init();
|
||||
|
||||
LOG_DEBUG(Service, "initialized OK");
|
||||
}
|
||||
|
||||
/// Shutdown ServiceManager
|
||||
void Shutdown() {
|
||||
HID::Shutdown();
|
||||
|
||||
SM::g_service_manager = nullptr;
|
||||
g_kernel_named_ports.clear();
|
||||
LOG_DEBUG(Service, "shutdown OK");
|
||||
|
||||
16
src/core/hle/service/time/time.cpp
Normal file
16
src/core/hle/service/time/time.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/time/time.h"
|
||||
#include "core/hle/service/time/time_s.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<TimeS>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Time
|
||||
} // namespace Service
|
||||
16
src/core/hle/service/time/time.h
Normal file
16
src/core/hle/service/time/time.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
/// Registers all Time services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Time
|
||||
} // namespace Service
|
||||
58
src/core/hle/service/time/time_s.cpp
Normal file
58
src/core/hle/service/time/time_s.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/service/time/time_s.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
class ISystemClock final : public ServiceFramework<ISystemClock> {
|
||||
public:
|
||||
ISystemClock() : ServiceFramework("ISystemClock") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISystemClock::GetCurrentTime, "GetCurrentTime"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetCurrentTime(Kernel::HLERequestContext& ctx) {
|
||||
const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count()};
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(time_since_epoch);
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
void TimeS::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) {
|
||||
auto client_port = std::make_shared<ISystemClock>()->CreatePort();
|
||||
auto session = client_port->Connect();
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
TimeS::TimeS() : ServiceFramework("time:s") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &TimeS::GetStandardUserSystemClock, "GetStandardUserSystemClock"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Time
|
||||
} // namespace Service
|
||||
23
src/core/hle/service/time/time_s.h
Normal file
23
src/core/hle/service/time/time_s.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
class TimeS final : public ServiceFramework<TimeS> {
|
||||
public:
|
||||
TimeS();
|
||||
~TimeS() = default;
|
||||
|
||||
private:
|
||||
void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Time
|
||||
} // namespace Service
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "core/hle/service/nvdrv/nvdrv_a.h"
|
||||
#include "core/hle/service/vi/vi.h"
|
||||
#include "core/hle/service/vi/vi_m.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
namespace Service {
|
||||
namespace VI {
|
||||
@@ -492,6 +494,7 @@ public:
|
||||
IManagerDisplayService(std::shared_ptr<NVFlinger> nv_flinger)
|
||||
: ServiceFramework("IManagerDisplayService"), nv_flinger(std::move(nv_flinger)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1020, &IManagerDisplayService::CloseDisplay, "CloseDisplay"},
|
||||
{1102, nullptr, "GetDisplayResolution"},
|
||||
{2010, &IManagerDisplayService::CreateManagedLayer, "CreateManagedLayer"},
|
||||
{6000, &IManagerDisplayService::AddToLayerStack, "AddToLayerStack"},
|
||||
@@ -501,6 +504,15 @@ public:
|
||||
~IManagerDisplayService() = default;
|
||||
|
||||
private:
|
||||
void CloseDisplay(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
u64 display = rp.Pop<u64>();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void CreateManagedLayer(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
@@ -743,7 +755,8 @@ void NVFlinger::Compose() {
|
||||
auto buffer = buffer_queue->AcquireBuffer();
|
||||
|
||||
if (buffer == boost::none) {
|
||||
// There was no queued buffer to draw.
|
||||
// There was no queued buffer to draw, render previous frame
|
||||
VideoCore::g_renderer->SwapBuffers({});
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <boost/optional.hpp>
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
virtual ~RendererBase() {}
|
||||
|
||||
/// Swap buffers (render frame)
|
||||
virtual void SwapBuffers(const FramebufferInfo& framebuffer_info) = 0;
|
||||
virtual void SwapBuffers(boost::optional<const FramebufferInfo&> framebuffer_info) = 0;
|
||||
|
||||
/**
|
||||
* Set the emulator window to use for renderer
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <glad/glad.h>
|
||||
#include "common/assert.h"
|
||||
@@ -98,20 +98,23 @@ RendererOpenGL::RendererOpenGL() = default;
|
||||
RendererOpenGL::~RendererOpenGL() = default;
|
||||
|
||||
/// Swap buffers (render frame)
|
||||
void RendererOpenGL::SwapBuffers(const FramebufferInfo& framebuffer_info) {
|
||||
void RendererOpenGL::SwapBuffers(boost::optional<const FramebufferInfo&> framebuffer_info) {
|
||||
// Maintain the rasterizer's state as a priority
|
||||
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||
state.Apply();
|
||||
|
||||
if (screen_info.texture.width != (GLsizei)framebuffer_info.width ||
|
||||
screen_info.texture.height != (GLsizei)framebuffer_info.height ||
|
||||
screen_info.texture.pixel_format != framebuffer_info.pixel_format) {
|
||||
// Reallocate texture if the framebuffer size has changed.
|
||||
// This is expected to not happen very often and hence should not be a
|
||||
// performance problem.
|
||||
ConfigureFramebufferTexture(screen_info.texture, framebuffer_info);
|
||||
if (framebuffer_info != boost::none) {
|
||||
// If framebuffer_info is provided, reload it from memory to a texture
|
||||
if (screen_info.texture.width != (GLsizei)framebuffer_info->width ||
|
||||
screen_info.texture.height != (GLsizei)framebuffer_info->height ||
|
||||
screen_info.texture.pixel_format != framebuffer_info->pixel_format) {
|
||||
// Reallocate texture if the framebuffer size has changed.
|
||||
// This is expected to not happen very often and hence should not be a
|
||||
// performance problem.
|
||||
ConfigureFramebufferTexture(screen_info.texture, *framebuffer_info);
|
||||
}
|
||||
LoadFBToScreenInfo(*framebuffer_info, screen_info);
|
||||
}
|
||||
LoadFBToScreenInfo(framebuffer_info, screen_info);
|
||||
|
||||
DrawScreens();
|
||||
|
||||
@@ -290,16 +293,16 @@ void RendererOpenGL::LoadFBToScreenInfo(const FramebufferInfo& framebuffer_info,
|
||||
* Fills active OpenGL texture with the given RGB color. Since the color is solid, the texture can
|
||||
* be 1x1 but will stretch across whatever it's rendered on.
|
||||
*/
|
||||
void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
|
||||
void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
|
||||
const TextureInfo& texture) {
|
||||
state.texture_units[0].texture_2d = texture.resource.handle;
|
||||
state.Apply();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
u8 framebuffer_data[3] = {color_r, color_g, color_b};
|
||||
u8 framebuffer_data[4] = {color_a, color_b, color_g, color_r};
|
||||
|
||||
// Update existing texture
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data);
|
||||
|
||||
state.texture_units[0].texture_2d = 0;
|
||||
state.Apply();
|
||||
@@ -361,6 +364,9 @@ void RendererOpenGL::InitOpenGLObjects() {
|
||||
|
||||
state.texture_units[0].texture_2d = 0;
|
||||
state.Apply();
|
||||
|
||||
// Clear screen to black
|
||||
LoadColorToActiveGLTexture(0, 0, 0, 0, screen_info.texture);
|
||||
}
|
||||
|
||||
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
~RendererOpenGL() override;
|
||||
|
||||
/// Swap buffers (render frame)
|
||||
void SwapBuffers(const FramebufferInfo& framebuffer_info) override;
|
||||
void SwapBuffers(boost::optional<const FramebufferInfo&> framebuffer_info) override;
|
||||
|
||||
/**
|
||||
* Set the emulator window to use for renderer
|
||||
@@ -53,17 +53,15 @@ public:
|
||||
|
||||
private:
|
||||
void InitOpenGLObjects();
|
||||
void ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
const FramebufferInfo& framebuffer_info);
|
||||
void ConfigureFramebufferTexture(TextureInfo& texture, const FramebufferInfo& framebuffer_info);
|
||||
void DrawScreens();
|
||||
void DrawSingleScreen(const ScreenInfo& screen_info, float x, float y, float w, float h);
|
||||
void UpdateFramerate();
|
||||
|
||||
// Loads framebuffer from emulated memory into the display information structure
|
||||
void LoadFBToScreenInfo(const FramebufferInfo& framebuffer_info,
|
||||
ScreenInfo& screen_info);
|
||||
// Fills active OpenGL texture with the given RGB color.
|
||||
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture);
|
||||
void LoadFBToScreenInfo(const FramebufferInfo& framebuffer_info, ScreenInfo& screen_info);
|
||||
// Fills active OpenGL texture with the given RGBA color.
|
||||
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, const TextureInfo& texture);
|
||||
|
||||
EmuWindow* render_window; ///< Handle to render window
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt;">yuzu is an experimental open-source emulator for the Nintendo Switch licensed under GPLv2.0 or any later version.</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt;">yuzu is an experimental open-source emulator for the Nintendo Switch licensed under GPLv2.0.</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt;">This software should not be used to play games you have not legally obtained.</span></p></body></html></string>
|
||||
</property>
|
||||
|
||||
Reference in New Issue
Block a user