Friday, December 05, 2008

SDL AcidWarp for Windows and SDL full screen mode issues

AcidWarp is an eye-candy program by Noah Spurrier. It draws patterns based on mathematical functions and then animates them via colour cycling. It originally ran in MS-DOS, and used the VGA 320x200 256 colour mode. In 2000 I was developing a library to emulate palletized 256 colour mode in the X Window System, and I modified the Linux SVGALib port of AcidWarp to use that library. Now I just had to modify it again to use SDL instead.

I was partly right about it being trivial. Using SDL for display was trivial. Adding keyboard input was very easy. However, full screen mode was a problem. Much to my surprise, SDL defaults to the windib driver, not directx (windx5). This means it uses the obsolete WinG interface to draw images instead of (the DirectDraw component of an older version of) DirectX. Windows doesn't normally allow programs to alter the whole palette, and SDL uses SetSystemPaletteUse to try to get access to the whole palette. Windows 2000 and XP can allow access to the whole palette (if the uUsage parameter is set to SYSPAL_NOSTATIC256) but other versions of Windows at least retain two entries for black and white (if uUsage is set to SYSPAL_NOSTATIC, which I think is an inappropriate name). This leads to some colours being remapped at the upper end of the palette, with multiple colours mapping to single colours. When this happens, part of the AcidWarp display is degraded, and with some patterns it's very obvious. It's easy to get around this by setting SDL_VIDEODRIVER to directx, but then Windows Vista turns off Aero when the program goes fullscreen, and Aero stays off until the program exits. The way around this problem is to totally shut down SDL with SDL_Quit and reinitialize it when switching from full screen to windowed mode. Aero is still shut down when in full screen mode, but that is not a problem. Initially I used the windib driver for full screen mode and directx for windowed mode. Soon I realized I probably only had to do the shutdown when leaving windowed mode and I could always use the directx driver, but when I made these changes I found that full screen mode sometimes becomes extremely slow (about 1 FPS animation) with high CPU usage. It seems like the version which switched between windib and directx didn't have this problem, but I'm not certain.

If you're not using Windows, you can ignore all that and try to compile the code for your operating system. The Makefile may need tweaking, but the code should be portable. All of the Windows-specific hack described above is conditional on WIN32 being defined.

Finally, here's a link to a zip file with the source and binaries. Take note of this notice which appears on Noah's page on AcidWarp: I do not accept responsibility for damage to persons or property that comes from the use or installation of this software. Use this software at your own risk. This software is free. Also, note that what I'm offering here is a new port which hasn't been tested extensively. I also think that the colour cycling patterns displayed by AcidWarp may cause seizures in individuals who are vulnerable to that sort of thing, especially if the animation is sped up, so please be careful.

[ Edit: Updated to latest version with some fixes in the Vista full screen workaround and a .reg file which should finally allow 256 colour full screen mode in Windows 7. ]

4 comments:

Anonymous said...

Thank you so much for this! AcidWarp is a classic...

Alex said...

Wow thx , there's still a problem with dual monitors tho in fullscreen sadly but a least it work...

Wish this would be ported to a full high-res high color version...

Boris Gjenero said...

Wow, yeah, what happens with multiple monitors is horrible: full screen AcidWarp is always on my main monitor, but both monitors are switched to 256 colour mode, and the second monitor cannot be used while AcidWarp is full screen.

This may be an SDL and/or Windows limitation. I'm not sure if Windows can only switch one monitor to 256 colour mode, and it doesn't seem like there's an SDL API for making a window full screen on one monitor while allowing the other to be used normally. It would be best to get rid of SDL and not need that mode change.

After that, it could be possible to do calculations with more precision and get rid of some of the banding. However, I also think banding can look nice in some situations.

The resolution in full screen mode can be changed now. When switching to full screen mode, the program chooses the video mode with the number of pixels that's closest to the window size.

Zac Mussatt said...

Awesome! This is one of the first programs I ever downloaded back in the BBS days.