ScreensaverStars/ScreenSaver/ScreenSaverForm.cs

310 lines
9.5 KiB
C#
Raw Permalink Normal View History

2022-09-03 23:45:44 -04:00
/*
* ScreenSaverForm.cs
* By Frank McCown
* Summer 2010
*
* Feel free to modify this code.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace ScreenSaver
{
public partial class ScreenSaverForm : Form
{
#region Win32 API functions
[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);
#endregion
private static readonly int MAXSTARS = 1000;
private static readonly int MAXPOS = 3000;
private static readonly int MAXWARP = 3;
public struct StarRec
{
public decimal[] x, y, z;
public decimal offsetX, offsetY, offsetR, rotation;
};
decimal nitro = 0;
int m_windW;
int m_windH;
readonly int starCount = MAXSTARS / 2;
decimal m_speed = 0.2m;
StarRec[] m_stars;
private Point mouseLocation;
private bool previewMode = false;
private readonly Random rand = new Random((int)DateTime.Now.Ticks);
public ScreenSaverForm()
{
InitializeComponent();
Init();
}
public ScreenSaverForm(Rectangle Bounds)
{
InitializeComponent();
this.Bounds = Bounds;
Init();
}
public ScreenSaverForm(IntPtr PreviewWndHandle)
{
InitializeComponent();
Init();
// 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
SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000));
// Place our window inside the parent
GetClientRect(PreviewWndHandle, out Rectangle ParentRect);
Size = ParentRect.Size;
Location = new Point(0, 0);
previewMode = true;
}
private void ScreenSaverForm_Load(object sender, EventArgs e)
{
Cursor.Hide();
TopMost = true;
moveTimer.Interval = 10;
moveTimer.Tick += new EventHandler(MoveTimer_Tick);
moveTimer.Start();
NitroTimer.Interval = 180000;
NitroTimer.Start();
}
private void MoveTimer_Tick(object sender, System.EventArgs e)
{
this.Invalidate();
}
private void ScreenSaverForm_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 ScreenSaverForm_KeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar)
{
case 'x':
nitro = 3;
break;
case '+':
case '=':
m_speed += 0.001m;
break;
case '-':
case '_':
m_speed -= 0.001m;
break;
default:
if (!previewMode)
Application.Exit();
break;
}
}
private void ScreenSaverForm_MouseClick(object sender, MouseEventArgs e)
{
if (!previewMode)
Application.Exit();
}
private void Init()
{
int n;
m_windW = Bounds.Width;
m_windH = Bounds.Height;
m_stars = new StarRec[MAXSTARS];
for (n = 0; n < MAXSTARS; n++)
{
NewStar(n, 100);
}
this.DoubleBuffered = true;
}
void NewStar(int n, int d)
{
m_stars[n].x = new decimal[] { 0, 0 };
m_stars[n].y = new decimal[] { 0, 0 };
m_stars[n].z = new decimal[] { 0, 0 };
m_stars[n].x[0] = (rand.Next() % MAXPOS) - MAXPOS / 2;
m_stars[n].y[0] = (rand.Next() % MAXPOS) - MAXPOS / 2;
m_stars[n].z[0] = (rand.Next() % MAXPOS) + d;
m_stars[n].x[1] = m_stars[n].x[0];
m_stars[n].y[1] = m_stars[n].y[0];
m_stars[n].z[1] = m_stars[n].z[0];
m_stars[n].offsetX = 0;
m_stars[n].offsetY = 0;
m_stars[n].offsetR = 0;
}
bool StarPoint(int n)
{
decimal x0, y0;
x0 = m_stars[n].x[0] * m_windW / m_stars[n].z[0];
y0 = m_stars[n].y[0] * m_windH / m_stars[n].z[0];
x0 += m_windW / 2;
y0 += m_windH / 2;
if (x0 >= 0 && x0 < m_windW && y0 >= 0 && y0 < m_windH)
{
return true;
}
return false;
}
void ShowStar(int n, PaintEventArgs e)
{
decimal x0, y0, x1, y1;
x0 = m_stars[n].x[0] * m_windW / m_stars[n].z[0];
y0 = m_stars[n].y[0] * m_windH / m_stars[n].z[0];
x0 += m_windW / 2;
y0 += m_windH / 2;
if (x0 >= 0 && x0 < m_windW && y0 >= 0 && y0 < m_windH)
{
x1 = m_stars[n].x[1] * m_windW / m_stars[n].z[1];
y1 = m_stars[n].y[1] * m_windH / m_stars[n].z[1];
x1 += m_windW / 2;
y1 += m_windH / 2;
Color color = Color.FromArgb((int) (255 * ((MAXWARP - m_speed) / MAXWARP)), (int)(255 * ((MAXWARP - m_speed) / MAXWARP)), 255);
using (Pen pen = new Pen(color, (float)(MAXPOS / 100 / m_stars[n].z[0] + 2)))
{
if (Math.Abs(x0 - x1) < 1 && Math.Abs(y0 - y1) < 1)
{
e.Graphics.DrawLine(pen, (float)x0, (float)y0, (float)x0, (float)y0);
}
else
{
e.Graphics.DrawLine(pen, (float)x0, (float)y0, (float)x1, (float)y1);
}
}
var s = m_speed >= 1.0m ? $"Warp Factor {m_speed}" : $"Impulse {m_speed}";
using (Brush b = new SolidBrush(Color.White))
e.Graphics.DrawString(s, new Font(FontFamily.GenericMonospace, 8.0f), b, 0, 0);
}
}
void ShowStars(PaintEventArgs e)
{
int n;
decimal offset;
for (n = 0; n < starCount; n++)
{
if (nitro > 0)
{
m_speed = (nitro / 10.0m) + 0.2m;
if (m_speed > MAXWARP)
{
m_speed = MAXWARP;
}
nitro += 0.0001m;
if (nitro > MAXWARP * 10)
{
nitro = -nitro;
}
}
else if (nitro < 0)
{
nitro += 0.0001m;
m_speed = (-nitro / 10.0m) + 0.2m;
if (m_speed > MAXWARP)
{
m_speed = MAXWARP;
}
}
offset = m_speed * 60;
m_stars[n].x[1] = m_stars[n].x[0];
m_stars[n].y[1] = m_stars[n].y[0];
m_stars[n].z[1] = m_stars[n].z[0];
m_stars[n].x[0] = m_stars[n].x[0] + m_stars[n].offsetX;
m_stars[n].y[0] = m_stars[n].y[0] + m_stars[n].offsetY;
m_stars[n].z[0] = m_stars[n].z[0] - offset;
m_stars[n].rotation = m_stars[n].rotation + m_stars[n].offsetR;
if (m_stars[n].z[0] > m_speed || (m_stars[n].z[0] > 0 && m_speed < MAXWARP))
{
if (!StarPoint(n))
{
NewStar(n, MAXPOS);
}
}
else
{
NewStar(n, MAXPOS);
}
if (m_stars[n].z[0] > m_speed || (m_stars[n].z[0] > 0 && m_speed < MAXWARP))
{
ShowStar(n, e);
}
}
}
private void ScreenSaverForm_Paint(object sender, PaintEventArgs e)
{
ShowStars(e);
}
private void NitroTimer_Tick(object sender, EventArgs e)
{
nitro = 10;
}
}
}