|
- using Microsoft.Win32;
- using System;
- using System.Drawing;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- using unvell.D2DLib;
- using unvell.D2DLib.WinForm;
-
- namespace GameOfLife
- {
- public partial class MainForm : D2DForm
- {
- private Point mouseLocation;
-
- private bool[,] newCells;
- private bool[,] oldCells;
-
- private Random random;
-
- private int gridSize = 8;
-
- private int magicCells = 0;
-
- private double density = 0.5;
-
- private int interval = 100;
-
- // TODO color
- //private int color;
-
- private D2DRect boundsRect;
-
- private D2DRect cellRect;
-
- private int maxX;
-
- private int maxY;
-
- private int firstX;
- private int lastX;
- private int firstY;
- private int lastY;
-
- private bool previewMode;
-
- [DllImport("user32.dll")]
- static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
-
- [DllImport("user32.dll")]
- static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
-
- [DllImport("user32.dll", SetLastError = true)]
- static extern int GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll")]
- static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect);
-
-
- private void LoadSettings()
- {
- RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\TheoryOfNekomata\\WindowsScreensavers\\GameOfLife");
- var retrievedGridSize = 3;
- var retrievedSpores = 0;
- int retrievedDensity = 50;
- var retrievedInterval = 250;
- var gridSizes = new int[] { 1, 2, 4, 8 };
-
- if (key != null)
- {
- retrievedGridSize = (int)key.GetValue("GridSizeIndex", 3);
- retrievedSpores = (int)key.GetValue("Spores", 0);
- retrievedDensity = (int)key.GetValue("DensityPercentage", 50);
- retrievedInterval = (int)key.GetValue("IntervalMs", 250);
- }
-
- gridSize = gridSizes[retrievedGridSize];
- magicCells = retrievedSpores;
- density = ((double)retrievedDensity) / 100.0;
- interval = retrievedInterval;
- }
-
- private void SetBounds(Rectangle bounds) {
- Bounds = bounds;
- boundsRect = new D2DRect(Bounds.Left, Bounds.Top, Bounds.Width, Bounds.Height);
- }
-
- private void RandomizeCells() {
- random = new Random();
-
- maxX = Bounds.Width / gridSize;
- maxY = Bounds.Height / gridSize;
-
- newCells = new bool[maxX, maxY];
- oldCells = new bool[maxX, maxY];
-
- firstX = oldCells.GetLowerBound(0);
- lastX = oldCells.GetUpperBound(0);
- firstY = oldCells.GetLowerBound(1);
- lastY = oldCells.GetUpperBound(1);
-
- for (var x = 0; x < maxX; x++)
- {
- for (var y = 0; y < maxY; y++)
- {
- newCells[x, y] = random.NextDouble() <= density;
- oldCells[x, y] = false;
- }
- }
- }
-
- public MainForm(Rectangle bounds)
- {
- LoadSettings();
- InitializeComponent();
- SetBounds(bounds);
- RandomizeCells();
- }
-
- public MainForm(IntPtr PreviewWndHandle)
- {
- LoadSettings();
- gridSize = 1;
- magicCells = 0;
- density = 0.5;
- InitializeComponent();
- // Set the preview window as the parent of this window
- SetParent(this.Handle, PreviewWndHandle);
-
- // Make this a child window so it will close when the parent dialog closes
- // GWL_STYLE = -16, WS_CHILD = 0x40000000
- SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000));
-
- // Place our window inside the parent
- Rectangle ParentRect;
- GetClientRect(PreviewWndHandle, out ParentRect);
- Size = ParentRect.Size;
- Location = new Point(0, 0);
- RandomizeCells();
- previewMode = true;
- }
-
-
- private void MainForm_Load(object sender, EventArgs e)
- {
- Cursor.Hide();
- TopMost = true;
-
- timer.Interval = interval;
- timer.Tick += new EventHandler(timer_Tick);
- timer.Start();
- }
-
- private void MainForm_MouseMove(object sender, MouseEventArgs e)
- {
- if (!previewMode)
- {
- if (!mouseLocation.IsEmpty)
- {
- // Terminate if mouse is moved a significant distance
- if (Math.Abs(mouseLocation.X - e.X) > 5 ||
- Math.Abs(mouseLocation.Y - e.Y) > 5)
- Application.Exit();
- }
-
- // Update current mouse location
- mouseLocation = e.Location;
- }
- }
-
- private void MainForm_MouseClick(object sender, MouseEventArgs e)
- {
-
- if (!previewMode)
- {
- Application.Exit();
- }
- }
-
- private void MainForm_KeyPress(object sender, KeyPressEventArgs e)
- {
-
- if (!previewMode)
- {
- Application.Exit();
- }
- }
-
- private int GetAliveNeighbors(int x, int y) {
- int prevX = x == firstX ? lastX : x - 1;
- int nextX = x == lastX ? firstX : x + 1;
- int prevY = y == firstY ? lastY : y - 1;
- int nextY = y == lastY ? firstY : y + 1;
-
- int aliveNeighbors = 0;
- if (oldCells[prevX, prevY]) {
- aliveNeighbors += 1;
- }
- if (oldCells[x, prevY])
- {
- aliveNeighbors += 1;
- }
- if (oldCells[nextX, prevY])
- {
- aliveNeighbors += 1;
- }
- if (oldCells[prevX, y])
- {
- aliveNeighbors += 1;
- }
- if (oldCells[nextX, y])
- {
- aliveNeighbors += 1;
- }
- if (oldCells[prevX, nextY])
- {
- aliveNeighbors += 1;
- }
- if (oldCells[x, nextY])
- {
- aliveNeighbors += 1;
- }
- if (oldCells[nextX, nextY])
- {
- aliveNeighbors += 1;
- }
- return aliveNeighbors;
- }
-
- private void timer_Tick(object sender, EventArgs e) {
- for (var x = 0; x < newCells.GetLength(0); x++)
- {
- for (var y = 0; y < newCells.GetLength(1); y++)
- {
- oldCells[x, y] = newCells[x, y];
- }
- }
-
- for (var x = 0; x < newCells.GetLength(0); x++)
- {
- for (var y = 0; y < newCells.GetLength(1); y++)
- {
- int neighbors = GetAliveNeighbors(x, y);
- bool shouldLive = false;
- if (oldCells[x, y] && neighbors == 2)
- {
- shouldLive = true;
- } else if (!oldCells[x, y] && neighbors == 3) {
- shouldLive = true;
- }
-
- newCells[x, y] = shouldLive;
- }
- }
-
- for (var i = 0; i < magicCells; i++) {
- int magicX = random.Next(0, newCells.GetUpperBound(0));
- int magicY = random.Next(0, newCells.GetUpperBound(1));
-
- newCells[magicX, magicY] = true;
- }
- Refresh();
- }
-
- protected override void OnRender(D2DGraphics graphics)
- {
- graphics.FillRectangle(boundsRect, D2DColor.White);
-
- for (var x = 0; x < newCells.GetLength(0); x++)
- {
- for (var y = 0; y < newCells.GetLength(1); y++)
- {
- if (!newCells[x, y])
- {
- cellRect = new D2DRect(x * gridSize, y * gridSize, gridSize, gridSize);
- graphics.FillRectangle(cellRect, D2DColor.Black);
- }
- }
- }
- }
- }
- }
|