310 lines
9.5 KiB
C#
310 lines
9.5 KiB
C#
|
/*
|
|||
|
* 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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|