aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2020-11-08 21:00:54 +0100
committerGitHub <noreply@github.com>2020-11-08 17:00:54 -0300
commiteda6b78894eef3d9dc1e8ea6984e2f5bd319d68e (patch)
tree546394d268af11a550a01099014747fa8fbdcf23 /Ryujinx.HLE/HOS/Services
parent8d168574eb04ae1e7026ac2b058e3b184f068fae (diff)
apm/am: Refactoring/Unstub services (#1662)
* apm: Refactoring/Unstub service This PR implement some IPC calls of apm service: - nn::apm::IManager is fully implemented. - nn::apm::ISession is fully implemented (close #1633). - nn::apm::ISystemManager is partially implemented. nn::appletAE::ICommonStateGetter have some calls which are just a layer of apm IPC calls. What we did in some calls was wrong, it's fixed now! Everything is checked with RE. * abstract Apm *Server as Thog requested * abstract ISession and fix other classes * Address gdkchan feedback * Fix class * Fix Logging
Diffstat (limited to 'Ryujinx.HLE/HOS/Services')
-rw-r--r--Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs35
-rw-r--r--Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/IManager.cs32
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/ISession.cs33
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs42
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs31
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs25
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs12
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs58
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs28
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs6
14 files changed, 277 insertions, 37 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs
index de2281c2..f131aff8 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
// GetCommonStateGetter() -> object<nn::am::service::ICommonStateGetter>
public ResultCode GetCommonStateGetter(ServiceCtx context)
{
- MakeObject(context, new ICommonStateGetter());
+ MakeObject(context, new ICommonStateGetter(context));
return ResultCode.Success;
}
diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs
index a2113163..82e18922 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs
@@ -2,17 +2,22 @@ using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
-using Ryujinx.HLE.HOS.Services.Apm;
using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class ICommonStateGetter : IpcService
{
- private CpuBoostMode _cpuBoostMode = CpuBoostMode.Disabled;
- private bool _vrModeEnabled = false;
+ private Apm.ManagerServer apmManagerServer;
+ private Apm.SystemManagerServer apmSystemManagerServer;
- public ICommonStateGetter() { }
+ private bool _vrModeEnabled = false;
+
+ public ICommonStateGetter(ServiceCtx context)
+ {
+ apmManagerServer = new Apm.ManagerServer(context);
+ apmSystemManagerServer = new Apm.SystemManagerServer(context);
+ }
[Command(0)]
// GetEventHandle() -> handle<copy>
@@ -58,16 +63,10 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
}
[Command(6)]
- // GetPerformanceMode() -> u32
+ // GetPerformanceMode() -> nn::apm::PerformanceMode
public ResultCode GetPerformanceMode(ServiceCtx context)
{
- PerformanceMode mode = context.Device.System.State.DockedMode
- ? PerformanceMode.Docked
- : PerformanceMode.Handheld;
-
- context.ResponseData.Write((int)mode);
-
- return ResultCode.Success;
+ return (ResultCode)apmManagerServer.GetPerformanceMode(context);
}
[Command(8)]
@@ -136,12 +135,18 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
return ResultCode.InvalidParameters;
}
- _cpuBoostMode = (CpuBoostMode)cpuBoostMode;
+ apmSystemManagerServer.SetCpuBoostMode((Apm.CpuBoostMode)cpuBoostMode);
- // NOTE: There is a condition variable after the assignment, probably waiting something with apm:sys service (SetCpuBoostMode call?).
- // Since we will probably never support CPU boost things, it's not needed to implement more.
+ // TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used.
return ResultCode.Success;
}
+
+ [Command(91)] // 7.0.0+
+ // GetCurrentPerformanceConfiguration() -> nn::apm::PerformanceConfiguration
+ public ResultCode GetCurrentPerformanceConfiguration(ServiceCtx context)
+ {
+ return (ResultCode)apmSystemManagerServer.GetCurrentPerformanceConfiguration(context);
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs
index 3d3287d0..700886fd 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs
@@ -11,7 +11,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService
// GetCommonStateGetter() -> object<nn::am::service::ICommonStateGetter>
public ResultCode GetCommonStateGetter(ServiceCtx context)
{
- MakeObject(context, new ICommonStateGetter());
+ MakeObject(context, new ICommonStateGetter(context));
return ResultCode.Success;
}
diff --git a/Ryujinx.HLE/HOS/Services/Apm/IManager.cs b/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
index 19fbcd44..ae1cfba8 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
@@ -1,15 +1,41 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
- [Service("apm")] // 8.0.0+
- class IManager : IpcService
+ abstract class IManager : IpcService
{
public IManager(ServiceCtx context) { }
+ protected abstract ResultCode OpenSession(out SessionServer sessionServer);
+ protected abstract PerformanceMode GetPerformanceMode();
+ protected abstract bool IsCpuOverclockEnabled();
+
[Command(0)]
// OpenSession() -> object<nn::apm::ISession>
public ResultCode OpenSession(ServiceCtx context)
{
- MakeObject(context, new ISession());
+ ResultCode resultCode = OpenSession(out SessionServer sessionServer);
+
+ if (resultCode == ResultCode.Success)
+ {
+ MakeObject(context, sessionServer);
+ }
+
+ return resultCode;
+ }
+
+ [Command(1)]
+ // GetPerformanceMode() -> nn::apm::PerformanceMode
+ public ResultCode GetPerformanceMode(ServiceCtx context)
+ {
+ context.ResponseData.Write((uint)GetPerformanceMode());
+
+ return ResultCode.Success;
+ }
+
+ [Command(6)] // 7.0.0+
+ // IsCpuOverclockEnabled() -> bool
+ public ResultCode IsCpuOverclockEnabled(ServiceCtx context)
+ {
+ context.ResponseData.Write(IsCpuOverclockEnabled());
return ResultCode.Success;
}
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ISession.cs b/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
index a979af76..95bdf35d 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
@@ -1,30 +1,43 @@
-using Ryujinx.Common.Logging;
-
namespace Ryujinx.HLE.HOS.Services.Apm
{
- class ISession : IpcService
+ abstract class ISession : IpcService
{
- public ISession() { }
+ public ISession(ServiceCtx context) { }
+
+ protected abstract ResultCode SetPerformanceConfiguration(PerformanceMode performanceMode, PerformanceConfiguration performanceConfiguration);
+ protected abstract ResultCode GetPerformanceConfiguration(PerformanceMode performanceMode, out PerformanceConfiguration performanceConfiguration);
+ protected abstract void SetCpuOverclockEnabled(bool enabled);
[Command(0)]
// SetPerformanceConfiguration(nn::apm::PerformanceMode, nn::apm::PerformanceConfiguration)
public ResultCode SetPerformanceConfiguration(ServiceCtx context)
{
- PerformanceMode perfMode = (PerformanceMode)context.RequestData.ReadInt32();
- PerformanceConfiguration perfConfig = (PerformanceConfiguration)context.RequestData.ReadInt32();
+ PerformanceMode performanceMode = (PerformanceMode)context.RequestData.ReadInt32();
+ PerformanceConfiguration performanceConfiguration = (PerformanceConfiguration)context.RequestData.ReadInt32();
- return ResultCode.Success;
+ return SetPerformanceConfiguration(performanceMode, performanceConfiguration);
}
[Command(1)]
// GetPerformanceConfiguration(nn::apm::PerformanceMode) -> nn::apm::PerformanceConfiguration
public ResultCode GetPerformanceConfiguration(ServiceCtx context)
{
- PerformanceMode perfMode = (PerformanceMode)context.RequestData.ReadInt32();
+ PerformanceMode performanceMode = (PerformanceMode)context.RequestData.ReadInt32();
+
+ ResultCode resultCode = GetPerformanceConfiguration(performanceMode, out PerformanceConfiguration performanceConfiguration);
- context.ResponseData.Write((uint)PerformanceConfiguration.PerformanceConfiguration1);
+ context.ResponseData.Write((uint)performanceConfiguration);
+
+ return resultCode;
+ }
+
+ [Command(2)] // 8.0.0+
+ // SetCpuOverclockEnabled(bool)
+ public ResultCode SetCpuOverclockEnabled(ServiceCtx context)
+ {
+ bool enabled = context.RequestData.ReadBoolean();
- Logger.Stub?.PrintStub(LogClass.ServiceApm);
+ SetCpuOverclockEnabled(enabled);
return ResultCode.Success;
}
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs b/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs
new file mode 100644
index 00000000..f7b2f450
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs
@@ -0,0 +1,42 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ abstract class ISystemManager : IpcService
+ {
+ public ISystemManager(ServiceCtx context) { }
+
+ protected abstract void RequestPerformanceMode(PerformanceMode performanceMode);
+ internal abstract void SetCpuBoostMode(CpuBoostMode cpuBoostMode);
+ protected abstract PerformanceConfiguration GetCurrentPerformanceConfiguration();
+
+ [Command(0)]
+ // RequestPerformanceMode(nn::apm::PerformanceMode)
+ public ResultCode RequestPerformanceMode(ServiceCtx context)
+ {
+ RequestPerformanceMode((PerformanceMode)context.RequestData.ReadInt32());
+
+ // NOTE: This call seems to overclock the system related to the PerformanceMode, since we emulate it, it's fine to do nothing instead.
+
+ return ResultCode.Success;
+ }
+
+ [Command(6)] // 7.0.0+
+ // SetCpuBoostMode(nn::apm::CpuBootMode)
+ public ResultCode SetCpuBoostMode(ServiceCtx context)
+ {
+ SetCpuBoostMode((CpuBoostMode)context.RequestData.ReadUInt32());
+
+ // NOTE: This call seems to overclock the system related to the CpuBoostMode, since we emulate it, it's fine to do nothing instead.
+
+ return ResultCode.Success;
+ }
+
+ [Command(7)] // 7.0.0+
+ // GetCurrentPerformanceConfiguration() -> nn::apm::PerformanceConfiguration
+ public ResultCode GetCurrentPerformanceConfiguration(ServiceCtx context)
+ {
+ context.ResponseData.Write((uint)GetCurrentPerformanceConfiguration());
+
+ return ResultCode.Success;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs b/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs
new file mode 100644
index 00000000..af051934
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs
@@ -0,0 +1,31 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ [Service("apm")]
+ [Service("apm:am")] // 8.0.0+
+ class ManagerServer : IManager
+ {
+ private readonly ServiceCtx _context;
+
+ public ManagerServer(ServiceCtx context) : base(context)
+ {
+ _context = context;
+ }
+
+ protected override ResultCode OpenSession(out SessionServer sessionServer)
+ {
+ sessionServer = new SessionServer(_context);
+
+ return ResultCode.Success;
+ }
+
+ protected override PerformanceMode GetPerformanceMode()
+ {
+ return _context.Device.System.PerformanceState.PerformanceMode;
+ }
+
+ protected override bool IsCpuOverclockEnabled()
+ {
+ return _context.Device.System.PerformanceState.CpuOverclockEnabled;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs b/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs
new file mode 100644
index 00000000..d03bf6c7
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs
@@ -0,0 +1,25 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ class PerformanceState
+ {
+ public PerformanceState() { }
+
+ public bool CpuOverclockEnabled = false;
+
+ public PerformanceMode PerformanceMode = PerformanceMode.Default;
+ public CpuBoostMode CpuBoostMode = CpuBoostMode.Disabled;
+
+ public PerformanceConfiguration DefaultPerformanceConfiguration = PerformanceConfiguration.PerformanceConfiguration7;
+ public PerformanceConfiguration BoostPerformanceConfiguration = PerformanceConfiguration.PerformanceConfiguration8;
+
+ public PerformanceConfiguration GetCurrentPerformanceConfiguration(PerformanceMode performanceMode)
+ {
+ return performanceMode switch
+ {
+ PerformanceMode.Default => DefaultPerformanceConfiguration,
+ PerformanceMode.Boost => BoostPerformanceConfiguration,
+ _ => PerformanceConfiguration.PerformanceConfiguration7
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs
new file mode 100644
index 00000000..c4499b01
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ enum ResultCode
+ {
+ ModuleId = 148,
+ ErrorCodeShift = 9,
+
+ Success = 0,
+
+ InvalidParameters = (1 << ErrorCodeShift) | ModuleId
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs b/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs
new file mode 100644
index 00000000..3ef713cf
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs
@@ -0,0 +1,58 @@
+using Ryujinx.Common.Logging;
+
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ class SessionServer : ISession
+ {
+ private readonly ServiceCtx _context;
+
+ public SessionServer(ServiceCtx context) : base(context)
+ {
+ _context = context;
+ }
+
+ protected override ResultCode SetPerformanceConfiguration(PerformanceMode performanceMode, PerformanceConfiguration performanceConfiguration)
+ {
+ if (performanceMode > PerformanceMode.Boost)
+ {
+ return ResultCode.InvalidParameters;
+ }
+
+ switch (performanceMode)
+ {
+ case PerformanceMode.Default:
+ _context.Device.System.PerformanceState.DefaultPerformanceConfiguration = performanceConfiguration;
+ break;
+ case PerformanceMode.Boost:
+ _context.Device.System.PerformanceState.BoostPerformanceConfiguration = performanceConfiguration;
+ break;
+ default:
+ Logger.Error?.Print(LogClass.ServiceApm, $"PerformanceMode isn't supported: {performanceMode}");
+ break;
+ }
+
+ return ResultCode.Success;
+ }
+
+ protected override ResultCode GetPerformanceConfiguration(PerformanceMode performanceMode, out PerformanceConfiguration performanceConfiguration)
+ {
+ if (performanceMode > PerformanceMode.Boost)
+ {
+ performanceConfiguration = 0;
+
+ return ResultCode.InvalidParameters;
+ }
+
+ performanceConfiguration = _context.Device.System.PerformanceState.GetCurrentPerformanceConfiguration(performanceMode);
+
+ return ResultCode.Success;
+ }
+
+ protected override void SetCpuOverclockEnabled(bool enabled)
+ {
+ _context.Device.System.PerformanceState.CpuOverclockEnabled = enabled;
+
+ // NOTE: This call seems to overclock the system, since we emulate it, it's fine to do nothing instead.
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs b/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs
new file mode 100644
index 00000000..a6264236
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs
@@ -0,0 +1,28 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ [Service("apm:sys")]
+ class SystemManagerServer : ISystemManager
+ {
+ private readonly ServiceCtx _context;
+
+ public SystemManagerServer(ServiceCtx context) : base(context)
+ {
+ _context = context;
+ }
+
+ protected override void RequestPerformanceMode(PerformanceMode performanceMode)
+ {
+ _context.Device.System.PerformanceState.PerformanceMode = performanceMode;
+ }
+
+ internal override void SetCpuBoostMode(CpuBoostMode cpuBoostMode)
+ {
+ _context.Device.System.PerformanceState.CpuBoostMode = cpuBoostMode;
+ }
+
+ protected override PerformanceConfiguration GetCurrentPerformanceConfiguration()
+ {
+ return _context.Device.System.PerformanceState.GetCurrentPerformanceConfiguration(_context.Device.System.PerformanceState.PerformanceMode);
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs b/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
index a4c87d3c..587142c8 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
@@ -2,8 +2,8 @@
{
enum CpuBoostMode
{
- Disabled = 0,
- Mode1 = 1, // Use PerformanceConfiguration13 and PerformanceConfiguration14, or PerformanceConfiguration15 and PerformanceConfiguration16
- Mode2 = 2 // Use PerformanceConfiguration15 and PerformanceConfiguration16.
+ Disabled = 0,
+ BoostCPU = 1, // Uses PerformanceConfiguration13 and PerformanceConfiguration14, or PerformanceConfiguration15 and PerformanceConfiguration16
+ ConservePower = 2 // Uses PerformanceConfiguration15 and PerformanceConfiguration16.
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
index e42edebc..e8c5752e 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
- enum PerformanceConfiguration : uint // Clocks are all in MHz.
+ enum PerformanceConfiguration : uint // Clocks are all in MHz.
{ // CPU | GPU | RAM | NOTE
PerformanceConfiguration1 = 0x00010000, // 1020 | 384 | 1600 | Only available while docked.
PerformanceConfiguration2 = 0x00010001, // 1020 | 768 | 1600 | Only available while docked.
diff --git a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
index a7a0dfad..6d6f9643 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
@@ -1,8 +1,8 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
- enum PerformanceMode
+ enum PerformanceMode : uint
{
- Handheld = 0,
- Docked = 1
+ Default = 0,
+ Boost = 1
}
} \ No newline at end of file