mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-19 06:42:01 +00:00
Port from OpenTK.NETCore to OpenTK.NetStandard (#176)
* Minor code changes * Forgot to remove a method
This commit is contained in:
parent
53ebbcfbd9
commit
a4020bb398
8 changed files with 108 additions and 100 deletions
|
@ -1,11 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK.NETCore" Version="1.1.2749.6433" />
|
||||
<PackageReference Include="OpenTK.NetStandard" Version="1.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -23,8 +23,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
OGLEnumConverter.GetBlendEquation(Equation));
|
||||
|
||||
GL.BlendFunc(
|
||||
OGLEnumConverter.GetBlendFactorSrc(FuncSrc),
|
||||
OGLEnumConverter.GetBlendFactorDst(FuncDst));
|
||||
OGLEnumConverter.GetBlendFactor(FuncSrc),
|
||||
OGLEnumConverter.GetBlendFactor(FuncDst));
|
||||
}
|
||||
|
||||
public void SetSeparate(
|
||||
|
@ -40,10 +40,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
OGLEnumConverter.GetBlendEquation(EquationAlpha));
|
||||
|
||||
GL.BlendFuncSeparate(
|
||||
OGLEnumConverter.GetBlendFactorSrc(FuncSrcRgb),
|
||||
OGLEnumConverter.GetBlendFactorDst(FuncDstRgb),
|
||||
OGLEnumConverter.GetBlendFactorSrc(FuncSrcAlpha),
|
||||
OGLEnumConverter.GetBlendFactorDst(FuncDstAlpha));
|
||||
(BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcRgb),
|
||||
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstRgb),
|
||||
(BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcAlpha),
|
||||
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstAlpha));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -73,16 +73,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
throw new NotImplementedException(Format.ToString());
|
||||
}
|
||||
|
||||
public static PixelInternalFormat GetCompressedTextureFormat(GalTextureFormat Format)
|
||||
public static InternalFormat GetCompressedTextureFormat(GalTextureFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalTextureFormat.BC7U: return PixelInternalFormat.CompressedRgbaBptcUnorm;
|
||||
case GalTextureFormat.BC1: return PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
|
||||
case GalTextureFormat.BC2: return PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
|
||||
case GalTextureFormat.BC3: return PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
|
||||
case GalTextureFormat.BC4: return PixelInternalFormat.CompressedRedRgtc1;
|
||||
case GalTextureFormat.BC5: return PixelInternalFormat.CompressedRgRgtc2;
|
||||
case GalTextureFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm;
|
||||
case GalTextureFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext;
|
||||
case GalTextureFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext;
|
||||
case GalTextureFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext;
|
||||
case GalTextureFormat.BC4: return InternalFormat.CompressedRedRgtc1;
|
||||
case GalTextureFormat.BC5: return InternalFormat.CompressedRgRgtc2;
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
|
@ -162,57 +162,29 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
throw new ArgumentException(nameof(BlendEquation));
|
||||
}
|
||||
|
||||
public static BlendingFactorSrc GetBlendFactorSrc(GalBlendFactor BlendFactor)
|
||||
public static BlendingFactor GetBlendFactor(GalBlendFactor BlendFactor)
|
||||
{
|
||||
switch (BlendFactor)
|
||||
{
|
||||
case GalBlendFactor.Zero: return BlendingFactorSrc.Zero;
|
||||
case GalBlendFactor.One: return BlendingFactorSrc.One;
|
||||
case GalBlendFactor.SrcColor: return BlendingFactorSrc.SrcColor;
|
||||
case GalBlendFactor.OneMinusSrcColor: return BlendingFactorSrc.OneMinusSrcColor;
|
||||
case GalBlendFactor.DstColor: return BlendingFactorSrc.DstColor;
|
||||
case GalBlendFactor.OneMinusDstColor: return BlendingFactorSrc.OneMinusDstColor;
|
||||
case GalBlendFactor.SrcAlpha: return BlendingFactorSrc.SrcAlpha;
|
||||
case GalBlendFactor.OneMinusSrcAlpha: return BlendingFactorSrc.OneMinusSrcAlpha;
|
||||
case GalBlendFactor.DstAlpha: return BlendingFactorSrc.DstAlpha;
|
||||
case GalBlendFactor.OneMinusDstAlpha: return BlendingFactorSrc.OneMinusDstAlpha;
|
||||
case GalBlendFactor.ConstantColor: return BlendingFactorSrc.ConstantColor;
|
||||
case GalBlendFactor.OneMinusConstantColor: return BlendingFactorSrc.OneMinusConstantColor;
|
||||
case GalBlendFactor.ConstantAlpha: return BlendingFactorSrc.ConstantAlpha;
|
||||
case GalBlendFactor.OneMinusConstantAlpha: return BlendingFactorSrc.OneMinusConstantAlpha;
|
||||
case GalBlendFactor.SrcAlphaSaturate: return BlendingFactorSrc.SrcAlphaSaturate;
|
||||
case GalBlendFactor.Src1Color: return BlendingFactorSrc.Src1Color;
|
||||
case GalBlendFactor.OneMinusSrc1Color: return BlendingFactorSrc.OneMinusSrc1Color;
|
||||
case GalBlendFactor.Src1Alpha: return BlendingFactorSrc.Src1Alpha;
|
||||
case GalBlendFactor.OneMinusSrc1Alpha: return BlendingFactorSrc.OneMinusSrc1Alpha;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(BlendFactor));
|
||||
}
|
||||
|
||||
public static BlendingFactorDest GetBlendFactorDst(GalBlendFactor BlendFactor)
|
||||
{
|
||||
switch (BlendFactor)
|
||||
{
|
||||
case GalBlendFactor.Zero: return BlendingFactorDest.Zero;
|
||||
case GalBlendFactor.One: return BlendingFactorDest.One;
|
||||
case GalBlendFactor.SrcColor: return BlendingFactorDest.SrcColor;
|
||||
case GalBlendFactor.OneMinusSrcColor: return BlendingFactorDest.OneMinusSrcColor;
|
||||
case GalBlendFactor.DstColor: return BlendingFactorDest.DstColor;
|
||||
case GalBlendFactor.OneMinusDstColor: return BlendingFactorDest.OneMinusDstColor;
|
||||
case GalBlendFactor.SrcAlpha: return BlendingFactorDest.SrcAlpha;
|
||||
case GalBlendFactor.OneMinusSrcAlpha: return BlendingFactorDest.OneMinusSrcAlpha;
|
||||
case GalBlendFactor.DstAlpha: return BlendingFactorDest.DstAlpha;
|
||||
case GalBlendFactor.OneMinusDstAlpha: return BlendingFactorDest.OneMinusDstAlpha;
|
||||
case GalBlendFactor.ConstantColor: return BlendingFactorDest.ConstantColor;
|
||||
case GalBlendFactor.OneMinusConstantColor: return BlendingFactorDest.OneMinusConstantColor;
|
||||
case GalBlendFactor.ConstantAlpha: return BlendingFactorDest.ConstantAlpha;
|
||||
case GalBlendFactor.OneMinusConstantAlpha: return BlendingFactorDest.OneMinusConstantAlpha;
|
||||
case GalBlendFactor.SrcAlphaSaturate: return BlendingFactorDest.SrcAlphaSaturate;
|
||||
case GalBlendFactor.Src1Color: return BlendingFactorDest.Src1Color;
|
||||
case GalBlendFactor.OneMinusSrc1Color: return BlendingFactorDest.OneMinusSrc1Color;
|
||||
case GalBlendFactor.Src1Alpha: return BlendingFactorDest.Src1Alpha;
|
||||
case GalBlendFactor.OneMinusSrc1Alpha: return BlendingFactorDest.OneMinusSrc1Alpha;
|
||||
case GalBlendFactor.Zero: return BlendingFactor.Zero;
|
||||
case GalBlendFactor.One: return BlendingFactor.One;
|
||||
case GalBlendFactor.SrcColor: return BlendingFactor.SrcColor;
|
||||
case GalBlendFactor.OneMinusSrcColor: return BlendingFactor.OneMinusSrcColor;
|
||||
case GalBlendFactor.DstColor: return BlendingFactor.DstColor;
|
||||
case GalBlendFactor.OneMinusDstColor: return BlendingFactor.OneMinusDstColor;
|
||||
case GalBlendFactor.SrcAlpha: return BlendingFactor.SrcAlpha;
|
||||
case GalBlendFactor.OneMinusSrcAlpha: return BlendingFactor.OneMinusSrcAlpha;
|
||||
case GalBlendFactor.DstAlpha: return BlendingFactor.DstAlpha;
|
||||
case GalBlendFactor.OneMinusDstAlpha: return BlendingFactor.OneMinusDstAlpha;
|
||||
case GalBlendFactor.ConstantColor: return BlendingFactor.ConstantColor;
|
||||
case GalBlendFactor.OneMinusConstantColor: return BlendingFactor.OneMinusConstantColor;
|
||||
case GalBlendFactor.ConstantAlpha: return BlendingFactor.ConstantAlpha;
|
||||
case GalBlendFactor.OneMinusConstantAlpha: return BlendingFactor.OneMinusConstantAlpha;
|
||||
case GalBlendFactor.SrcAlphaSaturate: return BlendingFactor.SrcAlphaSaturate;
|
||||
case GalBlendFactor.Src1Color: return BlendingFactor.Src1Color;
|
||||
case GalBlendFactor.OneMinusSrc1Color: return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Color;
|
||||
case GalBlendFactor.Src1Alpha: return BlendingFactor.Src1Alpha;
|
||||
case GalBlendFactor.OneMinusSrc1Alpha: return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Alpha;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(BlendFactor));
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
if (IsCompressedTextureFormat(Texture.Format))
|
||||
{
|
||||
PixelInternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);
|
||||
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);
|
||||
|
||||
GL.CompressedTexImage2D(
|
||||
TextureTarget.Texture2D,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
|
@ -13,7 +13,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK.NETCore" Version="1.1.2749.6433" />
|
||||
<PackageReference Include="OpenTK.NetStandard" Version="1.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
|
@ -6,7 +6,7 @@
|
|||
<RuntimeIdentifiers>win10-x64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK.NETCore" Version="1.1.2749.6433" />
|
||||
<PackageReference Include="OpenTK.NetStandard" Version="1.0.4" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -20,6 +20,10 @@ namespace Ryujinx
|
|||
|
||||
private IGalRenderer Renderer;
|
||||
|
||||
private KeyboardState? Keyboard = null;
|
||||
|
||||
private MouseState? Mouse = null;
|
||||
|
||||
public GLScreen(Switch Ns, IGalRenderer Renderer)
|
||||
: base(1280, 720,
|
||||
new GraphicsMode(), "Ryujinx", 0,
|
||||
|
@ -47,44 +51,49 @@ namespace Ryujinx
|
|||
HidJoystickPosition LeftJoystick;
|
||||
HidJoystickPosition RightJoystick;
|
||||
|
||||
if (Keyboard[Key.Escape]) this.Exit();
|
||||
|
||||
int LeftJoystickDX = 0;
|
||||
int LeftJoystickDY = 0;
|
||||
int RightJoystickDX = 0;
|
||||
int RightJoystickDY = 0;
|
||||
|
||||
if (Keyboard.HasValue)
|
||||
{
|
||||
KeyboardState Keyboard = this.Keyboard.Value;
|
||||
|
||||
//RightJoystick
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickUp]) LeftJoystickDY = short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickDown]) LeftJoystickDY = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickLeft]) LeftJoystickDX = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickRight]) LeftJoystickDX = short.MaxValue;
|
||||
if (Keyboard[Key.Escape]) this.Exit();
|
||||
|
||||
//LeftButtons
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickButton]) CurrentButton |= HidControllerButtons.KEY_LSTICK;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadUp]) CurrentButton |= HidControllerButtons.KEY_DUP;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadDown]) CurrentButton |= HidControllerButtons.KEY_DDOWN;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadLeft]) CurrentButton |= HidControllerButtons.KEY_DLEFT;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadRight]) CurrentButton |= HidControllerButtons.KEY_DRIGHT;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonMinus]) CurrentButton |= HidControllerButtons.KEY_MINUS;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonL]) CurrentButton |= HidControllerButtons.KEY_L;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonZL]) CurrentButton |= HidControllerButtons.KEY_ZL;
|
||||
//RightJoystick
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickUp]) LeftJoystickDY = short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickDown]) LeftJoystickDY = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickLeft]) LeftJoystickDX = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickRight]) LeftJoystickDX = short.MaxValue;
|
||||
|
||||
//RightJoystick
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickUp]) RightJoystickDY = short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickDown]) RightJoystickDY = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickLeft]) RightJoystickDX = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickRight]) RightJoystickDX = short.MaxValue;
|
||||
//LeftButtons
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.StickButton]) CurrentButton |= HidControllerButtons.KEY_LSTICK;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadUp]) CurrentButton |= HidControllerButtons.KEY_DUP;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadDown]) CurrentButton |= HidControllerButtons.KEY_DDOWN;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadLeft]) CurrentButton |= HidControllerButtons.KEY_DLEFT;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadRight]) CurrentButton |= HidControllerButtons.KEY_DRIGHT;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonMinus]) CurrentButton |= HidControllerButtons.KEY_MINUS;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonL]) CurrentButton |= HidControllerButtons.KEY_L;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonZL]) CurrentButton |= HidControllerButtons.KEY_ZL;
|
||||
|
||||
//RightButtons
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickButton]) CurrentButton |= HidControllerButtons.KEY_RSTICK;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonA]) CurrentButton |= HidControllerButtons.KEY_A;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonB]) CurrentButton |= HidControllerButtons.KEY_B;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonX]) CurrentButton |= HidControllerButtons.KEY_X;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonY]) CurrentButton |= HidControllerButtons.KEY_Y;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonPlus]) CurrentButton |= HidControllerButtons.KEY_PLUS;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonR]) CurrentButton |= HidControllerButtons.KEY_R;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonZR]) CurrentButton |= HidControllerButtons.KEY_ZR;
|
||||
//RightJoystick
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickUp]) RightJoystickDY = short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickDown]) RightJoystickDY = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickLeft]) RightJoystickDX = -short.MaxValue;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickRight]) RightJoystickDX = short.MaxValue;
|
||||
|
||||
//RightButtons
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.StickButton]) CurrentButton |= HidControllerButtons.KEY_RSTICK;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonA]) CurrentButton |= HidControllerButtons.KEY_A;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonB]) CurrentButton |= HidControllerButtons.KEY_B;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonX]) CurrentButton |= HidControllerButtons.KEY_X;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonY]) CurrentButton |= HidControllerButtons.KEY_Y;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonPlus]) CurrentButton |= HidControllerButtons.KEY_PLUS;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonR]) CurrentButton |= HidControllerButtons.KEY_R;
|
||||
if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonZR]) CurrentButton |= HidControllerButtons.KEY_ZR;
|
||||
}
|
||||
|
||||
LeftJoystick = new HidJoystickPosition
|
||||
{
|
||||
|
@ -102,8 +111,10 @@ namespace Ryujinx
|
|||
|
||||
//Get screen touch position from left mouse click
|
||||
//OpenTK always captures mouse events, even if out of focus, so check if window is focused.
|
||||
if (Focused && Mouse?.GetState().LeftButton == ButtonState.Pressed)
|
||||
if (Focused && Mouse?.LeftButton == ButtonState.Pressed)
|
||||
{
|
||||
MouseState Mouse = this.Mouse.Value;
|
||||
|
||||
int ScrnWidth = Width;
|
||||
int ScrnHeight = Height;
|
||||
|
||||
|
@ -191,5 +202,30 @@ namespace Ryujinx
|
|||
{
|
||||
Renderer.SetWindowSize(Width, Height);
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyboardKeyEventArgs e)
|
||||
{
|
||||
Keyboard = e.Keyboard;
|
||||
}
|
||||
|
||||
protected override void OnKeyUp(KeyboardKeyEventArgs e)
|
||||
{
|
||||
Keyboard = e.Keyboard;
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
Mouse = e.Mouse;
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseButtonEventArgs e)
|
||||
{
|
||||
Mouse = e.Mouse;
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseMoveEventArgs e)
|
||||
{
|
||||
Mouse = e.Mouse;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue