Introduction
I once saw a really cool Linux screen saver while working in the Linux labs at school. It had a bunch of colored numbers and letters all over the screen which periodically pulsed and changed. I could tell it was some kind of program interpreter and that the cycling pulses were running code, but beyond that I didn't have a clue.
Some time later (and not too long ago), I had the urge to write a similar screen saver. My friend shot down my ideas one by one and then suggested I do a port of the original Linux screen saver. That's precisely what I've done.
The Windows Virtual Machine (WVM) screen saver is distributed under the GNU General Public License (GPL). It requires at least Windows NT 4.0 and DirectX 8.0 to run. The source code is provided in Visual C++ 6.0 format. The original screen saver was written by Artur Rataj and is called KVM.
Getting Started
If you want to get the screen saver up and running, extract wvm.scr to your system directory (probably C:\WINDOWS\SYSTEM32). Then right-click on the Desktop, select Properties, and click on the Screen Saver tab. Select the Virtual Machine screen saver from the list. You can now click Settings to change the simulation parameters, click Test to see the screen saver, and click OK to set this as your screen saver.
For details on what the screen saver actually does, click on Help in the Settings dialog. There's a rather exhaustive explanation from the user's perspective there. What follows is an overview from the programmer's perspective.
Framework
The screen saver is divided into four main modules:
- Display.cpp / Display.h
- ScreenSaver.cpp / ScreenSaver.h
- Settings.cpp / Settings.h
- Simulator.cpp / Simulator.h
ScreenSaver
This is the entry point module. Screen savers that link with scrnsave.lib are required to implement the ScreenSaverProc
function. This function is called when the screen saver is started and terminated. Because the screen saver needs to enter a constantly running loop to function, this function starts a thread which handles the rest of the screen saver and returns immediately. Upon termination, it destroys the thread and ends the screen saver.
The thread creates an instance of the ScreenSaver
class, which is a singleton (only one instance can exist at a time). It then calls the Heartbeat
function, which is the screen saver's main loop, on that instance. This loop continually updates the virtual machine by calling Behave
on it and then requesting a screen paint.
Settings
The settings dialog and registry reading and writing is handled by this module. ScreenSaverConfigureDialog
, another required screen saver function, is augmented by a static Settings
object. This module could probably use a little tidying up but it does the job well.
Display
Nearly all of the DirectX code is contained in this module. The item of interest is the singleton Display
class. The code is very minimal because screen savers don't have to deal with losing the device. The constructor initializes Direct3D and the device, the Paint
function prepares the device for painting, and the Blt
function does a nicely versatile job of painting 2D sprites.
Simulator
This module is the core of the screen saver. Much of the code was taken directly from the Linux original. If you want to really understand it, you'll have to get into the code. I'll point out major landmarks though. Behave
is called each time the main loop repeats. It in turn calls DoCycle
which updates the state of the virtual machine. It also updates all the effects.
Effects are an addition I made to the screen saver that are not found in the original. In essence, the effects are a linked list of Effect
struct
s. They are updated separately from the virtual machine itself and are painted on top of it.
Conclusion
So that's an overview of the Windows Virtual Machine screen saver. You'll get the most benefit from it by rummaging through the code yourself. Feel free to ask any specific questions and I will go into greater detail.
Happy coding!