diff --git a/RhythmThing/Objects/Test Objects/MultiWindowTest.cs b/RhythmThing/Objects/Test Objects/MultiWindowTest.cs new file mode 100644 index 0000000..f700f2b --- /dev/null +++ b/RhythmThing/Objects/Test Objects/MultiWindowTest.cs @@ -0,0 +1,77 @@ +using RhythmThing.System_Stuff; +using System; +using System.Collections.Generic; +using System.Text; +using RhythmThing.Components; +namespace RhythmThing.Objects.Test_Objects +{ + + class MultiWindowTest : GameObject + { + SlaveManager manager; + SlaveManager manager2; + SlaveManager manager3; + private Visual visualTest; + public override void End() + { + + } + + public override void Start(Game game) + { + manager = new SlaveManager("A", 50, 50); + manager2 = new SlaveManager("B", 30, 30); + manager3 = new SlaveManager("C", 20, 50); + + Input.focusInput = false; + visualTest = new Visual(); + visualTest.LoadBMP("RightReceiver.bmp"); + manager.visuals.Add(visualTest); + manager2.visuals.Add(visualTest); + manager3.visuals.Add(visualTest); + } + + public override void Update(double time, Game game) + { + if(game.input.ButtonStates[Input.ButtonKind.Right] == Input.ButtonState.Press) + { + manager.MoveWindowEase(-100, -100, 100, 100, 5, "easeInOutExpo"); + + + visualTest.x++; + } + if (game.input.ButtonStates[Input.ButtonKind.Left] == Input.ButtonState.Press) + { + manager.MoveWindow(100, 0); + manager2.MoveWindow(100, 0); + + visualTest.x--; + } + if (game.input.ButtonStates[Input.ButtonKind.Up] == Input.ButtonState.Press) + { + manager.MoveWindow(0, 100); + manager2.MoveWindow(0, 100); + + visualTest.y++; + } + if (game.input.ButtonStates[Input.ButtonKind.Down] == Input.ButtonState.Press) + { + manager.MoveWindow(100, 100); + manager2.MoveWindow(100, 100); + + visualTest.y--; + } + if (manager.alive) + { + manager.UpdateVisuals(); + + } + manager2.UpdateVisuals(); + manager3.UpdateVisuals(); + if(game.input.ButtonStates[Input.ButtonKind.Cancel] == Input.ButtonState.Press) + { + manager.CloseWindow(); + } + } + } +} diff --git a/RhythmThing/Program.cs b/RhythmThing/Program.cs index 0585ca5..671f46e 100644 --- a/RhythmThing/Program.cs +++ b/RhythmThing/Program.cs @@ -7,6 +7,7 @@ using RhythmThing.Utils; using System.IO; using System.Security.Cryptography; +using System.Diagnostics; namespace RhythmThing { @@ -37,6 +38,13 @@ class Program static void Main(string[] args) { + if(args.Length > 0) + { + SlaveWindow slave = new SlaveWindow(args); + + } else + { + contentPath = Path.Combine(Directory.GetCurrentDirectory(), "!Content"); //backup last log Logger.NewLog(); @@ -56,10 +64,11 @@ static void Main(string[] args) PlayerSettings.Instance.ReadSettings(); Game main = new Game(ScreenX, ScreenY); - //testOUTPUT test = new testOUTPUT(); - // test.Setup(); - //put in test object - // main.addGameObject(new LeftArrow()); + //testOUTPUT test = new testOUTPUT(); + // test.Setup(); + //put in test object + // main.addGameObject(new LeftArrow()); + } } } } diff --git a/RhythmThing/Scenes/TestScene.cs b/RhythmThing/Scenes/TestScene.cs index e7a04ad..b009e3c 100644 --- a/RhythmThing/Scenes/TestScene.cs +++ b/RhythmThing/Scenes/TestScene.cs @@ -11,14 +11,14 @@ class TestScene : Scene { public TestScene() { - this.name = "BMP Testing"; + this.name = "Testing"; this.index = 5; } public override void Start() { initialObjs = new List(); - initialObjs.Add(new RotationTest()); + initialObjs.Add(new MultiWindowTest()); } diff --git a/RhythmThing/System Stuff/Game.cs b/RhythmThing/System Stuff/Game.cs index 5edd2ff..73496d6 100644 --- a/RhythmThing/System Stuff/Game.cs +++ b/RhythmThing/System Stuff/Game.cs @@ -49,6 +49,9 @@ public class Game //private List toRemove; //for our good ol friend deltatime Stopwatch stopwatch = new Stopwatch(); + + + public Game(int screenX, int screenY) { this.screenX = screenX; @@ -74,10 +77,10 @@ public Game(int screenX, int screenY) sceneManager = new SceneManager(this); //entry point - sceneManager.loadScene(0); + //sceneManager.loadScene(0); //debug scene - //sceneManager.loadScene(5); + sceneManager.loadScene(5); while (gameLoopLives) { diff --git a/RhythmThing/System Stuff/Input.cs b/RhythmThing/System Stuff/Input.cs index ad32212..4ac5cea 100644 --- a/RhythmThing/System Stuff/Input.cs +++ b/RhythmThing/System Stuff/Input.cs @@ -29,7 +29,7 @@ public class Input private int _escCode = 1; */ - + public static bool focusInput = true; private static Input _instance; public static Input Instance { get { @@ -196,7 +196,7 @@ public void UpdateInput() - if (!WindowManager.isFocused()) + if (!WindowManager.isFocused() && focusInput) { return; } diff --git a/RhythmThing/System Stuff/SlaveDisplay.cs b/RhythmThing/System Stuff/SlaveDisplay.cs new file mode 100644 index 0000000..e25f8fd --- /dev/null +++ b/RhythmThing/System Stuff/SlaveDisplay.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.Text; +using RhythmThing.Components; + +namespace RhythmThing.System_Stuff +{ + class SlaveDisplay + { + ushort None = 0x0000; + ushort FOREGROUND_BLUE = 0x0001; + ushort FOREGROUND_GREEN = 0x0002; + ushort FOREGROUND_RED = 0x0004; + ushort FOREGROUND_INTENSITY = 0x0008; + ushort BACKGROUND_BLUE = 0x0010; + ushort BACKGROUND_GREEN = 0x0020; + ushort BACKGROUND_RED = 0x0040; + ushort BACKGROUND_INTENSITY = 0x0080; + ushort COMMON_LVB_LEADING_BYTE = 0x0100; + ushort COMMON_LVB_TRAILING_BYTE = 0x0200; + ushort COMMON_LVB_GRID_HORIZONTAL = 0x0400; + ushort COMMON_LVB_GRID_LVERTICAL = 0x0800; + ushort COMMON_LVB_GRID_RVERTICAL = 0x1000; + ushort COMMON_LVB_REVERSE_VIDEO = 0x4000; + ushort COMMON_LVB_UNDERSCORE = 0x8000; + + ConsoleColor[,] currentForeColors; + ConsoleColor[,] currentBackColors; + char[,] currentFinalChars; + public WindowManager windowManager; + //consoleb + //private ConsoleColor[,] finalPixels; //ech terminology consistency what is that + public SlaveDisplay() + { + + + currentForeColors = new ConsoleColor[Program.ScreenX, Program.ScreenY]; + currentBackColors = new ConsoleColor[Program.ScreenX, Program.ScreenY]; + currentFinalChars = new char[Program.ScreenX, Program.ScreenY]; + windowManager = new WindowManager(); + windowManager.InitWindow(); + windowManager.CenterWindow(); + //windowManager.moveWindow(0.75f, 0.75f); + } + + + + public void DrawFrame(SlaveManager.SlaveData data) + { + + //remove objects from main list that need to be + + //add objects to main list that need to be + + ConsoleColor[,] finalForeColors = new ConsoleColor[Program.ScreenX, Program.ScreenY]; + ConsoleColor[,] finalBackColors = new ConsoleColor[Program.ScreenX, Program.ScreenY]; + char[,] finalChars = new char[Program.ScreenX, Program.ScreenY]; + //sosorry + + + //DisplayData newData = screenFilter.RunFilt(finalForeColors, finalBackColors, finalChars); + finalForeColors = data.foreColors; + finalBackColors = data.backColors; + finalChars = data.characters; + + //not gonna try drawing this way anymore... + /* + Console.SetCursorPosition(0, 0); + for (int y = 0; y < Program.ScreenY; y++) + { + for (int x = 0; x < Program.ScreenX; x++) + { + //only draw changes + if(currentBackColors[x, y] != finalBackColors[x,y] || currentForeColors[x,y] != finalForeColors[x,y] || currentFinalChars[x,y] != finalChars[x,y]) + { + Console.SetCursorPosition(x, Program.ScreenY - y); + Console.ForegroundColor = finalForeColors[x, y]; + Console.BackgroundColor = finalBackColors[x, y]; + Console.Write(finalChars[x, y]); + } + + } + } + */ + //here we go oh boy. + WindowManager.CHAR_INFO[] buffer = new WindowManager.CHAR_INFO[Program.ScreenX * Program.ScreenY]; + + for (int y = 0; y < Program.ScreenY; y++) + { + for (int x = 0; x < Program.ScreenX; x++) + { + ushort attributes = None; + switch (finalForeColors[x, Program.ScreenY - (y + 1)]) + { + case ConsoleColor.Black: + attributes = None; + break; + case ConsoleColor.DarkBlue: + attributes = FOREGROUND_BLUE; + break; + case ConsoleColor.DarkGreen: + attributes = FOREGROUND_GREEN; + break; + case ConsoleColor.DarkCyan: + attributes = (ushort)(FOREGROUND_GREEN | FOREGROUND_BLUE); + break; + case ConsoleColor.DarkRed: + attributes = FOREGROUND_RED; + break; + case ConsoleColor.DarkMagenta: + attributes = (ushort)(FOREGROUND_RED | FOREGROUND_BLUE); + break; + case ConsoleColor.DarkYellow: + attributes = (ushort)(FOREGROUND_RED | FOREGROUND_GREEN); + break; + case ConsoleColor.Gray: + attributes = (ushort)(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); + break; + case ConsoleColor.DarkGray: + attributes = FOREGROUND_INTENSITY; + break; + case ConsoleColor.Blue: + attributes = (ushort)(FOREGROUND_BLUE | FOREGROUND_INTENSITY); + break; + case ConsoleColor.Green: + attributes = (ushort)(FOREGROUND_GREEN | FOREGROUND_INTENSITY); + break; + case ConsoleColor.Cyan: + attributes = (ushort)(FOREGROUND_BLUE | FOREGROUND_BLUE | FOREGROUND_INTENSITY); + break; + case ConsoleColor.Red: + attributes = (ushort)(FOREGROUND_RED | FOREGROUND_INTENSITY); + break; + case ConsoleColor.Magenta: + attributes = (ushort)(FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); + break; + case ConsoleColor.Yellow: + attributes = (ushort)(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); + break; + case ConsoleColor.White: + attributes = (ushort)(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); + break; + default: + break; + } + + ushort backattribute = None; + switch (finalBackColors[x, Program.ScreenY - (y + 1)]) + { + case ConsoleColor.Black: + backattribute = None; + break; + case ConsoleColor.DarkBlue: + backattribute = BACKGROUND_BLUE; + break; + case ConsoleColor.DarkGreen: + backattribute = BACKGROUND_GREEN; + break; + case ConsoleColor.DarkCyan: + backattribute = (ushort)(BACKGROUND_GREEN | BACKGROUND_BLUE); + break; + case ConsoleColor.DarkRed: + backattribute = BACKGROUND_RED; + break; + case ConsoleColor.DarkMagenta: + backattribute = (ushort)(BACKGROUND_RED | BACKGROUND_BLUE); + break; + case ConsoleColor.DarkYellow: + backattribute = (ushort)(BACKGROUND_RED | BACKGROUND_GREEN); + break; + case ConsoleColor.Gray: + backattribute = (ushort)(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED); + break; + case ConsoleColor.DarkGray: + backattribute = BACKGROUND_INTENSITY; + break; + case ConsoleColor.Blue: + backattribute = (ushort)(BACKGROUND_BLUE | BACKGROUND_INTENSITY); + break; + case ConsoleColor.Green: + backattribute = (ushort)(BACKGROUND_GREEN | BACKGROUND_INTENSITY); + break; + case ConsoleColor.Cyan: + backattribute = (ushort)(BACKGROUND_BLUE | BACKGROUND_BLUE | BACKGROUND_INTENSITY); + break; + case ConsoleColor.Red: + backattribute = (ushort)(BACKGROUND_RED | BACKGROUND_INTENSITY); + break; + case ConsoleColor.Magenta: + backattribute = (ushort)(BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY); + break; + case ConsoleColor.Yellow: + backattribute = (ushort)(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY); + break; + case ConsoleColor.White: + backattribute = (ushort)(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY); + break; + default: + break; + } + + //im so sorry for these switch cases interop is not nice + attributes = (ushort)(backattribute | attributes); + + buffer[y * Program.ScreenX + x] = new WindowManager.CHAR_INFO { UnicodeChar = finalChars[x, Program.ScreenY - (y + 1)], Attributes = attributes }; + } + } + //buffer[1 + 1] = new WindowManager.CHAR_INFO { UnicodeChar = 'h', Attributes = (ushort)(BACKGROUND_BLUE | FOREGROUND_GREEN ) }; + windowManager.RenderBuffer(buffer); + //save changes + currentBackColors = finalBackColors; + currentForeColors = finalForeColors; + currentFinalChars = finalChars; + + } + } +} + diff --git a/RhythmThing/System Stuff/SlaveManager.cs b/RhythmThing/System Stuff/SlaveManager.cs new file mode 100644 index 0000000..809dcdf --- /dev/null +++ b/RhythmThing/System Stuff/SlaveManager.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using RhythmThing.Components; +using System.Text; +using System.IO.MemoryMappedFiles; +using System.IO.Pipes; +using System.IO; +namespace RhythmThing.System_Stuff +{ + public class SlaveManager + { + public static List aliveWindows = new List(); + public struct SlaveData + { + public ConsoleColor[,] foreColors; + public ConsoleColor[,] backColors; + public char[,] characters; + + } + public bool alive = true; + Process slaveProcess; + public SlaveData displayData; + MemoryMappedFile mappedFile; + private NamedPipeServerStream pipe; + private StreamWriter writer; + MemoryMappedViewAccessor accessor; + long length; + private int x; + private int y; + public List visuals; + public static long getLength(int x, int y) + { + return ((x * y) * 4) * 3; + } + public void UpdateVisuals() + { + displayData.foreColors = new ConsoleColor[x, y]; + displayData.backColors = new ConsoleColor[x, y]; + displayData.characters = new char[x, y]; + visuals.Sort((x, y) => x.z.CompareTo(y.z)); + visuals.ForEach(visual => + { + visual.localPositions.ForEach(coord => + { + int locX = visual.x + coord.x; + int locY = visual.y + coord.y; + if(!((locX >= x) ||(locX < 0 ) || (locY >= y) || (locY < 0))) + { + displayData.foreColors[locX, locY] = coord.foreColor; + displayData.backColors[locX, locY] = coord.backColor; + displayData.characters[locX, locY] = coord.character; + + } + }); + }); + Draw(); + } + public void Draw() + { + int curWrite = 0; + for (int lX = 0; lX < x; lX += 1) + { + for (int lY = 0; lY < y; lY += 1) + { + accessor.Write(curWrite, (int)displayData.foreColors[lX, lY]); + curWrite += 4; + accessor.Write(curWrite, (int)displayData.backColors[lX, lY]); + curWrite += 4; + accessor.Write(curWrite, displayData.characters[lX, lY]); + curWrite += 2; + } + } + } + public void CloseWindow() + { + if(pipe.IsConnected) + { + + + writer.AutoFlush = true; + writer.WriteAsync("close"); + pipe.Disconnect(); + accessor.Dispose(); + mappedFile.Dispose(); + aliveWindows.Remove(this); + this.alive = false; + + } + } + public static void CloseAll() + { + SlaveManager[] alive = aliveWindows.ToArray(); + for (int i = 0; i < alive.Length; i++) + { + alive[i].CloseWindow(); + } + } + + public void MoveWindow(float x, float y) + { + x = (float)(x / 100) * 0.5f + 0.75f; + y = (y / 100) * 0.5f + 0.75f; + writer.Write($"SetWindowPos|{x}|{y}|"); + + + } + public void MoveWindowEase(float startX, float startY, float endX, float endY, float duration, string easing) + { + startX = (float)(startX / 100) * 0.5f + 0.75f; + startY = (startY / 100) * 0.5f + 0.75f; + endX = (float)(endX / 100) * 0.5f + 0.75f; + endY = (endY / 100) * 0.5f + 0.75f; + writer.Write($"SetWindowEase|{startX}|{startY}|{endX}|{endY}|{duration}|{easing}|"); + } + //if for one reason or another the ease MUST end + public void EndEase() { + writer.Write($"StopEase|"); + } + public SlaveManager(string arg, int x, int y) + { + visuals = new List(); + this.x = x; + this.y = y; + length = getLength(x, y); + mappedFile = MemoryMappedFile.CreateNew(arg, length); + displayData = new SlaveData(); + displayData.foreColors = new ConsoleColor[x, y]; + displayData.backColors = new ConsoleColor[x, y]; + displayData.characters = new char[x, y]; + //just for now + for (int xl = 0; xl < 10; xl++) + { + for (int yl = 0; yl < 10; yl++) + { + displayData.foreColors[xl, yl] = ConsoleColor.Red; + displayData.backColors[xl, yl] = ConsoleColor.Red; + displayData.characters[xl, yl] = arg.ToCharArray()[0]; + + } + } + ProcessStartInfo processStartInfo = new ProcessStartInfo + { + FileName = "RhythmThing.exe", + CreateNoWindow = false, + UseShellExecute = true, + Arguments = $"{arg} {x} {y}" + + }; + accessor = mappedFile.CreateViewAccessor(); + + pipe = new NamedPipeServerStream(arg); + + slaveProcess = Process.Start(processStartInfo); + pipe.WaitForConnection(); + writer = new StreamWriter(pipe); + writer.AutoFlush = true; + aliveWindows.Add(this); + } + + } +} diff --git a/RhythmThing/System Stuff/SlaveWindow.cs b/RhythmThing/System Stuff/SlaveWindow.cs new file mode 100644 index 0000000..a0ca9a6 --- /dev/null +++ b/RhythmThing/System Stuff/SlaveWindow.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO.MemoryMappedFiles; +using System.Diagnostics; +using System.IO.Pipes; +using RhythmThing.Utils; +using System.Threading; + +namespace RhythmThing.System_Stuff +{ + public class SlaveWindow + { + private SlaveDisplay display; + public bool alive = true; + MemoryMappedFile file; + private NamedPipeClientStream pipe; + private SlaveManager.SlaveData data; + Stopwatch stopwatch = new Stopwatch(); + public double deltaTime; + + + //ease variables + float timepassed; + float duration; + float startX; + float startY; + float endX; + float endY; + string easing; + bool easeGo; + // + + public SlaveWindow(string[] arg) + { + deltaTime = 0; + + //just dont die for now + Program.ScreenX = int.Parse(arg[1]); + Program.ScreenY = int.Parse(arg[2]); + file = MemoryMappedFile.OpenExisting(arg[0]); + pipe = new NamedPipeClientStream(arg[0]); + pipe.Connect(); + + data = new SlaveManager.SlaveData(); + data.foreColors = new ConsoleColor[Program.ScreenX, Program.ScreenY]; + data.backColors = new ConsoleColor[Program.ScreenX, Program.ScreenY]; + data.characters = new char[Program.ScreenX, Program.ScreenY]; + + display = new SlaveDisplay(); + new Thread(() => + { + while (alive) + { + if(!pipe.IsConnected) + { + alive = false; + } + Console.WriteLine("a"); + byte[] messageBuffer = new byte[520]; + pipe.Read(messageBuffer, 0, 520); + string input = Encoding.UTF8.GetString(messageBuffer); + if (input.StartsWith("close")) + { + this.alive = false; + } + string[] args = input.Split("|"); + switch (args[0]) + { + case "SetWindowPos": + display.windowManager.moveWindow(float.Parse(args[1]), float.Parse(args[2])); + break; + case "SetWindowEase": + startX = float.Parse(args[1]); + startY = float.Parse(args[2]); + endX = float.Parse(args[3]); + endY = float.Parse(args[4]); + duration = float.Parse(args[5]); + easing = args[6]; + timepassed = 0; + easeGo = true; + break; + case "StopEase": + timepassed = duration; + + break; + default: + break; + } + + } + }).Start(); + while (alive) + { + + + stopwatch.Start(); + + + var stream = file.CreateViewStream(); + int curOffset = 0; + for (int x = 0; x < Program.ScreenX; x++) + { + for (int y = 0; y < Program.ScreenY; y++) + { + byte[] buffer = new byte[4]; + stream.Read(buffer, 0, 4); + data.foreColors[x, y] = (ConsoleColor)BitConverter.ToInt32(buffer); + curOffset += 4; + + stream.Read(buffer, 0, 4); + data.backColors[x, y] = (ConsoleColor)BitConverter.ToInt32(buffer); + curOffset += 4; + + buffer = new byte[2]; + stream.Read(buffer, 0, 2); + data.characters[x, y] = BitConverter.ToChar(buffer); + curOffset += 2; + } + } + string temp; + //read.ReadLine(); + display.DrawFrame(data); + // + if (easeGo) + { + if(timepassed >= duration) + { + display.windowManager.moveWindow(endX, endY); + } else + { + float x = (startX) + ((endX-startX) * Ease.byName[easing](timepassed / duration)); + float y = (startY) + ((endY - startY) * Ease.byName[easing](timepassed / duration)); + display.windowManager.moveWindow(x, y); + } + timepassed += (float)deltaTime; + } + + Thread.Sleep(1); //just in case + stopwatch.Stop(); + deltaTime = stopwatch.ElapsedMilliseconds * 0.001; + stopwatch.Reset(); + } + + + + } + } + } + diff --git a/RhythmThing/WindowManager.cs b/RhythmThing/System Stuff/WindowManager.cs similarity index 99% rename from RhythmThing/WindowManager.cs rename to RhythmThing/System Stuff/WindowManager.cs index b15cda1..402c56e 100644 --- a/RhythmThing/WindowManager.cs +++ b/RhythmThing/System Stuff/WindowManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text;