Friday, June 03, 2011

Falling Stuff 1.0b6 for Mac and Windows

I have a new beta of the Falling Stuff screensaver ready to go for both Mac and Windows. Here's what's new:
  • made lines a bit wider, which should help remove jagged edges.
  • improved performance on Macs.
  • added an experimental, screen-blanking battery saver mode for laptops. If enabled, this'll put the screensaver into a low-power mode when the computer is unplugged. Nothing will get displayed while in low-power mode, but the battery won't be unnecessarily drained either. Plugging the power back in will resume the screensaver. This option is turned off by default and can be turned on in the screensaver's options menu.
  • new Windows installer (exciting, I know ;-) )
Regarding the Mac version, I did have a chance to test it out on a preview release of Mac OS X Lion and it ran great!

Basic information on the screensaver, including installation instructions and a list of configurable options, can be found in its docs. Here's a link to an online copy:
Finally, here are the download links:
I hope y'all enjoy it!

Saturday, April 09, 2011

Falling Stuff 1.0b4 for Mac OS X Snow Leopard

After a somewhat lengthy hiatus, I've released Beta 4 of the Falling Stuff screensaver. For now, this is a Mac only release, as the only new feature is that the screensaver has is that it's been updated to work on Snow Leopard.

Download Falling Stuff for Mac OS X

To install:

  1. Download and extract the zip file.
  2. Double-click on the extracted, "Falling Stuff.saver" file. This should open Mac OS X's System Preferences app, which'll ask if you want to install it.
  3. Choose "Falling Stuff" from the list of screen savers to preview it and/or use it as the main screensaver.


Feedback much welcomed! I'm especially curious to know if it runs ok on the computers of others. If so, I may re-release this version as 1.0 final.

Friday, September 03, 2010

Shell Scripting for MacOS X: Laundry Timer with Text To Speech Synthesis

I occasionally forget things. Yes, I admit it. In high school, a friend of mine once said that I'd probably forget at home a certain, rear-facing body part if it weren't attached to my body. He was probably right.

In my apartment building, there is a small set of laundry machines: one washer and two dryers. These three machines are to be split between the twelve apartments in the building. It's not a bad amount of machines, except for when people leave things in the machine for extended periods of time. Yes, I have been one of these people. Many apologies to my building mates!

I had a small minute timer that I used to remind me to move the finished laundry. It was nice, super-cheap, portable device that worked very well, at least until it died. Yes, it was ever so slightly tragic, and involved some amount of leaky battery goo. This really shouldn't have been much of a problem, at least in relation to my bad retrieval-of-laundry habits. I could have used one of the other timers in my house, such as the one on the microwave. For a while, that's what I did, except I occasionally missed hearing it, either from being in the wrong room at the wrong time, having headphones on, etc.

This morning, I started trying a slightly different solution. I wrote a simple shell script to tell me when to move my laundry. It started by using the sleep command to wait the proper number of seconds needed for whatever cycle I'd be on (1500 seconds for a wash cycle in my building, 3600 for a dryer load). When the laundry is done, it would use MacOS X's text-to-speech synthesis libraries (via the 'say' command) to verbally announce the machine's completion.

About half an hour of hacking and documentation-searching resulted in the 'laundry' command, along with a better understanding of bash's numeric 'for' loops and math capabilities, among other things.

The 'laundry' command, as it currently exists, takes in a number of minutes as input and then does the following, in order:

  1. prints the current/start time and the amount of time input.
  2. counts down the minutes, waiting as necessary and printing the remaining time along the way.
  3. prints the end time.
  4. over the computer's audio output, it says the word, "Laundry". This is repeated every ten seconds until Ctrl-C is pressed.


For example, given my building's dryers run time of about an hour, I can run the following:

laundry 60


This is roughly what I would see in the terminal (using a smaller wait time of five minutes):


Start Time: Fri Sep 3 20:33:53 EDT 2010
Waiting for 5 minutes (300 seconds).
Press Ctrl-C to exit.
4 minutes left
3 minutes left
2 minutes left
1 minutes left
Done!
End Time: Fri Sep 3 20:33:53 EDT 2010


The complete code is posted below. You can also download it here (use a right-click to save the file). To install it, be sure to mark it as an executable program (via 'chmod +x ~/Downloads/laundry', assuming it's in the common, MacOS X 'Downloads' folder), and also to copy it somewhere in your PATH, such as /usr/local/bin ('sudo mv ~/Downloads/laundry /usr/local/bin'). To note, the last step is purely optional. Not doing so just means you'll have to type in a longer command to run it.


#!/bin/bash
#
# Super-Simple Laundry Timer
# by David Ludwig
#

if [ "$1" == "" ]; then
echo
echo "Usage:"
echo " laundry <time in minutes>"
echo
exit 0
fi

MINUTES=$1
SECONDS=$[$MINUTES * 60]
START_TIME=`date`

echo "Start Time: $START_TIME"
echo "Waiting for $MINUTES minutes ($SECONDS seconds)."
echo "Press Ctrl-C to exit."

for (( i=1; i<=$MINUTES; i++ )); do
sleep 60
MINUTES_LEFT=$[MINUTES - $i]
if [ $MINUTES_LEFT -ne 0 ]; then
echo "$MINUTES_LEFT minutes left"
fi
done

END_TIME=`date`
echo "Done!"
echo "End Time: $END_TIME"

while true; do
say Laundry
sleep 10
done

Wednesday, April 28, 2010

Camera Solitaire Pong

Last weekend I attended a small game jam co-run by a friend of mine, Darren Torpey. The scene was very laid back, and the weekend was fun. I ended up playing around with the openFrameworks C++ toolkit, a multimedia framework of which I had seen a presentation about it a week before. The feature set looked nice, and it was reported to be very easy to use. It had a lot of computer vision features built in, which seemed interesting and was something I hadn't worked with before. I decided to try my hand at writing a pong app using the camera on my laptop. "Camera Solitaire Pong" is the result.

The game is a heavily simplified version of 3rd person 3d pong, whereby the player views tge game world behind their paddle. The world is represented by a boxy corridor. Normally there'd be another paddle at the other end, however I ended up cutting that feature due to time constraints. Instead, the player's goal is to hit a ball of increasing velocity as many times as possible.

Control of the paddle is done through a video camera. The app will attempt to track an object of a player-specified color. Tennis balls work ok, as do many single color objects of similar size. Ultimately I found that a piece of colored duct tape on the hand worked best, and had a good feel (IMO).

The game consists of two screens. The first is a calibration screen, whereby the player clicks on the object they wish to use. Pressing the spacebar brings the player to the second screen, the game screen.

A Mac build is available at: http://alum.wpi.edu/~davidl/Camera_Solitaire_Pong/latest_mac_build

If I get around to it, I'll try porting to Windows. The only Mac specific code in the game involves loading and saving a few variables, such as the calibrated color. I may also try and add a few features to it. I've already tweaked a few settings since the game jam, and added a title and some basic credits.

Here are some screenshots. Clicking on them should bring up larger versions.

Calibration Screen

Game Screen

A big thanks goes out to Laurence Lee, game jam attendee and Berklee College of Music student, for creating several nice sound effects for the game using one of the tennis balls I brought. Special thanks also goes out to Vickie Wu for making tasty food during the event, and to everyone involved in running things or otherwise making for what was a fun weekend!

Sunday, May 24, 2009

Falling Stuff 1.0b3, With Windows Support!

I just finished up a new beta verson of the Falling Stuff screensaver. Here's a list of additions and changes:

  • a Windows version is now available! Windows XP or higher is required. To note:

    • an OpenGL compatible video card and drivers are recommended for performance reasons, but isn't explicitly necessary. If you're unsure whether or not your computer supports this, just note that in this version of the screensaver, performance may be a bit slow. It varies from computer to computer. I have a few thoughts on how to go about addressing this, which I'm considering for future releases.

    • the installer includes an option for the "Microsoft Visual C++ 2005 Redistributable". This is a will install a set of shared libraries that help run apps written in Visual C++, namely this screensaver. :-)


  • for MacBook users, accelerometer-based gravity can now reverse accelerometer-based gravity along its X axis. Some MacBooks were interpreting a tilt to the right as a tilt to the left, and vice-versa. Enabling this option on these machines should cause gravity to go in the correct direction.

  • fixed a bug whereby some fallen objects wouldn't move if accelerometer-based gravity was enabled, and the laptop was tilted in a new direction.

  • prevented a bug in ball-dot drawing.



Download Falling Stuff for Mac OS X


Download Falling Stuff for Windows

Monday, March 30, 2009

Falling Stuff 1.0b2

Last summer, during my annual two week vacation, I ended up starting work on a screensaver. It was a remake of an old After Dark screensaver module called Marbles, whereby marbles would fall to the bottom of the screen, only to be met with a set of large pegs. Using a bit of code I had written on a few lazy Sundays before, along with an excellent 2D Physics engine called Box2D, I was able to get a reasonable simulation up and running. It wasn't quite distributable, due to some occasional crashes, some performance issues, etc., so I never released it. Once my vacation ended, development on it slowed way down.

I recently spent a few days finishing up my screensaver project and now have something to show for. I've called it "Falling Stuff", for lack of a better name. For now, it is for MacOS X only, and only for Intel-based Macs at that, although I do have a Windows version pending (which needs polish, among other things). Also note, I have only tested this on OS X 10.5. In theory, it should run on 10.4 though.

The initial release of Falling Stuff, 1.0b2 (beta 1 was only distributed to a few friends) sports the following features:

* Pegs of two shapes
* Marbles of two shapes
* Hot falling action!
* Accelerometer-based gravity for select laptops (most MacBooks, I believe)

Ok, perhaps not much as of yet. :-) I have been thinking of adding some new features, possibly an interactive mode of some sort.

Anyways, here is a quick screenshot:

Falling Stuff 1.0b2 Screenshot

Falling Stuff 1.0b2 is available for download. If you have an Intel-based Mac, I'd love to hear what you think of it. If you have a Windows-based machine, I hope to have the Windows version out soon, although I doubt accelerometer support will be available for such, unless I can get my hands on some decent code and/or libraries to handle this.

To install, download and extract the zip file, then double click on the "Falling Stuff.saver" file. This should launch System Preferences, which'll ask if you'd like to install it. From there, you can either install it just for yourself, or for all users on the system.

Also, a readme/about file is available as well, which contains some info that wasn't covered in this post.

Sunday, December 07, 2008

Mac OS X Debugging Adventures

For the past few months, I've been spending some of my free time working on a cross-platform screensaver, one that runs under Windows and under Mac OS X. Getting the Windows version up and running was relatively easy. A Windows screensaver is just an exe with a special extension (.scr) and some code to handle a few special command line parameters. Having written Windows game code before helped there. Getting the Mac OS X version running was quite a bit trickier, due in part to my inexperience with OS X. I place some blame on OS X's screensaver engine though, which ended up being rather tricky to work with. It deals with screen savers in a very different manner than Windows' approach. OS X expects screensavers to be represented not as standalone applications, but as dynamically loadable modules, which can be loaded via one of a few different OS X-provided applications.

Every OS X screensaver module must adhere to a certain set of guidelines. Among them, they must be represented as an OS X bundle, they must provide a subclass of the OS-provided ScreenSaverView class, and they should play nice with other screensaver modules. Sounds ok, except I found the implementation of these guidelines to be a bit tricky. Why?


  1. OS X screensavers are subject to control via an external main loop, which each screensaver hooks into (for initialization, shutdown, time-stepping, drawing, etc.) This design seems ok in some ways: having no main loop to create reduces the amount of code needed for each screensaver to implement. I could see ways in which this could be easier for the beginner. In my case, there have been times that I've wanted to debug and profile portions of my screensaver logic using a main loop of my own, and without having to deal with the OS X screensaver engine.
  2. All OS X screensaver modules get loaded into the same address space. Furthermore, they get loaded in such a way that no two modules can share the same symbol names. If two modules implement a function with the same name, there's a good chance one or both of them will crash, even if only one of the two modules is actively displaying a screensaver. One solution to this is to name functions such that they don't clash, such as by appending a unique name to each function. Another solution, the one I chose to work with, is to load almost everything in a second dynamically loaded module, which gets loaded in such a way as not to cause naming clashes (via dlopen with RTLD_LOCAL.)


For the times when I want to debug or profile my app without OS X's screensaver engine getting involved, I can switch to Windows and use that version. I don't always want to switch to Windows though, so I created a small Mac app to help with debugging. It loads the platform-independent portions of the screensaver code and drives them via its own main loop, avoiding the OS X screensaver engine altogether. I recently ran into a problem with that approach though. I created the app, ran it, confirmed that it worked, then hit a case where I wanted to step into the screensaver code. When I tried to launch the app with a debugger attached, the app would immediately crash. It's main function would never get called, and I'd be stuck with a debugger command prompt and the following error message:


dyld: Library not loaded: @loader_path/../Frameworks/libBox2D.dylib
Referenced from: /Users/davidl/Documents/Code/Platformer/trunk/MacOS/build/Debug/Lugnut_Native.so
Reason: image not found
Program received signal: “SIGTRAP”.
Xcode: Introspection dylib not loaded because thread 1 has function: __dyld_dyld_fatal_error on stack


To note, Lugnut_Native.so is the current name of the shared library that contains most of my screensaver code, and libBox2D.dylib is another shared library that it depends on. "Platformer" is the original name of the project, which started out life as a 2d platformer, and eventually evolved into a screensaver having nothing to do with 2d platformers. Such is life.

The error message listed above says that my screensaver library, Lugnut_Native.so, can't load one of its dependencies, libBox2D.dylib. It's looking for it, and it can't find it.

A bit of background info: "@loader_path" is a term that has special meaning to the Mac OS X dynamic linker. When one module tries to load another module, it can use the token, "@loader_path" to indicate that the module to be loaded is located relative to the location of the module doing the loading. In this case, the module Lugnut_Native.so was trying to load another module, libBox2D.dylib, and it was trying to load it from a location relative to itself. Both modules were supposed to be located on my hard disk in locations predictably relative to each other. This is where "@loader_path" came in. It says that Lugnut_Native.so should expect that it's dependent library, libBox2D.dylib, in located spot relative to itself. The OS X dynamic linker replaces "@loader_path", with the path of the directory that Lugnut_Native.so exists in.

The problem ended up being that the wrong copy of Lugnut_Native.so was being loaded. There were two copies of the file, both getting created in the app's XCode-driven build process. The first was created by the linker. This was the copy that was getting inadvertently loaded. The second copy, the one I wanted to load, was a copy of the first placed inside the app's bundle, a location where OS X was supposed to be able to find it. In some cases, OS X would find it. If I ran the app outside of XCode, everything was ok. When I ran it from within XCode with a debugger attached, it'd crash immediately. Why would it do this?

The latter copy was the one I wanted to load. It existed inside the app's bundle. The copy that was getting loaded wasn't. When the OS X dynamic linker tried to load the incorrect copy, it was unable to find libBox2D.dylib in the specified location!

The solution I used, and there may have been several, was to tell XCode that when it launched the app, the dynamic loader should try to load dynamic libraries from a specific location, namely the directory where the desired copy of Lugnut_Native.so existed (inside the main application's bundle, to note.) It did this by making sure an environment variable called DYLD_LIBRARY_PATH was set, and that it got set before the app launched. DYLD_LIBRARY_PATH, when set, tells the OS X dynamic linker to load dynamic libraries from a given path. By setting this variable to the location where the desired copy of Lugnut_Native.so was, the dynamic linker should load it, or so I hoped at the time.

When the app crashed, it presented me with a command prompt, with which I was able to list the environment variables exposed to the app and to the dynamic linker. The command, "show environment" (without the quotes), said that DYLD_LIBRARY_PATH was already set and that it pointed to the path with the incorrect copy of Lugnut_Native.so. If there were a way to tell XCode to set DYLD_LIBRARY_PATH to something else, maybe I would be able to debug my app.

As it turns out, there was a way to set DYLD_LIBRARY_PATH before the app ran, thus making sure that the correct copy of Lugnut_Native.so would load, and thus allowing me to debug my screensaver in the manner I was hoping for. Here are the steps I took, minus most of the annoying missteps I ran into:


  1. Under the "Executables" section of the XCode project, I clicked on the app to debug, then pressed Command-I to bring up its Info dialog.
  2. Clicked on the "Arguments" tab of the dialog that came up.
  3. In the section, "Variables to be set in the environment:" section, I clicked on the plus sign to add an entry.
  4. In the new entry, I set the name to be DYLD_LIBRARY_PATH, and the value to "$SRCROOT/$CONFIGURATION_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH", without the quotes. The value here told the dynamic linker to try loading modules from the application's bundle first and foremost, which is where the correct copy of Lugnut_Native.so was to exist. Furthermore, it gives the dynamic loader a full path name, rather than a relative one. This turned out to be important. When I tried setting DYLD_LIBRARY_PATH to just, "$CONFIGURATION_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH", it didn't work, which is not what I was expecting. $CONFIGURATION_BUILD_DIR, when used elsewhere in XCode, usually resolves to a full path name. Prefixing "$SRCROOT" to this value fixed it.
  5. I closed the dialog and then launchd the app in the debugger (via XCode's "Run" menu.) It worked!


From then on in, I've been able to debug my screensaver under OS X using a main loop of my own creation, which is a bit more flexible than trying to debug the screensaver via OS X's screensaver engine. Listing the reasons why are beyond the scope of this blog posting, perhaps some other time I'll list them. Time for a break. :-)