diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-09-08 17:29:12 +0000 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-09-08 17:29:12 +0000 |
| commit | 85445c6b6b659094c4b6ff8b99cc666bb6eeca0b (patch) | |
| tree | 6643b1f6a575bad3cb10bbb8327398f47cd6965c | |
| parent | d36205befa1e2bf45a3c6283ace18259bce12377 (diff) | |
debug and refinements
| -rw-r--r-- | shaders/tone_mapping2.frag | 58 | ||||
| -rw-r--r-- | src/BoardWidget.cs | 22 | ||||
| -rw-r--r-- | src/ExtensionMethods.cs | 19 | ||||
| -rw-r--r-- | src/LogViewerWidget.cs | 7 | ||||
| -rw-r--r-- | src/Piece.cs | 340 | ||||
| -rw-r--r-- | src/Vector3Widget.cs | 130 | ||||
| -rw-r--r-- | src/VkChess.cs | 288 | ||||
| -rw-r--r-- | src/deferredPbrRendererBase.cs | 5 | ||||
| -rw-r--r-- | src/shadowMapRenderer.cs | 3 | ||||
| -rw-r--r-- | ui/Vector3Widget.template | 7 | ||||
| -rw-r--r-- | ui/Window.template | 18 | ||||
| -rw-r--r-- | ui/chess.crow | 19 | ||||
| -rw-r--r-- | ui/chess.style | 20 | ||||
| -rw-r--r-- | ui/menuCommand.itmp | 10 | ||||
| -rw-r--r-- | ui/menuItem.itmp | 13 | ||||
| -rw-r--r-- | ui/menuItem.template | 13 | ||||
| -rw-r--r-- | ui/slider.tmp | 2 | ||||
| -rw-r--r-- | ui/winLog.crow | 5 | ||||
| -rw-r--r-- | ui/winOptions.crow | 158 | ||||
| -rw-r--r-- | ui/winSSR.crow | 4 |
20 files changed, 814 insertions, 327 deletions
diff --git a/shaders/tone_mapping2.frag b/shaders/tone_mapping2.frag index 6343912..84d672c 100644 --- a/shaders/tone_mapping2.frag +++ b/shaders/tone_mapping2.frag @@ -73,10 +73,9 @@ float linearDepth(float depth) float z = depth * 2.0f - 1.0f; return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); } - void main() { - const float reflectionCoef = 0.6; + const float reflectionCoef = 0.4; //ivec2 ts = textureSize(samplerHDR, 0); //vec4 hdrColor = texelFetch (samplerHDR, ivec2(gl_FragCoord.xy), gl_SampleID); @@ -105,6 +104,7 @@ void main() float curLength = step; bool hit = false; vec2 uv; + float s = step; for (int i=0; i<maxStep; i++) { @@ -116,25 +116,67 @@ void main() if (uv.x < 0 || uv.y < 0 || uv.x > 1 || uv.y > 1) break; - vec4 cp = texture(gbPos, uv); - float linDepthCP = linearDepth (ndc.z / ndc.w); + vec4 cp = texture(gbPos, uv); //outColor = vec4 (vec3 (linDepthCP/100.0), 1); /*outColor = vec4 (1,0,0, 1); return;*/ if (abs(linDepthCP - cp.a) < depthTreshold) { + /*outColor = vec4 (vec3(linDepthCP/100),1); + return;*/ hit = true; break; - } - - curLength += step; + } + /*cp = textureOffset(gbPos, uv, ivec2 (0,1)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } + cp = textureOffset(gbPos, uv, ivec2 (1,0)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } + cp = textureOffset(gbPos, uv, ivec2 (0,-1)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } + cp = textureOffset(gbPos, uv, ivec2 (-1,0)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } + cp = textureOffset(gbPos, uv, ivec2 (1,1)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } + cp = textureOffset(gbPos, uv, ivec2 (1,-1)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } + cp = textureOffset(gbPos, uv, ivec2 (-1,-1)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } + cp = textureOffset(gbPos, uv, ivec2 (-1,1)); + if (abs(linDepthCP - cp.a) < depthTreshold) { + hit = true; + break; + } */ + curLength += s; + //s *= 1.2; } if (hit) hdrColor = mix (hdrColor, texture(samplerHDR, uv), reflectionCoef); - //hdrColor = vec4 (1,0,0,1);// texture(samplerHDR, uv); + //hdrColor = vec4 (1,0,0,1); + } diff --git a/src/BoardWidget.cs b/src/BoardWidget.cs index c119791..80668af 100644 --- a/src/BoardWidget.cs +++ b/src/BoardWidget.cs @@ -1,23 +1,7 @@ -// -// ChessBoardWidget.cs +// Copyright (c) 2016-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2016 jp -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + using System; using System.ComponentModel; using Crow; diff --git a/src/ExtensionMethods.cs b/src/ExtensionMethods.cs new file mode 100644 index 0000000..d240078 --- /dev/null +++ b/src/ExtensionMethods.cs @@ -0,0 +1,19 @@ +using System.Numerics; + +namespace vkChess +{ + public static class ExtensionMethods { + public static Vector3 ParseVec3 (string str) { + if (string.IsNullOrEmpty (str)) + return new Vector3(); + string[] components = str.Substring(1, str.Length - 2).Split (','); + if (components.Length != 3) + throw new System.Exception ("Vector3 Parse Error, expecting 3 components."); + return new Vector3( + float.Parse (components[0]), + float.Parse (components[1]), + float.Parse (components[2]) + ); + } + } +}
\ No newline at end of file diff --git a/src/LogViewerWidget.cs b/src/LogViewerWidget.cs index 5dbb511..deb2469 100644 --- a/src/LogViewerWidget.cs +++ b/src/LogViewerWidget.cs @@ -67,6 +67,10 @@ namespace Crow lines.ListAdd += Lines_ListAdd; lines.ListRemove += Lines_ListRemove; lines.ListClear += Lines_ListClear; + + MaxScrollY = lines.Count - visibleLines; + if (scrollOnOutput) + ScrollY = MaxScrollY; } NotifyValueChanged ("Lines", lines); RegisterForGraphicUpdate (); @@ -179,6 +183,9 @@ namespace Crow } } } + protected override void Dispose (bool disposing) { + Lines = null; + } } } diff --git a/src/Piece.cs b/src/Piece.cs index af990ec..f509132 100644 --- a/src/Piece.cs +++ b/src/Piece.cs @@ -1,28 +1,6 @@ -// -// Piece.cs +// Copyright (c) 2019-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // -// Author: -// Jean-Philippe Bruyère <jp_bruyere@hotmail.com> -// -// Copyright (c) 2019 -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; using System.Collections.Generic; @@ -31,37 +9,37 @@ using System.Numerics; using vke; namespace vkChess { - public class ChessMoves : List<String> { - public void AddMove(string move) { - if (!string.IsNullOrEmpty(move)) - base.Add(move); - } - public void AddMove(string[] moves) { - if (moves == null) - return; - if (moves.Length > 0) - base.AddRange(moves); - } - } + public class ChessMoves : List<String> { + public void AddMove(string move) { + if (!string.IsNullOrEmpty(move)) + base.Add(move); + } + public void AddMove(string[] moves) { + if (moves == null) + return; + if (moves.Length > 0) + base.AddRange(moves); + } + } - [DebuggerDisplay("{DebuggerDisplay}")] - public class Piece { - static Vector4 blackColor = new Vector4(0.03f, 0.03f, 0.03f, 1f); - static Vector4 whiteColor = new Vector4(1.0f, 1.0f, 1.0f, 1f); - public static HostBuffer<VkChess.InstanceData> instanceBuff; + [DebuggerDisplay("{DebuggerDisplay}")] + public class Piece { + static Vector4 blackColor = new Vector4(0.03f, 0.03f, 0.03f, 1f); + static Vector4 whiteColor = new Vector4(1.0f, 1.0f, 1.0f, 1f); + public static HostBuffer<VkChess.InstanceData> instanceBuff; public static VkChess.InstanceData[] boardDatas; public static uint flushStart, flushEnd; - static uint nextInstanceIdx; - float xAngle, zAngle; - Vector3 position; - public PieceType Type; - public readonly ChessColor Player; - public uint instanceIdx; + static uint nextInstanceIdx; + float xAngle, zAngle; + Vector3 position, capturePos; + public PieceType Type; + public readonly ChessColor Player; + public uint instanceIdx; - public bool IsPromoted; - public bool HasMoved; - public bool Captured { + public bool IsPromoted; + public bool HasMoved; + public bool Captured { get { return BoardCell < 0; } set { if (value) @@ -70,95 +48,100 @@ namespace vkChess { BoardCell = 0; } } + public void SetCaptured (Vector3 capturePos) { + Captured = true; + HasMoved = true; + this.capturePos = capturePos; + } public int initX, initY; - VkChess.InstanceData instData; + VkChess.InstanceData instData; - public Piece (ChessColor player, PieceType type, int col, int line) { - this.instanceIdx = nextInstanceIdx++; - this.Type = type; - this.Player = player; - initX = col; - initY = line; - position.X = initX; - position.Y = initY; + public Piece (ChessColor player, PieceType type, int col, int line) { + this.instanceIdx = nextInstanceIdx++; + this.Type = type; + this.Player = player; + initX = col; + initY = line; + position.X = initX; + position.Y = initY; BoardCell = new Crow.Point (col, line); - instData = new VkChess.InstanceData(Player == ChessColor.White ? whiteColor : blackColor, Matrix4x4.Identity); + instData = new VkChess.InstanceData(Player == ChessColor.White ? whiteColor : blackColor, Matrix4x4.Identity); if (player == ChessColor.Black && type == PieceType.Knight) zAngle = MathHelper.Pi; updatePos (); - } + } public Crow.Point BoardCell; - public Vector3 Position { - get { return position; } - set { - if (value == position) - return; - position = value; - updatePos(); - } - } + public Vector3 Position { + get { return position; } + set { + if (value == position) + return; + position = value; + updatePos(); + } + } - public float X { - get { return position.X; } - set { - if (position.X == value) - return; - position.X = value; - updatePos(); - } - } - public float Y { - get { return position.Y; } - set { - if (position.Y == value) - return; - position.Y = value; - updatePos(); - } - } - public float Z { - get { return position.Z; } - set { - if (position.Z == value) - return; - position.Z = value; - updatePos(); - } - } - public float XAngle { - get { return xAngle; } - set { - if (xAngle == value) - return; - xAngle = value; - updatePos(); - } - } - public float ZAngle { - get { return zAngle; } - set { - if (zAngle == value) - return; - zAngle = value; - updatePos(); - } - } - static Vector3 centerDiff = new Vector3(3.5f, 0, 3.5f); + public float X { + get { return position.X; } + set { + if (position.X == value) + return; + position.X = value; + updatePos(); + } + } + public float Y { + get { return position.Y; } + set { + if (position.Y == value) + return; + position.Y = value; + updatePos(); + } + } + public float Z { + get { return position.Z; } + set { + if (position.Z == value) + return; + position.Z = value; + updatePos(); + } + } + public float XAngle { + get { return xAngle; } + set { + if (xAngle == value) + return; + xAngle = value; + updatePos(); + } + } + public float ZAngle { + get { return zAngle; } + set { + if (zAngle == value) + return; + zAngle = value; + updatePos(); + } + } + static Vector3 centerDiff = new Vector3(3.5f, 0, 3.5f); - public void updatePos() { - Quaternion q = Quaternion.CreateFromYawPitchRoll (zAngle, 0f, xAngle); + public void updatePos() { + Quaternion q = Quaternion.CreateFromYawPitchRoll (zAngle, 0f, xAngle); Vector3 pos = (new Vector3 (position.X, position.Z, 7f-position.Y) - centerDiff) * 2; - instData.mat = Matrix4x4.CreateFromQuaternion(q) * Matrix4x4.CreateTranslation(pos); + instData.mat = Matrix4x4.CreateFromQuaternion(q) * Matrix4x4.CreateTranslation(pos); UpdateBuff (instanceIdx, ref instData); - } + } public static void UpdateBuff (uint instIdx, ref VkChess.InstanceData data) { if (instanceBuff == null) return; @@ -178,71 +161,78 @@ namespace vkChess { UpdateBuff ((uint)index+32, ref boardDatas[index]); } public static void FlushHostBuffer () { - if (flushEnd == 0) - return; - instanceBuff.Flush(flushStart, flushEnd); - flushEnd = flushStart = 0; - } + if (flushEnd == 0) + return; + instanceBuff.Flush(flushStart, flushEnd); + flushEnd = flushStart = 0; + } - public void Reset(bool animate = true) { - xAngle = 0f; - Z = 0f; - if (HasMoved) { - if (animate) - Animation.StartAnimation(new PathAnimation(this, "Position", - new BezierPath( - Position, - new Vector3(initX, initY, 0f), Vector3.UnitZ))); - //else - // Position = new Vector3(initX, initY, 0f); - } + public void Reset(bool animate = true) { + xAngle = 0f; + Z = 0f; + if (HasMoved) { + if (animate) + Animation.StartAnimation(new PathAnimation(this, "Position", + new BezierPath( + Position, + new Vector3(initX, initY, 0f), Vector3.UnitZ))); + //else + // Position = new Vector3(initX, initY, 0f); + } if (IsPromoted) - Unpromote(); - IsPromoted = false; - HasMoved = false; + Unpromote(); + IsPromoted = false; + HasMoved = false; BoardCell = new Crow.Point (initX, initY); - } + } public void MoveTo (Crow.Point newPos, bool animate = false) { BoardCell = newPos; if (animate) { - Animation.StartAnimation (new PathAnimation (this, "Position", - new BezierPath ( - Position, - new Vector3 (newPos.X, newPos.Y, 0f), Vector3.UnitZ), VkChess.animationSteps), - 0); - } //else - // Position = new Vector3 (newPos.X, newPos.Y, 0f); + if (Captured) + Animation.StartAnimation (new PathAnimation (this, "Position", + new BezierPath ( + Position, + capturePos, Vector3.UnitZ), VkChess.animationSteps), + 0); + else if (BoardCell.X != Position.X || BoardCell.Y != Position.Y) + Animation.StartAnimation (new PathAnimation (this, "Position", + new BezierPath ( + Position, + new Vector3 (newPos.X, newPos.Y, 0f), Vector3.UnitZ), VkChess.animationSteps), + 0); + + } } public void Promote(char prom, bool preview = false) { - if (IsPromoted) - throw new Exception("trying to promote already promoted " + Type.ToString()); - if (Type != PieceType.Pawn) - throw new Exception("trying to promote " + Type.ToString()); - IsPromoted = true; - switch (prom) { - case 'q': - Type = PieceType.Queen; - break; - case 'r': - Type = PieceType.Rook; - break; - case 'b': - Type = PieceType.Bishop; - break; - case 'k': - Type = PieceType.Knight; - break; - default: - throw new Exception("Unrecognized promotion"); - } + if (IsPromoted) + throw new Exception("trying to promote already promoted " + Type.ToString()); + if (Type != PieceType.Pawn) + throw new Exception("trying to promote " + Type.ToString()); + IsPromoted = true; + switch (prom) { + case 'q': + Type = PieceType.Queen; + break; + case 'r': + Type = PieceType.Rook; + break; + case 'b': + Type = PieceType.Bishop; + break; + case 'k': + Type = PieceType.Knight; + break; + default: + throw new Exception("Unrecognized promotion"); + } VkChess.updateInstanceCmds = true; - } - public void Unpromote() { - IsPromoted = false; - Type = PieceType.Pawn; + } + public void Unpromote() { + IsPromoted = false; + Type = PieceType.Pawn; VkChess.updateInstanceCmds = true; } - string DebuggerDisplay => string.Format($"{Type}:{BoardCell.ToString()}"); - } + string DebuggerDisplay => string.Format($"{Type}:{BoardCell.ToString()}"); + } } diff --git a/src/Vector3Widget.cs b/src/Vector3Widget.cs new file mode 100644 index 0000000..9acc615 --- /dev/null +++ b/src/Vector3Widget.cs @@ -0,0 +1,130 @@ +// Copyright (c) 2021-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.ComponentModel; +using System.Numerics; +using Crow; +using Crow.Drawing; +//using vkvg; + +namespace vkChess +{ + public class Vector3Widget : TemplatedControl + { + Vector3 vector; + protected float minValue, maxValue, smallStep, bigStep; + protected int decimals; + + + [DefaultValue(2)] + public int Decimals + { + get => decimals; + set + { + if (value == decimals) + return; + decimals = value; + NotifyValueChangedAuto (decimals); + RegisterForRedraw (); + } + } + [DefaultValue(0.0f)] + public virtual float Minimum { + get => minValue; + set { + if (minValue == value) + return; + + minValue = value; + NotifyValueChangedAuto (minValue); + RegisterForRedraw (); + } + } + [DefaultValue(100.0f)] + public virtual float Maximum + { + get => maxValue; + set { + if (maxValue == value) + return; + + maxValue = value; + NotifyValueChangedAuto (maxValue); + RegisterForRedraw (); + } + } + [DefaultValue(1.0f)] + public virtual float SmallIncrement + { + get => smallStep; + set { + if (smallStep == value) + return; + + smallStep = value; + NotifyValueChangedAuto (smallStep); + RegisterForRedraw (); + } + } + [DefaultValue(5.0f)] + public virtual float LargeIncrement + { + get => bigStep; + set { + if (bigStep == value) + return; + + bigStep = value; + NotifyValueChangedAuto (bigStep); + RegisterForRedraw (); + } + } + + public Vector3 Value { + get => vector; + set { + if (vector == value) + return; + vector = value; + NotifyValueChangedAuto (vector); + NotifyValueChanged ("X", vector.X); + NotifyValueChanged ("Y", vector.Y); + NotifyValueChanged ("Z", vector.Z); + } + } + public float X { + get => vector.X; + set { + if (X == value) + return; + vector.X = value; + NotifyValueChangedAuto (vector.X); + NotifyValueChanged ("Value", vector); + } + } + public float Y { + get => vector.Y; + set { + if (Y == value) + return; + vector.Y = value; + NotifyValueChangedAuto (vector.Y); + NotifyValueChanged ("Value", vector); + } + } + public float Z { + get => vector.Z; + set { + if (Z == value) + return; + vector.Z = value; + NotifyValueChangedAuto (vector.Z); + NotifyValueChanged ("Value", vector); + } + } + } +} + diff --git a/src/VkChess.cs b/src/VkChess.cs index e31c27d..8a84461 100644 --- a/src/VkChess.cs +++ b/src/VkChess.cs @@ -13,7 +13,7 @@ using System.Reflection; namespace vkChess { - public enum GameState { Init, Play, Pad, Checked, Checkmate }; + public enum GameState { Init, SceneInitialized, StockFishStarted, Play, Pad, Checked, Checkmate }; public enum PlayerType { Human, AI }; public enum ChessColor { White, Black }; public enum PieceType { Pawn, Rook, Knight, Bishop, King, Queen }; @@ -173,10 +173,7 @@ namespace vkChess cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount); - camera = new Camera (Utils.DegreesToRadians (40f), 1f, 0.1f, 32f); - camera.SetRotation (0.6f, 0, 0); - camera.SetPosition (0, 0f, -12.0f); - camera.AspectRatio = Width / Height; + createCamera (); DeferredPbrRendererBase.NUM_SAMPLES = SampleCount; @@ -185,8 +182,8 @@ namespace vkChess renderer.matrices.scaleIBLAmbient = IBLAmbient; renderer.lights[0].color = new Vector4 (LightStrength); //renderer.LoadModel (transferQ, "data/models/chess.glb"); - renderer.LoadModel (transferQ, "/mnt/devel/vkChess.net/data/models/chess2.glb"); - camera.Model = Matrix4x4.CreateScale (0.5f);// Matrix4x4.CreateScale(1f / Math.Max(Math.Max(renderer.modelAABB.Width, renderer.modelAABB.Height), renderer.modelAABB.Depth)); + renderer.LoadModel (transferQ, "/mnt/devel/vkChess.net/data/models/chess.glb"); + // Matrix4x4.CreateScale(1f / Math.Max(Math.Max(renderer.modelAABB.Width, renderer.modelAABB.Height), renderer.modelAABB.Depth)); DescriptorSetWrites dsw = new DescriptorSetWrites (descSet, dslToneMap.Bindings[4]); @@ -197,14 +194,24 @@ namespace vkChess curRenderer = renderer; + updateCellHighlighting(); + initBoard (); initStockfish (); - CurrentState = GameState.Play; + iFace.Load ("ui/chess.crow").DataSource = this; - } + loadCurrentGame (); + } + void createCamera () { + camera = new Camera (Utils.DegreesToRadians (CameraFOV), 1f, 0.1f, 32f); + camera.SetPosition (CameraPosition.X, CameraPosition.Y, -CameraPosition.Z); + camera.SetRotation (CameraRotation.X, CameraRotation.Y, CameraRotation.Z); + camera.AspectRatio = Width / Height; + camera.Model = Matrix4x4.CreateScale (0.5f); + } Queue transferQ; protected override void createQueues () { base.createQueues (); @@ -262,7 +269,7 @@ namespace vkChess renderer.recordDraw (cmds[i], i, instanceBuff, instancedCmds?.ToArray ()); statPool.End (cmds[i]); #else - renderer.recordDraw (cmds [i], i, instanceBuff, instancedCmds?.ToArray ()); + renderer?.recordDraw (cmds [i], i, instanceBuff, instancedCmds?.ToArray ()); recordUICmd (cmds[i], i); #endif @@ -344,6 +351,8 @@ namespace vkChess protected override void Dispose (bool disposing) { + saveCurrentGame (); + Configuration.Global.Save(); if (disposing) { if (!isDisposed) { plToneMap.Dispose(); @@ -382,13 +391,16 @@ namespace vkChess return vec; } protected override void onScroll (double xOffset, double yOffset) { + base.onScroll (xOffset, yOffset); + if (MouseIsInInterface) + return; /*if (KeyModifiers.HasFlag (Modifier.Shift)) { if (crow.ProcessMouseWheelChanged ((float)xOffset)) return; } else if (crow.ProcessMouseWheelChanged ((float)yOffset)) return;*/ camera.Move (0, 0, (float)yOffset * 4f); - updateViewRequested = true; + CameraPosition = new Vector3 (camera.Position.X, camera.Position.Y, -camera.Position.Z); } protected override void onMouseMove (double xPos, double yPos) { base.onMouseMove (xPos, yPos); @@ -401,11 +413,11 @@ namespace vkChess if (GetButton (MouseButton.Middle) == InputAction.Press) { camera.Rotate ((float)-diffY, (float)-diffX); - updateViewRequested = true; + CameraRotation = camera.Rotation; return; } - if (currentState == GameState.Init) + if (currentState < GameState.Play) return; Vector3 vMouse = UnProject (ref renderer.matrices.projection, ref renderer.matrices.view, @@ -447,7 +459,7 @@ namespace vkChess // return; //} - if (currentState == GameState.Init) + if (currentState < GameState.Play) return; if (CurrentState == GameState.Checkmate) { @@ -589,18 +601,19 @@ namespace vkChess break; } } + void onQuitClick (object sender, MouseButtonEventArgs e) { Close (); } - void onUndoClick (object sender, MouseButtonEventArgs e) { - undo(); - } void undo() { + if (currentState < GameState.Play) + return; lock (movesMutex) { bool hintIsEnabled = EnableHint; EnableHint = false; - if (currentState != GameState.Pad && currentState != GameState.Checkmate && !playerIsAi (CurrentPlayer) && playerIsAi (Opponent))//undo ai move + //if (currentState != GameState.Pad && currentState != GameState.Checkmate && !playerIsAi (CurrentPlayer) && playerIsAi (Opponent))//undo ai move + if (!playerIsAi (CurrentPlayer) && playerIsAi (Opponent)) undoLastMove (); undoLastMove (); @@ -627,16 +640,41 @@ namespace vkChess } public CommandGroup Commands => new CommandGroup ( - new Command ("New Game", ()=>loadWindow ("ui/newGame.crow", this)), - new Command ("Options", ()=>loadWindow ("ui/winOptions.crow", this)), + new CommandGroup ("Menu", + new Command ("New Game", () => loadWindow ("ui/newGame.crow", this)), + new Command ("Save", () => loadWindow ("ui/newGame.crow", this)), + new Command ("Load", () => loadWindow ("ui/newGame.crow", this)), + new Command ("Options", () => loadWindow ("ui/winOptions.crow", this)), #if DEBUG - new Command ("Log", ()=>loadWindow ("ui/winLog.crow", this)), + new Command ("Log", () => loadWindow ("ui/winLog.crow", this)), #endif - new Command ("Undo", ()=>undo()), - new Command ("Redo", ()=>Close()) + new Command ("Quit", () => Close()) + ), + new Command ("Undo", () => undo()), + new Command ("Redo", () => Close()) ); + void terminateCurrentGame () { + if (CurrentState < GameState.Play) + return; + if (!playerIsAi(CurrentPlayer) && enableHint) { + searchStopRequested = true; + sendToStockfish ("stop"); + while (searchStopRequested) + System.Threading.Thread.Sleep (10); + } + } + public float CameraAngleY { + get => CameraRotation.Y; + set => CameraRotation = new Vector3(CameraRotation.X, value, CameraRotation.Z); + } + void rotateBoard (float targetYAngle) { + + } void onNewWhiteGame (object sender, MouseButtonEventArgs e) { closeWindow ("ui/newGame.crow"); + Log(LogType.Custom1, "New White Game"); + + terminateCurrentGame(); CurrentState = GameState.Play; @@ -645,9 +683,17 @@ namespace vkChess resetBoard (); syncStockfish (); + + if (enableHint) + sendToStockfish ("go infinite"); + + Animation.StartAnimation (new AngleAnimation (this, "CameraAngleY", 0, 0.05f)); } void onNewBlackGame (object sender, MouseButtonEventArgs e) { closeWindow ("ui/newGame.crow"); + Log(LogType.Custom1, "New Black Game"); + + terminateCurrentGame(); CurrentState = GameState.Play; @@ -657,7 +703,12 @@ namespace vkChess resetBoard (); syncStockfish (); - sendToStockfish ("go"); + if (AISearchTime > 0) + sendToStockfish ("go movetime " + AISearchTime.ToString()); + else + sendToStockfish ("go depth 1"); + + Animation.StartAnimation (new AngleAnimation (this, "CameraAngleY", MathHelper.Pi, 0.05f)); } void onPromoteToQueenClick (object sender, MouseButtonEventArgs e) { closeWindow ("ui/promote.crow"); @@ -778,6 +829,92 @@ namespace vkChess rebuildBuffers = true; } } + public float CameraFOV { + get => Configuration.Global.Get<float> ("CameraFOV", 35f); + set { + if (value == CameraFOV) + return; + Configuration.Global.Set ("CameraFOV", value); + NotifyValueChanged ("CameraFOV", value); + createCamera (); + updateViewRequested = true; + } + } + /*public float CameraY { + get => Configuration.Global.Get<float> ("CameraY", 0); + set { + if (value == CameraY) + return; + Configuration.Global.Set ("CameraY", value); + NotifyValueChanged ("CameraY", value); + camera.SetPosition (0, CameraY, -CameraZ); + updateViewRequested = true; + } + } + public float CameraZ { + get => Configuration.Global.Get<float> ("CameraZ", 12); + set { + if (value == CameraZ) + return; + Configuration.Global.Set ("CameraZ", value); + NotifyValueChanged ("CameraZ", value); + camera.SetPosition (0, CameraY, -CameraZ); + updateViewRequested = true; + } + } + public float CameraAngle { + get => Configuration.Global.Get<float> ("CameraAngle", 0.6f); + set { + if (value == CameraAngle) + return; + Configuration.Global.Set ("CameraAngle", value); + NotifyValueChanged ("CameraAngle", value); + camera.SetRotation (CameraAngle, 0, 0); + updateViewRequested = true; + } + }*/ + public Vector3 CameraRotation { + get => ExtensionMethods.ParseVec3 (Configuration.Global.Get<string> ("CameraRotation", "<0.6f,0,0>")); + set { + if (value == CameraRotation) + return; + Configuration.Global.Set ("CameraRotation", value.ToString()); + NotifyValueChanged ("CameraRotation", value); + camera.SetRotation (CameraRotation.X, CameraRotation.Y, CameraRotation.Z); + updateViewRequested = true; + } + } + public Vector3 CameraPosition { + get => ExtensionMethods.ParseVec3 (Configuration.Global.Get<string> ("CameraPosition", "<0,0,12>")); + set { + if (value == CameraPosition) + return; + Configuration.Global.Set ("CameraPosition", value.ToString()); + NotifyValueChanged ("CameraPosition", value); + camera.SetPosition (CameraPosition.X, CameraPosition.Y, -CameraPosition.Z); + updateViewRequested = true; + } + } + public float CellHighlightIntensity { + get => Configuration.Global.Get<float> ("CellHighlightIntensity", 5.0f); + set { + if (value == CellHighlightIntensity) + return; + Configuration.Global.Set ("CellHighlightIntensity", value); + NotifyValueChanged ("CellHighlightIntensity", value); + updateCellHighlighting(); + } + } + public float CellHighlightDim { + get => Configuration.Global.Get<float> ("CellHighlightDim", 0.7f); + set { + if (value == CellHighlightDim) + return; + Configuration.Global.Set ("CellHighlightDim", value); + NotifyValueChanged ("CellHighlightDim", value); + updateCellHighlighting(); + } + } #endregion #region LOGS @@ -803,7 +940,6 @@ namespace vkChess object movesMutex = new object (); Process stockfish; volatile bool waitAnimationFinished; - volatile bool stockfishIsReady; //Queue<string> stockfishCmdQueue = new Queue<string> (); List<String> stockfishMoves = new List<string> (); @@ -822,8 +958,10 @@ namespace vkChess if (enableHint) { syncStockfish (); sendToStockfish ("go infinite"); - } else + } else { + searchStopRequested = true; sendToStockfish ("stop"); + } } NotifyValueChanged ("EnableHint", enableHint); @@ -846,7 +984,7 @@ namespace vkChess public int AISearchTime { get => Configuration.Global.Get<int> ("AISearchTime"); set { - if (value == WhitesLevel) + if (value == AISearchTime) return; Configuration.Global.Set ("AISearchTime", value); @@ -914,24 +1052,36 @@ namespace vkChess Configuration.Global.Set ("CurrentGame", stockfishPositionCommand); } void loadCurrentGame() { + + resetBoard (false); + string curGame = Configuration.Global.Get<string> ("CurrentGame"); if (string.IsNullOrEmpty (curGame)) return; stockfishMoves = curGame.Split (' ').ToList(); + + if (currentState < GameState.Play) + return; + resync3DScene (); + } + void resync3DScene () { replaySilently (); foreach (Piece p in whites) p.MoveTo (p.BoardCell, true); - foreach (Piece p in whites) + foreach (Piece p in blacks) p.MoveTo (p.BoardCell, true); syncStockfish(); } void initStockfish () { + if (currentState == GameState.Init) + throw new Exception ("init stockfish impossible: 3d scene must be initialized first."); + currentState = GameState.SceneInitialized; + if (stockfish != null) { - currentState = GameState.Play; - resetBoard (false); + //resetBoard (false); stockfish.OutputDataReceived -= dataReceived; stockfish.ErrorDataReceived -= dataReceived; @@ -945,6 +1095,7 @@ namespace vkChess NotifyValueChanged ("StockfishNotFound", true); return; } + NotifyValueChanged ("StockfishNotFound", false); stockfish = new Process (); stockfish.StartInfo.UseShellExecute = false; @@ -956,15 +1107,19 @@ namespace vkChess stockfish.OutputDataReceived += dataReceived; stockfish.ErrorDataReceived += dataReceived; stockfish.Exited += P_Exited; + stockfish.Start (); stockfish.BeginOutputReadLine (); - - sendToStockfish ("uci"); + stockfish.PriorityClass = ProcessPriorityClass.BelowNormal; + } void syncStockfish () { + if (currentState < GameState.Play) + return; NotifyValueChanged ("StockfishMoves", StockfishMoves); sendToStockfish ("setoption name Skill Level value " + (CurrentPlayer == ChessColor.White ? WhitesLevel.ToString() : BlacksLevel.ToString())); + //sendToStockfish ($"setoption name nodestime value 10"); sendToStockfish ($"position startpos moves {stockfishPositionCommand}"); } //void askStockfishIsReady () { @@ -976,6 +1131,8 @@ namespace vkChess // AddLog ("<= isready"); //} void sendToStockfish (string msg) { + if (currentState < GameState.StockFishStarted) + return; #if DEBUG Log (LogType.Normal, $"<= {msg}"); @@ -989,6 +1146,7 @@ namespace vkChess Log (LogType.High, "Stockfish Terminated"); #endif } + volatile bool searchStopRequested; void dataReceived (object sender, DataReceivedEventArgs e) { if (string.IsNullOrEmpty (e.Data)) return; @@ -1004,12 +1162,12 @@ namespace vkChess switch (tmp [0]) { case "readyok": - stockfishIsReady = true; + resync3DScene(); startTurn (); return; case "uciok": - //NotifyValueChanged ("StockfishNotFound", false); - //sendToStockfish ("setoption name Skill Level value " + StockfishLevel.ToString ()); + CurrentState = GameState.Play; + sendToStockfish ("isready"); break; case "info": if (playerIsAi (CurrentPlayer) || !enableHint) @@ -1021,12 +1179,16 @@ namespace vkChess BestMove = tmp [19]; break; case "bestmove": + if (searchStopRequested) { + searchStopRequested = false; + break; + } if (tmp [1] == "(none)") { if (checkKingIsSafe ()) CurrentState = GameState.Pad; else CurrentState = GameState.Checkmate; - return; + break; } if (playerIsAi (CurrentPlayer)) { @@ -1036,6 +1198,12 @@ namespace vkChess switchPlayer (); break; + case "Stockfish": + //stockfish starting + CurrentState = GameState.StockFishStarted; + NotifyValueChanged("StockfishVersion", tmp[1]); + sendToStockfish ("uci"); + break; } } } @@ -1044,11 +1212,17 @@ namespace vkChess #region game logic public static int animationSteps = 50; - static Vector4 bestMovePosColor = new Vector4 (0, 10, 10, 0); - static Vector4 selectionPosColor = new Vector4 (0, 0, 5, 0); - static Vector4 validPosColor = new Vector4 (0, 5, 0, 0); - static Vector4 activeColor = new Vector4 (0, 5, 0, 0); - static Vector4 kingCheckedColor = new Vector4 (20, 0, 0, 0); + Vector4 bestMovePosColor, selectionPosColor, validPosColor, activeColor, kingCheckedColor; + + void updateCellHighlighting () { + float dimC = -CellHighlightDim; + float highC = CellHighlightIntensity; + bestMovePosColor = new Vector4 (dimC, highC, highC, 0); + selectionPosColor = new Vector4 (dimC, dimC, highC, 0); + validPosColor = new Vector4 (dimC, highC, dimC, 0); + activeColor = new Vector4 (dimC, highC, dimC, 0); + kingCheckedColor = new Vector4 (highC, dimC, dimC, 0); + } Piece [,] board; Piece [] whites; @@ -1065,7 +1239,7 @@ namespace vkChess string bestMove; string BestMove { - get { return bestMove; } + get => bestMove; set { if (bestMove == value) return; @@ -1088,7 +1262,7 @@ namespace vkChess } public GameState CurrentState { - get { return currentState; } + get => currentState; set { if (currentState == value) return; @@ -1100,7 +1274,7 @@ namespace vkChess currentState = value; - if ((int)currentState > 2) { + if (currentState > GameState.Play) { Point kPos = CurrentPlayerPieces.First (p => p.Type == PieceType.King).BoardCell; Piece.UpdateCase (kPos.X, kPos.Y, kingCheckedColor); if (currentState == GameState.Checkmate) { @@ -1219,6 +1393,7 @@ namespace vkChess int [] boardCellMesheIndices; void initBoard () { + currentState = GameState.Init; CurrentPlayer = ChessColor.White; cptWhiteOut = 0; cptBlackOut = 0; @@ -1290,6 +1465,7 @@ namespace vkChess Piece.flushEnd = 97; updateDrawCmdList (); + currentState = GameState.SceneInitialized; } void updateDrawCmdList () { @@ -1322,6 +1498,7 @@ namespace vkChess void resetBoard (bool animate = true) { CurrentPlayer = ChessColor.White; + BestMove = null; cptWhiteOut = 0; cptBlackOut = 0; @@ -1339,6 +1516,19 @@ namespace vkChess p.Reset (animate); board [p.initX, p.initY] = p; } + } + void saveGame (string fileName = "default.chess") { + string defaultSaveDirectory = System.IO.Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".config", + System.Reflection.Assembly.GetEntryAssembly ().GetName().Name, "SavedGames"); + if (!Directory.Exists (defaultSaveDirectory)) + Directory.CreateDirectory (defaultSaveDirectory); + + string filePath = System.IO.Path.Combine (defaultSaveDirectory, fileName); + using (Stream stream = new FileStream (filePath, FileMode.Create)) + using (StreamWriter sw = new StreamWriter (stream)) + sw.WriteLine (stockfishPositionCommand); + } + void loadGame (string fileName = "default.chess") { } void addPiece (ChessColor player, PieceType _type, int col, int line) { @@ -1709,16 +1899,13 @@ namespace vkChess else cptBlackOut++; - p.Captured = true; - p.HasMoved = true; + p.SetCaptured (capturePos); if (animate) Animation.StartAnimation (new PathAnimation (p, "Position", new BezierPath ( p.Position, capturePos, Vector3.UnitZ), animationSteps)); - else - p.Position = capturePos; } void processMove (string move, bool animate = true) { @@ -1793,6 +1980,11 @@ namespace vkChess if (StockfishMoves.Count == 0) return; + if (currentState == GameState.Checked || currentState == GameState.Checkmate) { + Point kPos = CurrentPlayerPieces.First (p => p.Type == PieceType.King).BoardCell; + Piece.UpdateCase (kPos.X, kPos.Y, -kingCheckedColor); + } + string move = StockfishMoves [StockfishMoves.Count - 1]; StockfishMoves.RemoveAt (StockfishMoves.Count - 1); diff --git a/src/deferredPbrRendererBase.cs b/src/deferredPbrRendererBase.cs index 75f2a3f..6e85694 100644 --- a/src/deferredPbrRendererBase.cs +++ b/src/deferredPbrRendererBase.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) 2020-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; using System.Numerics; using System.Runtime.InteropServices; using vke; diff --git a/src/shadowMapRenderer.cs b/src/shadowMapRenderer.cs index c9cef4b..2a151a8 100644 --- a/src/shadowMapRenderer.cs +++ b/src/shadowMapRenderer.cs @@ -3,6 +3,9 @@ * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ +// Copyright (c) 2020-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; using System.Numerics; using System.Runtime.InteropServices; diff --git a/ui/Vector3Widget.template b/ui/Vector3Widget.template new file mode 100644 index 0000000..707ce0a --- /dev/null +++ b/ui/Vector3Widget.template @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<HorizontalStack Spacing="5" Background="{./Background}"> + <Label Text="{./Caption}" Margin="2"/> + <Spinner Value="{²./X}" SmallIncrement="{²./SmallIncrement}" LargeIncrement="{²./LargeIncrement}" Minimum="{²./Minimum}" Maximum="{²./Maximum}" Decimals="{²./Decimals}" Width="Fit"/> + <Spinner Value="{²./Y}" SmallIncrement="{²./SmallIncrement}" LargeIncrement="{²./LargeIncrement}" Minimum="{²./Minimum}" Maximum="{²./Maximum}" Decimals="{²./Decimals}" Width="Fit"/> + <Spinner Value="{²./Z}" SmallIncrement="{²./SmallIncrement}" LargeIncrement="{²./LargeIncrement}" Minimum="{²./Minimum}" Maximum="{²./Maximum}" Decimals="{²./Decimals}" Width="Fit"/> +</HorizontalStack> diff --git a/ui/Window.template b/ui/Window.template new file mode 100644 index 0000000..cdd8a5e --- /dev/null +++ b/ui/Window.template @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<Border Name="SizeHandle" Style="winBorder" CornerRadius="{./CornerRadius}" Background="{./Background}" > + <VerticalStack Spacing="0"> + <Group Margin="6" Height="Fit"> + <Label Font="serif, 20" Name="MoveHandle" Width="Fit" Foreground="${WindowTitleBarForeground" Margin="2" HorizontalAlignment="Center" Text="{./Caption}" /> + <ListBox Data="{./Commands}" Fit="true" HorizontalAlignment="Right" VerticalAlignment="Top"> + <Template> + <HorizontalStack Name="ItemsContainer" /> + </Template> + <ItemTemplate Path="#Crow.WindowButton.template"/> + </ListBox> + + <!--<Button MinimumSize="1,1" Fit="true" Command="{./CMDClose}" Template="#Crow.WindowButton.template" VerticalAlignment="Top" + HorizontalAlignment="Right"/>--> + </Group> + <Container Name="Content" MinimumSize="0,0" /> + </VerticalStack> +</Border>
\ No newline at end of file diff --git a/ui/chess.crow b/ui/chess.crow index a813be4..183107e 100644 --- a/ui/chess.crow +++ b/ui/chess.crow @@ -1,16 +1,19 @@ <?xml version="1.0" encoding="UTF-8"?> -<HorizontalStack Height="Fit" Background="vgradient|0:Grey|0.3:Jet|0.7:Jet|1:Black" VerticalAlignment="Bottom" Margin="10"> - <CheckBox Caption="Hint" IsChecked="{²EnableHint}" /> - <Menu Data="{Commands}" Height="Stretched" Width="Stretched"> +<HorizontalStack Height="Fit" Background="vgradient|0:Grey|0.3:Jet|0.7:Jet|1:Black" VerticalAlignment="Bottom" Margin="5"> + <Menu Data="{Commands}" Height="Stretched" Width="Fit"> <Template> <HorizontalStack Name="ItemsContainer" /> </Template> - <ItemTemplate> - <Button Command="{}"> - <Label Font="{./Font}" Name="caption" Margin="3" Foreground="LightGrey" Text="{./Caption}" /> - </Button> - </ItemTemplate> + <ItemTemplate DataType="Crow.Command" Path="ui/menuCommand.itmp"/> + <ItemTemplate DataType="Crow.CommandGroup" > + <MenuItem Data="{Commands}" Width="Fit" Height="Stretched" IsEnabled="{CanExecute}" + Template="ui/menuItem.template" + ItemTemplate="ui/menuItem.itmp"> + </MenuItem> + </ItemTemplate> </Menu> + <CheckBox Caption="Hint" IsChecked="{²EnableHint}" /> + <Widget Width="Stretched"/> <VerticalStack Style="hsStatus"> <Label Style="labStatus" Text="State:" /> <Label Style="labStatus2" Text="{CurrentState}" /> diff --git a/ui/chess.style b/ui/chess.style index 3ac5666..8e3d580 100644 --- a/ui/chess.style +++ b/ui/chess.style @@ -1,5 +1,7 @@ ControlHighlight = "DodgerBlue"; LogFont = "consolas, 10"; +WindowBackground = "0.01,0.01,0.02,0.8"; +ContainerBackground = "0.01,0.01,0.01,0.9"; icon { Width="14"; @@ -44,9 +46,17 @@ Button { MinimumSize = "80, 30"; Width="Fit"; } +MenuItem { + MinimumSize = "80, 30"; +} Window { - CornerRadius="5"; - Background="0.1,0.1,0.1,0.8"; + Template="ui/Window.template"; + AllowedStates="Normal"; + CornerRadius="0"; + Background="${WindowBackground}"; +} +Expandable { + Background="${ContainerBackground}"; } Slider { Foreground = "Jet"; @@ -90,7 +100,11 @@ ColorSlider { } LightingSlider { Template = "ui/slider.tmp"; - Height = "40"; + Height = "20"; Width = "Stretched"; CursorSize = "50"; +} +Vector3Widget { + Template = "ui/Vector3Widget.template"; + Width="Fit"; }
\ No newline at end of file diff --git a/ui/menuCommand.itmp b/ui/menuCommand.itmp new file mode 100644 index 0000000..324e4fa --- /dev/null +++ b/ui/menuCommand.itmp @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<Button Command="{}" Width="Stretched"> + <Template> + <Container Width="Stretched" Height="Stretched" Margin="6" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Label Text="{./Caption}" HorizontalAlignment="Left" /> + </Container> + </Template> +</Button> diff --git a/ui/menuItem.itmp b/ui/menuItem.itmp new file mode 100644 index 0000000..cb09180 --- /dev/null +++ b/ui/menuItem.itmp @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<ItemTemplate DataType="Crow.Command" Path="ui/menuCommand.itmp"/> +<ItemTemplate DataType="Crow.CommandGroup" Data="Commands"> + <Popper PopDirection="Right" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3" + Background="{./Background}"/> + </Template> + <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="Jet"/> + </Popper> +</ItemTemplate> diff --git a/ui/menuItem.template b/ui/menuItem.template new file mode 100644 index 0000000..4a72422 --- /dev/null +++ b/ui/menuItem.template @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<Popper PopDirection="Top" Caption="{Caption}" Width="Stretched" IsPopped="{²./IsOpened}" + MouseEnter="{Background=${ControlHighlight}}" + MouseLeave="{Background=Transparent}"> + <Template> + <Container Background="{./Background}" Width="Stretched" Height="Stretched" Margin="6"> + <Label Text="{./Caption}" HorizontalAlignment="Left" /> + </Container> + </Template> + <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="Jet"/> +</Popper> + + diff --git a/ui/slider.tmp b/ui/slider.tmp index ce0129b..bcb1be5 100644 --- a/ui/slider.tmp +++ b/ui/slider.tmp @@ -1,7 +1,7 @@ <?xml version="1.0"?> <Group Background="DarkGrey" > <Gauge Height="50%" Foreground="${ControlHighlight}" Background="Onyx" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}"/> - <Border Name="Cursor" Background="White" BorderWidth="3" Foreground="Grey" MouseEnter="{Foreground=${ControlHighlight}}" MouseLeave="{Foreground=Grey}" > + <Border Name="Cursor" Background="White" BorderWidth="2" Foreground="Grey" MouseEnter="{Foreground=${ControlHighlight}}" MouseLeave="{Foreground=Grey}" > <Label Text="{./Value}" Foreground="Black"/> </Border> </Group> diff --git a/ui/winLog.crow b/ui/winLog.crow index 4151ee4..8d3cf66 100644 --- a/ui/winLog.crow +++ b/ui/winLog.crow @@ -1,6 +1,9 @@ <?xml version="1.0"?> -<Window Caption="Log" Width="Stretched" Height="20%" VerticalAlignment="Top" > +<Window Caption="Log" Width="Stretched" Height="40%" VerticalAlignment="Top" > <VerticalStack RootDataLevel="true" > + <HorizontalStack Height="Fit"> + <CheckBox Caption="Scroll on Output" IsChecked="{²../../log.ScrollOnOutput}"/> + </HorizontalStack> <HorizontalStack Spacing="0"> <LogViewerWidget Name="log" Lines="{MainLog}" Font="${LogFont}" MaxScrollX="1000" ContextCommands="{LogContextMenu}"/> <ScrollBar Name="scrollbarY" Value="{²../log.ScrollY}" CursorRatio="{../log.ChildHeightRatio}" Maximum="{../log.MaxScrollY}" /> diff --git a/ui/winOptions.crow b/ui/winOptions.crow index 8b8e5d9..908497c 100644 --- a/ui/winOptions.crow +++ b/ui/winOptions.crow @@ -1,63 +1,99 @@ <?xml version="1.0"?> -<Window Caption="Options" Width="70%" Height="Fit" > - <VerticalStack Spacing="1" Margin="10" > - <HorizontalStack Height="Fit" Margin="5"> - <Label Text="Stockfish executable path:"/> - <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{StockfishNotFound}"/> - <TextBox Width="Stretched" Text="{²StockfishPath}"/> - <Button Caption="..." MinimumSize="1,1" Width="Fit" MouseClick="onFindStockfishPath"/> - </HorizontalStack> - <HorizontalStack Height="Fit"> - <VerticalStack Spacing="3" Width="50%" > - <HorizontalStack Height="Fit"> - <Label Width="Stretched" Text="Whites Level:"/> - <Spinner Width="60" Value="{²WhitesLevel}" Maximum="20" SmallIncrement="1"/> - </HorizontalStack> - <HorizontalStack Height="Fit"> - <Label Width="Stretched" Text="Blacks Level:"/> - <Spinner Width="60" Value="{²BlacksLevel}" Maximum="20" SmallIncrement="1"/> - </HorizontalStack> - <HorizontalStack Height="Fit"> - <Label Width="Stretched" Text="AI Search time (ms):" /> - <Spinner Width="60" Value="{²AISearchTime}" Maximum="10000" SmallIncrement="10"/> - </HorizontalStack> - <CheckBox Caption="Whites are AI" IsChecked="{²WhitesAreAI}" Width="Stretched"/> - <CheckBox Caption="Blacks are AI" IsChecked="{²BlacksAreAI}" Width="Stretched"/> - <CheckBox Caption="Enable Hint" IsChecked="{²EnableHint}" Width="Stretched"/> - </VerticalStack> - <VerticalStack Margin="20" Spacing="1"> - <HorizontalStack Height="Fit"> - <Label Text="Pce Color" Style="GridLabel"/> - <Label Text="{DebugCurColor}" Style="GridValue"/> - </HorizontalStack> - <HorizontalStack Height="Fit"> - <Label Text="Pce Type" Style="GridLabel"/> - <Label Text="{DebugCurType}" Style="GridValue" /> - </HorizontalStack> - <HorizontalStack Height="Fit"> - <Label Text="Pce Cell" Style="GridLabel"/> - <Label Text="{DebugCurCell}" Style="GridValue"/> - </HorizontalStack> - <HorizontalStack Height="Fit"> - <Label Text="Pce Cell pos" Style="GridLabel"/> - <Label Text="{DebugCurCellPos}" Style="GridValue"/> - </HorizontalStack> - </VerticalStack> - </HorizontalStack> - <Border Margin="10"> - <VerticalStack> - <HorizontalStack Style="Slid" > - <Label Text="Exposure:" Width="100"/> - <Slider Style="LightingSlider" Value="{²Exposure}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> - </HorizontalStack> - <HorizontalStack Style="Slid" > - <Label Text="Gamma:" Width="100" /> - <Slider Style="LightingSlider" Value="{²Gamma}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> - </HorizontalStack> - <HorizontalStack Style="Slid" > - <Label Text="IBL Ambient:" Width="100" /> - <Slider Style="LightingSlider" Value="{²IBLAmbient}" Maximum="50.0" SmallIncrement="0.01" LargeIncrement="0.1"/> - </HorizontalStack> +<Window Caption="Options" Width="50%" Height="Fit" > + <VerticalStack Spacing="1" Margin="10" > + <VerticalStack Height="Fit" Background="${ContainerBackground}" Margin="5"> + <HorizontalStack > + <Label Text="Stockfish executable path:"/> + <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{StockfishNotFound}"/> + </HorizontalStack> + <HorizontalStack Margin="5"> + <TextBox Width="Stretched" Text="{²StockfishPath}"/> + <Button Caption="..." MinimumSize="1,1" Width="Fit" MouseClick="onFindStockfishPath"/> + </HorizontalStack> + </VerticalStack> + <!--<HorizontalStack Height="Fit">--> + <Expandable Caption="Game" IsExpanded="true"> + <VerticalStack Height="Fit" Spacing="3" > + <HorizontalStack Height="Fit"> + <Label Width="Stretched" Text="Whites Level:"/> + <Spinner Width="60" Value="{²WhitesLevel}" Maximum="20" SmallIncrement="1"/> + </HorizontalStack> + <HorizontalStack Height="Fit"> + <Label Width="Stretched" Text="Blacks Level:"/> + <Spinner Width="60" Value="{²BlacksLevel}" Maximum="20" SmallIncrement="1"/> + </HorizontalStack> + <HorizontalStack Height="Fit"> + <Label Width="Stretched" Text="AI Search time (ms):" /> + <Spinner Width="60" Value="{²AISearchTime}" Maximum="10000" SmallIncrement="10"/> + </HorizontalStack> + <CheckBox Caption="Whites are AI" IsChecked="{²WhitesAreAI}" Width="Stretched"/> + <CheckBox Caption="Blacks are AI" IsChecked="{²BlacksAreAI}" Width="Stretched"/> + <CheckBox Caption="Enable Hint" IsChecked="{²EnableHint}" Width="Stretched"/> + <HorizontalStack Style="Slid" > + <Label Text="Cells Highlighting:" Width="100"/> + <Slider Style="LightingSlider" Value="{²CellHighlightIntensity}" Maximum="50.0" SmallIncrement="0.1" LargeIncrement="1"/> + </HorizontalStack> + <HorizontalStack Style="Slid" > + <Label Text="Cells Dim:" Width="100"/> + <Slider Style="LightingSlider" Value="{²CellHighlightDim}" Maximum="50.0" SmallIncrement="0.1" LargeIncrement="1"/> + </HorizontalStack> + </VerticalStack> + </Expandable> + <!--<VerticalStack Margin="20" Spacing="1"> + <HorizontalStack Height="Fit"> + <Label Text="Pce Color" Style="GridLabel"/> + <Label Text="{DebugCurColor}" Style="GridValue"/> + </HorizontalStack> + <HorizontalStack Height="Fit"> + <Label Text="Pce Type" Style="GridLabel"/> + <Label Text="{DebugCurType}" Style="GridValue" /> + </HorizontalStack> + <HorizontalStack Height="Fit"> + <Label Text="Pce Cell" Style="GridLabel"/> + <Label Text="{DebugCurCell}" Style="GridValue"/> + </HorizontalStack> + <HorizontalStack Height="Fit"> + <Label Text="Pce Cell pos" Style="GridLabel"/> + <Label Text="{DebugCurCellPos}" Style="GridValue"/> + </HorizontalStack> + </VerticalStack> + </HorizontalStack>--> + <Expandable Caption="Camera" IsExpanded="false"> + <VerticalStack Height="Fit"> + <Vector3Widget Caption="Rotation" Value="{²CameraRotation}" SmallIncrement="0.01" LargeIncrement="0.1" Maximum="7.0" Decimals="2"/> + <Vector3Widget Caption="Position" Value="{²CameraPosition}" SmallIncrement="0.1" LargeIncrement="1.0" Maximum="20.0" Decimals="1"/> + <HorizontalStack Style="Slid" > + <Label Text="Camera FOV:" Width="100" /> + <Slider Style="LightingSlider" Value="{²CameraFOV}" Decimals="0" Maximum="120" SmallIncrement="1" LargeIncrement="5"/> + </HorizontalStack> + <!--<HorizontalStack Style="Slid" > + <Label Text="Camera Angle:" Width="100" /> + <Slider Style="LightingSlider" Value="{²CameraAngle}" Decimals="1" Maximum="3.0" SmallIncrement="0.1" LargeIncrement="0.1"/> + </HorizontalStack> + <HorizontalStack Style="Slid" > + <Label Text="Camera Y:" Width="100" /> + <Slider Style="LightingSlider" Value="{²CameraY}" Decimals="1" Maximum="30.0" SmallIncrement="0.1" LargeIncrement="1.0"/> + </HorizontalStack> + <HorizontalStack Style="Slid" > + <Label Text="Camera Z:" Width="100" /> + <Slider Style="LightingSlider" Value="{²CameraZ}" Decimals="0" Maximum="30.0" SmallIncrement="1.0" LargeIncrement="5.0"/> + </HorizontalStack>--> + </VerticalStack> + </Expandable> + <Expandable Caption="Lighting" IsExpanded="false"> + <VerticalStack Height="Fit"> + <HorizontalStack Style="Slid" > + <Label Text="Exposure:" Width="100"/> + <Slider Style="LightingSlider" Value="{²Exposure}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> + </HorizontalStack> + <HorizontalStack Style="Slid" > + <Label Text="Gamma:" Width="100" /> + <Slider Style="LightingSlider" Value="{²Gamma}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> + </HorizontalStack> + <HorizontalStack Style="Slid" > + <Label Text="IBL Ambient:" Width="100" /> + <Slider Style="LightingSlider" Value="{²IBLAmbient}" Maximum="50.0" SmallIncrement="0.01" LargeIncrement="0.1"/> + </HorizontalStack> <EnumSelector Caption="Sample count" EnumValue="{²SampleCount}" Height="Fit" Width="Stretched"> <Template> <GroupBox Caption="{./Caption}" CornerRadius="{./CornerRadius}" Foreground="{./Foreground}" Background="{./Background}"> @@ -66,7 +102,7 @@ </Template> </EnumSelector> </VerticalStack> - </Border> - </VerticalStack> + </Expandable> + </VerticalStack> </Window> diff --git a/ui/winSSR.crow b/ui/winSSR.crow index 86ce8b8..6454b08 100644 --- a/ui/winSSR.crow +++ b/ui/winSSR.crow @@ -3,11 +3,11 @@ <VerticalStack Spacing="1" Margin="10" > <HorizontalStack Style="Slid" > <Label Text="Step:" Width="100"/> - <Slider Style="LightingSlider" Value="{²SSRStep}" Decimals="4" Maximum="0.1" SmallIncrement="0.0001" LargeIncrement="0.01"/> + <Slider Style="LightingSlider" Value="{²SSRStep}" Decimals="4" Maximum="1.0" SmallIncrement="0.0001" LargeIncrement="0.01"/> </HorizontalStack> <HorizontalStack Style="Slid" > <Label Text="Depth Threshold:" Width="100" /> - <Slider Style="LightingSlider" Value="{²SSRThreshold}" Decimals="4" Maximum="0.1" SmallIncrement="0.0001" LargeIncrement="0.01"/> + <Slider Style="LightingSlider" Value="{²SSRThreshold}" Decimals="4" Maximum="1.0" SmallIncrement="0.0001" LargeIncrement="0.01"/> </HorizontalStack> <HorizontalStack Style="Slid" > <Label Text="Max Step Count:" Width="100" /> |