Category Archives: Tutorials

Tutorials and how-to’s, and answers to common computer questions.

I had been looking off and on for a few years for a way to insert a timestamp into a file in Notepad++, preferably by a hotkey. The no-longer-in-development TextFX plugin frequently comes up in Google searches as one way of doing this, but the plugin doesn’t offer any ability to customize the format of the date or time stamp.

I found this article: http://sourceforge.net/p/notepad-plus/discussion/331753/thread/3458d1da that explains, briefly, how to do this using the Python Script plugin. I’ve been curious about Python for awhile, too, so I was willing to give it a shot. The SourceForge project page for Python Script is at http://sourceforge.net/projects/npppythonscript/.

So, here’s a quick tutorial on adding a customizable insert datestamp/timestamp macro to Notepad++.

Download the Python Script plugin from http://npppythonscript.sourceforge.net/download.shtml and install it. Do not download it from within Notepad++ by clicking Plugins | Plugin Manager | Show Plugin Manager, scrolling down the Available plugins list to Python Script, checking the box and clicking Install, because it just won’t work (and you may get an older version of the plugin).

Restart Notepad++ and you’ll find that Python Script has been added to the Plugins menu.

To create the script that will insert the timestamp, click Plugins | Python Script | New Script. Enter a filename for the script file you are about to create, like “Time.py”, and click Save.

A new, blank tab will appear in Notepad++. Paste in the following text:

import time 
editor.addText( time.strftime( '%Y-%m-%d %I:%M %p' ) )

Save the Time.py file to the default location in your user profile.

Add the Time.py script to Notepad++ by clicking on Plugins | Python Script | Configuration, highlighting Time.py, clicking the Add button above Menu items, and then clicking OK.

But, you probably want to be able to run this as a macro from a keyboard shortcut. Close the Time.py tab and then exit and relaunch Notepad++. Click on Settings | Shortcut Mapper… and choose the Plugin commands tab. The Time script should be listed here somewhere (in my case, it is usually somewhere around number 27). Highlight it, click Modify and assign it to a shortcut.

I choose to map my Time script to F5, because this mirrors the timestamp functionality built into Windows notepad.exe, but Notepad++ already uses that keystroke for the Run command. I never use the Run command, so I just remove the shortcut from that command by clicking on Settings | Shortcut Mapper… and choosing the Main menu tab, scrolling down to the Run item and either removing the mapping by changing the shortcut to None or changing it to something else, such as Ctrl+F5. For me, Run was located in the Shortcut mapper under Main menu around number 208. Close the Shortcut Mapper and you’re ready to use your new timestamp hotkey.

You can change the datetime formatting using variables! Just modify the contents of the Time.py file located at “%AppData%\Notepad++\plugins\Config\PythonScript\scripts”. See: https://docs.python.org/2/library/time.html#time.strftime

This post was originally written in October, 2012, and has been updated twice – first in January, 2013, while using “2012-12-16-wheezy-raspbian” and then again in February, 2014, while using “2014-01-07-wheezy-raspbian” – in all cases using the latest Raspbian release at the time and the latest versions of Emulation Station, RetroArch, and other software mentioned below. So, if you encounter instructions that don’t exactly jive with what you’re seeing, it’s probably because the software continues to change and my instructions have fallen out-of-date. If you get confused, please leave me a comment and I’ll try to help.

After playing around aimlessly a bit with my Raspberry Pi in 2012 (most recently, an install of the very nice RaspBMC), I thought of a useful purpose for it while showing my kids Super Mario Bros. and The Legend of Zelda running on the VirtualNES emulator on my Windows laptop. Before they get too spoiled on the Xbox 360’s graphics and sound, I want to get them some exposure to a few of the simple but influential 8-bit games from my childhood. At the same time, I don’t want my laptop to become the family’s gaming machine. We have a pretty massive TV and plenty of Xbox 360 controllers, so I figured I could throw the Raspberry Pi into the mix and come out with a neat retro gaming console.

Metroid running on my Raspberry Pi

Metroid running on my Raspberry Pi

As with all things Linux, the devil is in the details. Like, can you get the application to work with both video and sound, and are all of the peripherals fully functional? Add to that the uncertainty of the performance of Linux applications on the particular hardware limitations of the Raspberry Pi, and any simple-seeming project quickly develops into a series of hair-pulling and-now-this-doesn’t-work type obstacles. Case in point, a Google search as I began the project in October, 2012, turned up a number of people who had already thought of turning their Raspberry Pi’s into 80’s game console emulators, and it quickly became obvious that this wasn’t going to be a completely painless process.

This post on the Raspberry Pi forum from a few months earlier basically summed it up.

I have a NES emulator working without sound, using the Debian image, will only work running through console no LXDE

sudo apt-get install fceu
cd /usr/games
./fceu -input1 gamepad -inputcfg gamepad1 /home/pi/mario_bros.zip

Command above will map gamepad buttons to your keyboard, and load game image path you specify. Appears to work fine apart from no sound, I’ve had a few levels on Mario Bros.

Not tried with a joypad, I have a wireless xbox360 joypad that is discovered as a usb device, but have not had chance to try to get it working yet. It doesn’t work by default

http://www.raspberrypi.org/phpBB3/viewtopic.php?f=2&t=5874

Yikes! Emulation with no sound and keyboard-only input is considered a success! And then a reply to that already discouraging post makes the landscape seem even more bleak.

Oh yeah, that’s the one! I tried to use mednafen, but even disabling openGL so it would use SDL for graphics would only give me a blank screen. I’ve tried to find some console emulators that use openGLES but every time I find one, it turns out that it’s only available as a pre-assembled package for platform x.

http://www.raspberrypi.org/phpBB3/viewtopic.php?f=2&t=5874

Well, posts like those from people who certainly seem pretty well informed about console emulation would certainly dissuade most human beings from settling on this as a weekend project. But thankfully for us, plenty of people far smarter than I have been diligently working at converting their Raspberry Pi’s into something resembling a game console, and you and I can now directly benefit from their labor. I’m happy to report that I am getting decently playable NES emulation with sound (and slightly-less-satisfactory SNES emulation) from my Raspberry Pi after a few hours of struggle. And what with how quickly I’m willing to reformat the SD card with a different image (what? an update to RaspBMC?), I thought I should document my steps for posterity.

One of the most frustrating things about doing anything in Linux after living in Windows is that it rarely works as smoothly as you would expect and it takes some patience to get past the hurdles. On top of that, when you turn to Google for help, forum threads typically assume the readers will have more than a passing familiarity with the Linux file structure, command line input, Make files, and the like. Once I eventually track down something that looks like a possible fix, I often find myself searching for help on just exactly how to implement the fix, which advice frequently turns out to be out-of-date and no longer applicable.

So, for those of us who are not going to know how to chmod +x a shell script without some hand-holding, here are the steps I’ve followed so far, that are hopefully detailed enough that you end up with a working RPi game console instead of a smashed bit of PCB and some seething frustration. At times, I assume that you’re still using the ‘pi’ user account, but if you’re not, you’ll probably be able to recognize where you need to substitute your new account. If you can see where I’m definitely doing stuff horribly wrong, please leave a comment and I’ll try to make it better.

Learning a few new tricks here

Learning a few new tricks here

Steps to set up the SD card and configure Raspbian with the necessary software

1. On your main computer (I’ll go out on a limb and assume you’re running Windows here), get the latest release of Rasbian from the Raspberry Pi Downloads page, extract the image file, format your (4 GB or larger) SD card using SD Formatter 4.0 and write the Raspbian disk image to your SD card using win32diskimager. I’ve used win32diskimager successfully more than once, but it will complain at me every time.

Connect the Raspberry Pi to a TV or monitor (I greatly prefer the HDMI out, but the composite output is fine if that’s all you have), connect a USB keyboard (my superstitious nature makes me connect it to the bottom USB port), and connect an Ethernet cable to your router because 1) the Raspberry Pi will need Internet access during setup and 2) your life will be easier if the Raspberry Pi can also talk with a computer on your home network. You can also connect your wired Xbox controller or Xbox 360 Wireless Gaming Receiver dongle thingie now, if you like. Power on the Raspberry Pi and use the spacebar, tab, arrow and enter keys to navigate through the raspi-config utility (it should run automatically at the first boot) to

  1. expand the root partition to fill the SD card
  2. change the internationalization options – language, timezone, and keyboard – as appropriate (this actually is important)
  3. enable the SSH server (in Advanced Options)

Choose finish and reboot the Raspberry Pi by typing the command:

sudo shutdown -r now

And then hitting Enter. Each time I specify a line of input, like the one above, hit the Enter key at the end to execute it.

After the Raspberry Pi restarts, write down its IP address, which is reported in the lines just before the login prompt.

I typically overclock my Raspberry Pi to the Modest setting (800MHz), but I don’t know if this makes any difference, so you can play with this to meet your needs. I run the original Model B board with 256 MB memory, and while it’s sometimes recommended to bump up the memory split to allocate 192 MB to the GPU, it hasn’t been necessary in my experience. If you need to run the raspi-config utility again to change any of these settings, open a terminal (Alt+F1 through Alt+F6) and enter

sudo raspi-config

I recommend against changing the setting that causes the Raspberry Pi to boot straight into the desktop, as the Emulation Station and RetroArch stuff that comes later is best launched from the terminal immediately after logging in (and not from a window within X) and offers something of a GUI anyway.

2. Back on the Windows computer, download PuTTY, which is an application that will allow you to access the command prompt on the RPi (RPi is easier to type, so I’ll be using this shorthand frequently) from your Windows computer across your home network. Launch PuTTY, connect to the RPi using its IP address, and log in (username: pi and password: raspberry). A great thing about accessing the RPi via PuTTY is that you can send command lines to the RPi by copying them from your favorite web browser in Windows and pasting them into the PuTTY window, saving you from typing in lots of unfamiliar and sometimes lengthy Linux commands.

3. In the PuTTY window, get Raspbian up-to-date by updating the package lists from the repositories and retrieving new versions of existing packages with

sudo apt-get update && sudo apt-get upgrade -y

4. Still in the PuTTY window, install GIT, vim, xboxdrv, and other useful software with

sudo apt-get install -y git vim dialog xboxdrv

Then reboot the RPi with

sudo shutdown -r now

5. Because the next part – installing RetroArch, the console emulators, and Emulation Station – takes a long time, I recommend either a) using the USB-connected keyboard on the RPi or b) using the screen command (here’s a good introduction to screen) if you are connecting to the RPi with PuTTY. I mention this because if your PuTTY session drops, the shell in which the commands are running will terminate and interrupt any running process. If this happens, you will have to run the setup script again (but you won’t necessarily know how far along it got before it terminated).

Whichever way you choose to connect, follow the instructions at RetroPie-Setup: An initialization script for RetroArch on the Raspberry Pi to install RetroArch for the Raspberry Pi. I would recommend using the source-code based installation, as it’s unclear how often the binaries are compiled. You can leave the options for installing components at their defaults, but I generally deselect the cores (the console emulators) that I don’t want or that I expect won’t work very well on the RPi. The installation may take hours, but the fewer emulator cores you choose to install, the faster it will go. Reboot at the end of the RetroArch installation.

6. The next step is to copy your ROMs into the appropriate, console-named subdirectory under /home/pi/RetroPie/roms/ on the RPi. There are a few different ways to do this. You can put them on a FAT-32 formatted USB flash drive and then transfer them to the RPi via command line, or you can launch the desktop with startx and drag-and-drop them, but I find that it’s much easier to use WinSCP to copy files from a Windows machine to the RPi across the network. (You can also use WinSCP to copy config files between the Raspberry Pi and your Windows machine, where you can edit them in a more familiar text editor. More on this later.)

Contrary to the advice below, at least for NES ROMs, both the .nes and .NES file extensions are acceptable. But if you’re having problems with ROMs for other systems, you may consider looking at the extensions.

Make sure that the extensions of your roms are lowercase and correspond to those given in /home/pi/.emulationstation/es_systems.cfg. You can show the content of that file with “cat /home/pi/.emulationstation/es_systems.cfg”.
http://www.raspberrypi.org/phpBB3/viewtopic.php?t=13600&p=155809

Note: In my experience, if you have chosen not to install most of the emulator cores, you will need to put at least one ROM in at least one console emulator’s ROMs directory in order for Emulation Station to start up successfully. I ran into a problem when I chose not to install any cores except for NES, and then tried to start Emulation Station for the first time before I copied any NES ROMs to the RPi. Instead of the Emulation Station starting up the gamepad configuration wizard, I got only a black screen with a small white dot in the center and spent hours thinking that something was wrong with Raspian/Emulation Station/Retroarch/the RPi itself, etc.

This dot is the “fake” SDL window ES uses to get input. Actual rendering is done through OpenGL ES. If all you see is this dot, then odds are something went wrong initializing the OpenGL ES surface. Are you sure you’re running at least the 192/64mb memory split?
https://github.com/petrockblog/RetroPie-Setup/wiki/EmulationStation

That takes care of the basics. Now you can launch the Emulation Station, which is the front-end we’ll be interacting with, to choose between different game systems and within them, different individual games, by logging into the RPi using the USB keyboard and entering

emulationstation

Emulation Station does not like to be started from an SSH connection. Manually starting Emulation Station each time is optional, as it is possible to launch the Emulation Station automatically at start up, though I use the RPi for a few different things so I don’t actually want this behavior at each boot and just launch it myself if I’m there to play a game.

The first time that you launch Emulation Station, it will guide you through setting up either a keyboard or controller for navigating between the various consoles and launching games. These settings are saved to a config file named es_input.cfg and located in the hidden directory at ~/.emulationstation/es_input.cfg. (Files and directories with names that begin with a dot are hidden, so they won’t show up with a regular ls command, but they will show up if you use ls -a and they are displayed by default in WinSCP.) If you ever want to go through the wizard again to set up a keyboard or controller, delete that file and launch Emulation Station.

If you want to modify es_input.cfg by hand, it’s easy enough to transfer it to your Windows computer using WinSCP and open it in a text editor. One advantage of editing the file is that you can run through the wizard twice – configuring a keyboard the first time and a controller the second – and create two es_input.cfg files that you then splice together in a text editor to create a single file so that you can navigate through Emulation Station by either the keyboard or the controller. This is what my es_input.cfg file looks like, with mostly intuitive controls for the keyboard and an Xbox 360 controller:

<?xml version="1.0"?>
<inputList>
	<inputConfig type="keyboard">
		<input name="a" type="key" id="13" value="1" />
		<input name="b" type="key" id="8" value="1" />
		<input name="down" type="key" id="274" value="1" />
		<input name="left" type="key" id="276" value="1" />
		<input name="menu" type="key" id="303" value="1" />
		<input name="pagedown" type="key" id="281" value="1" />
		<input name="pageup" type="key" id="280" value="1" />
		<input name="right" type="key" id="275" value="1" />
		<input name="select" type="key" id="32" value="1" />
		<input name="up" type="key" id="273" value="1" />
	</inputConfig>
	<inputConfig type="joystick" deviceName="Microsoft X-Box 360 pad">
		<input name="a" type="button" id="0" value="1" />
		<input name="b" type="button" id="1" value="1" />
		<input name="down" type="axis" id="1" value="1" />
		<input name="left" type="axis" id="0" value="-1" />
		<input name="menu" type="button" id="6" value="1" />
		<input name="pagedown" type="button" id="5" value="1" />
		<input name="pageup" type="button" id="4" value="1" />
		<input name="right" type="axis" id="0" value="1" />
		<input name="up" type="axis" id="1" value="-1" />
	</inputConfig>
</inputList>

You can compare the contents of my file to your own in order to get an idea of what buttons are mapped to stuff I’ve never actually used in Emulation Station, like the Page Up and Page Down commands.

Ridley is easy, like this tutorial

Ridley is easy, like this tutorial

Your Raspberry Pi now has all the necessary software to emulate games and accept input from your Xbox 360 controller. It’s now time to…

Configure the controller for games

Once you have those components installed, it’s time for the next step in any Linux project: discover what’s not working. (I have a long, involved tale about the many futile hours I spent trying to map all of the buttons on my old Logitech MX510 mouse, but I digress…)

Back in 2012, a wired (and potentially wireless) Xbox 360 controller wouldn’t automatically work, and unless you were content using the keyboard in games, you wanted to get it working ASAP. You could connect the controller, and you might get the ring of lights to pulse, but you would need to crank up xboxdrv, a userspace driver for Xbox controllers, before you could do anything with it.

As of 2014, Xbox controller support is integrated into Emulation Station and RetroAarch, but if you are curious about how we did it in the good old days, I strongly recommend reading through the list of xboxdrv switches, particularly if something doesn’t work as expected or if you need to figure out why the triggers and analog sticks aren’t mapping.

Even though the controller and the RPi are talking, you need to configure RetroArch to work with it. It is certainly possible to do all the text file editing and copying by using the included Leafpad editor in LXDE, which is the graphical interface on the Raspbian distribution, or in your editor of choice on your Windows computer while transferring the files back and forth with WinSCP, as I normally do, but this is a rather geeky project so I feel that I should at least mention the text-only vim editor that you can run within a terminal, and so I’m going to use it briefly in this case. In the PuTTY window, enter the following code to create a back up copy of the default RetroArch configuration file that is used by all of the console emulators:

cp ~/RetroPie/configs/all/retroarch.cfg ~/RetroPie/configs/all/retroarch.cfg.bak

Then open the live file for editing in vim with:

vim ~/RetroPie/configs/all/retroarch.cfg

I think it’s good to get some idea of the many options within RetroArch, so I really recommend looking through this file, as you may need to come back later and tweak it to resolve problems with sound in games. When you’re done looking around, exit vim without saving the file by typing

:q

Then hit Enter. See, nothing to it.

Back on the USB keyboard attached to the RPi, log in and enter

cd ~/RetroPie/emulators/RetroArch/tools

This puts you in the directory containing the retroarch-joyconfig utility that you’ll use to set up the controller. (If you’re getting an error message about files or directories not being found, you may be using a US keyboard but the RPi is still set to a UK keyboard layout. This would cause the tilde key “~” on the keyboard to enter a logical negation symbol “¬” instead. The tilde in a path in Linux is expanded to be the current user’s home directory, and the logical negation symbol is not. Re-read step 1 for instructions on how to launch the raspi-config utility to change the keyboard layout.)

Launch the retroarch-joyconfig utility with the line:

./retroarch-joyconfig -o p1.cfg -p 1 -j 0

Follow the instructions to push the buttons and move the sticks/triggers/dpad. (The -o switch causes the output to be sent to a file, p1.cfg, otherwise, the output is just echo’d to the screen, which is interesting but doesn’t help us set up RetroArch.) If you mess up, just keep pressing buttons until the utility exits and then start all over again by relaunching the utility with the same command line.

Xbox 360 controller

Xbox 360 controller (click to enlarge)

When you’re satisfied that you have pushed all the right buttons, you should have a p1.cfg file located at ~/RetroPie/emulators/RetroArch/tools. The contents of this file is what will eventually tell RetroArch and each of the various system emulators how to interpret the commands coming from the primary, first controller, but it needs to be appended to the end of that retroarch.cfg file first. To do this, enter:

sudo cat p*.cfg >> ~/RetroPie/configs/all/retroarch.cfg

The end of my retroarch.cfg file looks like this, after I appended the p1.cfg file to it and then further edited it by hand to add some extra commands for exiting the emulator and saving and loading gamestates (one of the best things about playing games on an emulator is that you can save the current state of the game at anytime, and later resume from that point in time, so you don’t need to rely on in-game saves).

input_player1_joypad_index = "0"
input_player1_b_btn = "1"
input_player1_y_btn = "3"
input_player1_select_btn = "6"
input_player1_start_btn = "7"
input_player1_up_axis = "-7"
input_player1_down_axis = "+7"
input_player1_left_axis = "-6"
input_player1_right_axis = "+6"
input_player1_a_btn = "0"
input_player1_x_btn = "2"
input_player1_l_btn = "4"
input_player1_r_btn = "5"
input_player1_l2_axis = "+2"
input_player1_r2_axis = "+5"
input_player1_l3_btn = "9"
input_player1_r3_btn = "10"
input_player1_l_x_plus_axis = "+0"
input_player1_l_x_minus_axis = "-0"
input_player1_l_y_plus_axis = "+1"
input_player1_l_y_minus_axis = "-1"
input_player1_r_x_plus_axis = "+3"
input_player1_r_x_minus_axis = "-3"
input_player1_r_y_plus_axis = "+4"
input_player1_r_y_minus_axis = "-4"

# Hold the back or select button (6) while pressing another button for 
# special actions, like...
input_enable_hotkey_btn = 6

# ...the Xbox Guide button (8) to exit the emulator
input_exit_emulator_btn = 8

# ...the left bumper (4) to save the game state to the current slot
input_save_state_btn = "4"

# ...the right bumper (5) to load the game state from the current slot
input_load_state_btn = "5"

Note to self: I need to update this tutorial with instructions on how to configure multiple controllers.

Each console emulator can have its own retroarch.cfg file that overrides the settings in the default file at ~/RetroPie/configs/all/retroarch.cfg. For the NES emulator, the retroarch.cfg file lives at ~/RetroPie/configs/nes/retroarch.cfg (in a /nes/ directory under /configs/, at the same level as /all/). If you are using an Xbox 360 controller and don’t configure the NES retroarch.cfg file specifically, the B and A buttons will be reversed from the original controller layout, and you’ll have to use the D-pad (which is not great) instead of the left analog stick.

In case you don’t remember the button layout of the NES controller…

NES controller

NES controller (click to enlarge)

So, I would strongly recommend dropping the following file into ~/RetroPie/configs/nes/retroarch.cfg for a better experience.

# All settings made here will override the global settings for the current emulator core

# The original Nintendo controller has the B button on the left and the A button on the right
# which is reverse of the Xbox 360 button layout.  Your ten-year-old self wants you to fix this
input_player1_b_btn = "0"
input_player1_a_btn = "1"

# It would be nice to be able to use the left joystick as well as the D-pad in Nintendo games
# but it seems to be an either-or situation, because only the _axis buttons are honored
input_player1_up_axis = "-1"
input_player1_down_axis = "+1"
input_player1_left_axis = "-0"
input_player1_right_axis = "+0"

Now you should be all set to play NES games using the Xbox 360 controller with pretty intuitive controls. The Xbox 360 controller-to-Nintendo controller mappings are as follows: the left analog stick replaces the D-pad, the A and B buttons are the B and A buttons, the Back button is the Select button, and the Start button is the Start button.

In a hurry to see Mother Brain again

In a hurry to see Mother Brain again

The Super Nintendo controller has four buttons, like the Xbox 360 controller, but the X/Y and A/B buttons are reversed. If you’re going to be emulating SNES, you’ll most likely want to make an SNES-specific retroarch.cfg file for that game system, too.

This is my best-guess for a Super Nintendo retroarch.cfg, without actually having tested it yet.

# All settings made here will override the global settings for the current emulator core

rewind_enable = false

# The Super Nintendo controller's button layouts are the reverse of the Xbox 360 controller
input_player1_b_btn = "0"
input_player1_y_btn = "2"
input_player1_a_btn = "1"
input_player1_x_btn = "3"

# It would be nice to be able to use the left joystick as well as the d-pad in Super Nintendo games
# but it seems to be an either-or situation, because only the _axis buttons are honored
input_player1_up_axis = "-1"
input_player1_down_axis = "+1"
input_player1_left_axis = "-0"
input_player1_right_axis = "+0"

OK. The controllers should now work as expected in games. So…

Get impatient and try playing a game

Assuming you haven’t had any insurmountable problems with the directions above, you should be able to get into a game in a few simple steps:

1. plug everything into the RPi (USB keyboard, HDMI output to TV/monitor, and a wired Xbox 360 controller or Xbox 360 wireless gaming receiver dongle)
2. turn on the Xbox controller (if you need to link the controller with the dongle, you may have to reboot once this has been done before the RPi will see it)
3. power on the RPi (or reboot with sudo shutdown -r now from a terminal) and log in as the ‘pi’ user
4. at the prompt, type emulationstation to launch the Emulation Station front-end
5. use the arrow keys on the keyboard or the left analog stick on the Xbox 360 controller to browse the game systems and ROMs and the Enter key or A button to launch a game system or game.

And you should definitely pat yourself on the back for getting this far.

But your game probably won’t have sound.

Wrestle with the sound

I’m using a pair of headphones plugged into the analog jack, and while many people report that the game’s audio when output through HDMI is generally fine, the audio out through the analog jack was decidedly not fine with the default settings back in October, 2012. The sound would start off fine, but within 20-30 seconds it started becoming increasingly choppy and a few moments later I was ripping off the headphones. I Googled this a ton, and eventually used the options recommended at https://github.com/petrockblog/RetroPie-Setup/wiki/Sound-Issues by uncommenting and/or editing these lines in the retroarch.cfg file. Depending on your experience, you can do so using vim or your text editor via WinSCP:

audio_enable = true
audio_out_rate = 44100
audio_driver = sdl

I had read a bit about ALSA and very little about SDL, but from what I could tell, it boiled down to ALSA (which was in alpha on the Raspberry Pi in late 2012) should be faster than SDL once ALSA is working completely. If ALSA is not working completely or if the RPi is under considerable load, we are better off using something else, and that something else seems to be SDL.

When I rebuilt the RPi in 2014, I still had to modify the audio settings in retroarch.cfg, but I found that ALSA worked fine. The settings I’m currently using are:

# Enable audio.
audio_enable = true

# Audio output samplerate.
audio_out_rate = 44100

# Audio driver backend. Depending on configuration possible candidates are: alsa, pulse, oss, jack, rsound, roar, openal, sdl, xaudio.
audio_driver = alsa

Using these settings also avoids the warning message visible in the console when RetroArch exits while the sound is misconfigured:
RetroArch [WARN] :: Audio rate control was desired, but driver does not support needed features.

If the volume in games is too low, and you are using ALSA, you can increase it at the terminal prompt with the command:

amixer sset PCM,0 90%

I have both an Xbox 360 and my Raspberry Pi hooked up to the same TV via HDMI, and 90% volume on the Raspberry Pi seems to match the volume of the Xbox pretty closely, so that I don’t need to turn the TV up or down when I switch consoles.

So that’s it, you should be able to play those old NES games now, with the glorious, mesmerizing 8-bit sound, but with the far more comfortable Xbox 360 controller.

The Esc key on the keyboard will exit the game and return to the Emulation Station GUI, by default, and if you’ve used my retroarch.cfg file above, you can do this with the controller by holding the Back button and pressing the silver Xbox Guide button.

Great !!

Great !!

What else?

The keyboard is still convenient for saving and loading game states, and I don’t know if all of the functions can be mapped to buttons on the controller (it sounds like it’s not possible), so it stays within reach for now. To enable keyboard shortcuts to save and load save states, uncomment the following lines in retroarch.cfg.

# Saves state.
input_save_state = f2
# Loads state.
input_load_state = f4

# State slots. With slot set to 0, save state name is *.state (or whatever defined on commandline).
# When slot is != 0, path will be $path%d, where %d is slot number.
input_state_slot_increase = f7
input_state_slot_decrease = f6

While playing a game:
F2 – save state to current slot (defaults to slot 0)
F4 – load state from current slot (defaults to slot 0)
F6 – decrease the save slot (defaults to slot 0)
F7 – increase the save slot (defaults to slot 1)

Other useful features can be enabled in retroarch.cfg by uncommenting the lines:

# Mute/unmute audio
input_audio_mute = f9

# Take screenshot
input_screenshot = f8

While playing a game:
F8 – take a screenshot (saved to the ROM’s directory by default, but this is configurable)
F9 – mute audio

The rewind feature in RetroArch is also awesome, and allows to you literally rewind the game – going back in time a few seconds so that you can replay it differently. This comes at a CPU and storage cost, so you may or may not see a performance hit when rewind is enabled. To enable rewind, uncomment the line:

# Enable rewinding. This will take a performance hit when playing, so it is disabled by default.
rewind_enable = true

While in the Emulation Station GUI (such as it is):
Arrow keys – navigate through ROMs and systems (consoles)
Enter – launch the selected ROM
F1 – adjust the settings (including the master volume), restart or shutdown the Raspberry Pi
F4 – terminate Emulation Station and return to the command prompt in the terminal

Recently, themes for each console have been developed for the Emulation Station, which I think everyone who saw it in 2012 would agree really needed a designer’s touch. I would recommend experimenting with the ES Scraper utility, which should download themes for the consoles and boxart for your games automatically.

So that’s that. I’m playing Final Fantasy and Super Mario Bros. 3 for the first time in years, and it’s pretty neat.

Outstanding problems

Some games, or maybe all games that scroll from top to bottom, but certainly Final Fantasy and Dragon Warrior, tend to artifact at the top and bottom of the screen when walking north and south on the world map. I haven’t begun to try to tinker with the video settings in order to alleviate this problem, but I imagine the fix is in there somewhere.

I seemed to be having a problem restoring from save states when I built my first RPi/RetroArch box back in early October, 2012. If I changed to a different emulator (and possibly to another game within the same emulator), I lost the ability to later load from a save state. The load would fail. I could, however, successfully save and load game states as long as I stayed within a single game. It doesn’t seem to be a very common problem, however, as I’ve only found one thread that describes exactly my initial problem, and that was for RetroArch on the PS3: http://forum.themaister.net/viewtopic.php?id=231. In that thread, the OP pinpoints the problem to changing emulators, after which the save state files cannot be loaded. To my mind, this indicates the problem lies outside the save state files themselves. Resolving this problem was one of the reasons I rebuilt the whole thing from scratch in late January, 2013.

But sadly, my problem was not resolved with the rebuild and in some ways was actually worse after the rebuild. Not only could I neither save nor load states in games with save state files created before the rebuild, but now, instead of the save/load message that is typically output to the screen as yellow letters, I just got a black box (possibly with black letters, rendering the text impossible to read) whenever I triggered a save or load. After I renamed or deleted the old savestate files in the ROM’s directory, I was able to create a new save state without issue and load it.

This was rather disappointing for games that I had been playing for awhile and was relying on the save state, but I guess I can live with starting over.

A possible work around to this problem, for games that support saving in-game, is to use the rewind feature instead of save states to undo mistakes as soon as they happen, and then rely on the in-game saves. For games that don’t support in-game saves, I guess I’m S.O.L. until I get it figured out.

I was having a few problems with xboxdrv and wireless controllers, in the early days. When using the USB Xbox 360 Wireless Gaming Receiver for Windows through a USB hub, approximately 60 seconds after launching xboxdrv, xboxdrv will crash and I’ll get an error stating [ERROR] USBController::on_read_data(): failed to resubmit USB transfer: LIBUSB_ERROR_NO_DEVICE followed by Shutdown complete. This doesn’t happen when using a wired controller or when the USB Xbox 360 Wireless Gaming Receiver for Windows is connected directly to the USB port on the RPi, so maybe a powered USB hub would produce a better experience. I’ve also heard that the Xbox 360 Wireless Gaming Receiver for Windows draws a lot of power, so it may be a good idea to get it working through a powered hub anyway.

I remember her hair differently...

I remember her hair differently…

You can stop reading now. Everything below this point are my notes on how things used to be done.

The manual way of starting up xboxdrv for a single controller is to just run

sudo xboxdrv --trigger-as-button --silent

at the command prompt each time you turn on the RPi, but you could start this up automatically, too. If you don’t run it with sudo, you’ll get an error: USBController::USBController(): libusb_open() failed: LIBUSB_ERROR_ACCESS. The creator’s proposed workaround is to add the current user to the ‘root’ group, which I’m not terribly keen on, so I’d be content with just continuing to run it with sudo. If you want to see your joystick axis and button press information output to the console, just run sudo xboxdrv without the –silent switch, but this eats up some CPU, so use the –silent switch when you’re going to be playing games.

The automatic way of starting up xboxdrv for a single wireless controller is to add the command to /etc/rc.local, which is a file that runs (like a script) at the end of multi-user boot levels (think: before a user logs on). It makes sense to start up xboxdrv automatically, particularly because we want to pass some arguments that would be annoying to type each time. While connected via PuTTY, start by backing up /etc/rc.local with

sudo cp /etc/rc.local /etc/rc.local.bak

Open /etc/rc.local using the vim text editor with

sudo vim /etc/rc.local

Arrow down to the line immediately before exit 0, hit the Esc key, and type or copy and paste

xboxdrv --dpad-as-button --trigger-as-button --wid 0 --led 2 --deadzone 4000 --silent &

then hit Enter, and type

sleep 1

Hit Esc again, type

:wq

Then hit Enter to save the changes and exit the editor. Reboot the RPi again, and now you should see that the Xbox 360 driver is up and running even before the login prompt appears. How’s that for awesome?

(The official instructions in the Using a single controller section of the xboxdrv manual at http://pingus.seul.org/~grumbel/xboxdrv/xboxdrv.html don’t seem to apply to the RPi at this point, as the xpad driver isn’t loaded and the upinput and joydev modules are loaded during boot.)

If you want to be even more slick and automatically start up support for up to 4 controllers, check out https://github.com/petrockblog/RetroPie-Setup/wiki/Setting-up-the-XBox360-controller.

(I initially had some problems with analog joysticks and triggers not registering in the retroarch-joyconfig utility until I started passing the –trigger-as-button switch when launching xboxdrv. However, even when the analog sticks are mapped by retroarch-joyconfig, I don’t have the use of them in NES games like Metroid, and that’s mostly OK by me, except that the dpad on the Xbox 360 controller has always seemed horribly sloppy to me, even in Xbox games. For some reason, the analog joystick movements would be picked up by xboxdrv if I omitted the –trigger-as-button switch, but not by the retroarch-joyconfig utility. The problem with the triggers is that without the –trigger-as-button switch, each trigger pull and release counts as two analog axis movements. This is desired for games where the trigger acts as a brake or gas pedal, but NES and SNES games have little or no use for this. Analog joysticks behave the same way, throwing tons of input at the slightest movement when the NES really just needs to know when it’s been pushed and released. It’s possible to turn the analog sticks off entirely by passing xboxdrv the –dpad-only switch, but what I really want is to accurately control NES games with the far more reliable left analog stick – something I’m still working on.) Update: the workaround for this is to use a NES-specific retroarch.cfg file that maps the left analog stick to the same buttons as the dpad – leaving you without a dpad in NES but with the left-analog stick.

(If you get an error “Couldn’t open joystick #0.”, it probably means that xboxdrv needs to be restarted first.)

I’m in the middle of troubleshooting a printing problem that has arisen with our in-development Windows 7 image. We’re running 64-bit Windows 7 Enterprise with Office 2010 and using the HP Universal Print Driver for Windows PCL6 version 5.4.0 dated 1 Dec 2011 (the current version). The printer driver is installed on a Windows server using default settings and the printer connections on the workstations are created either as per-machine connections by running printui.exe /ga or as per-user connections by running the Find Printers wizard in an Office application. The printers themselves are HP 4250n and HP P4015 models with relatively up-to-date firmware.

The problem is that certain print jobs produce many pages of apparent gibberish instead of the intended file or email message. The gibberish pages begin like this:

"
 @PJL SET JOBATTR="JobAcct8=USERNAME"
                                     @PJL SET JOBATTR="JobAcct9="
                                                                 @PJL SET RET=OFF

I’ve done some research into the lines beginning @PJL, and my understanding is that PJL (Printer Job Language) commands are part of the standard job header output from the Universal Printer Driver, and that when everything is working normally, they are processed by the printer as instructions instead of printed as text.

For more reading about PJL commands, I can recommend the page at: http://www.sxlist.com/techref/language/pcl/lj1686.htm

Almost immediately, I was able to rule out the per-machine connections as being the cause, as the problem also occurred on per-user connections. The same files that printed problematically to the networked HP printers printed normally to locally-installed printers using non-UPD PCL 6 drivers. It seemed logical to pursue this as a driver-related problem.

What is PCL 6

It’s probably worth pausing here for a bit of explanation of PCL 6.

The Enhanced PCL XL or PCL6 driver that is included with the HP LaserJet printers provides enhanced WYSIWYG and enhanced performance with application support over the Standard (PCL5e) driver. PCL XL is a new page description language by HP that is part of PCL6 and is closer to GDI, which many applications use. Less translation takes place by the driver, which means increased WYSIWYG capabilities and better performance with applications that support escapes implemented by the Enhanced driver. The output from the Enhanced (PCL XL) driver may not be the same as the output from the Standard driver. If the output is not as expected, choose the Standard (PCL5e) driver instead.
What is the Enhanced PCL XL or PCL6 Driver?

The part that catches my eye is “better performance with applications that support escapes implemented by the Enhanced driver”. Are we encountering applications that do not support escapes?

Eliminating possible causes

Possible causes of the PJL commands being output as text include the driver not prefixing the PJL statements (at the beginning of each job) with a Universal Exit Language (UEL) escape sequence. (http://www.tek-tips.com/viewthread.cfm?qid=1618494)

To rule this out, one can use the “print to file” option in the print dialog box to produce a file that contains the instructions that would be sent to the printer.

Choose File | Print in your application, then check the “Print to file” box in the print dialog box. (In Office 2010, the Print Options button under the available printers menu displays the print dialog box.) Choose a name for the .prn file and save it somewhere, then open the resultant *.prn file in something that displays escape characters, such as Notepad++ (or even Notepad). The first character should be an escape character, and the first line of text will begin something like this:

{ESC}%-12345X

If the PJL initialization command looks correct, it’s possible that the printer is not properly configured to accept PJL commands. Older printers may not be PJL-aware, but I knew our printers to work fine with older 32-bit HP UPDs installed on our Windows XP machines. The ‘Personality’ attribute on HP printers can be checked by going to the printer’s web admin panel and browsing to Settings | Configure Device | System Setup. Setting the Personality to PS is probably going to cause problems, but either Auto or PCL should work. I confirmed that our printers were set to Auto, further ruling out the printers themselves as the cause of the problem.

I next looked at disabling the advanced features of the driver (a little skeptically, I’ll admit). This can be done by going into the printer’s properties and unchecking the “Enable advanced printing features” box on the Advanced tab. (http://h30499.www3.hp.com/t5/Print-Servers-Network-Storage/12345X-PJL-Printing-on-Dot-Matrix-Printers/td-p/1132391) I was curious about how this affected the job sent to the printer – would the entire series of JPL commands be removed?

To test, I unchecked the “Enable advanced printing features” and printed an email message to a *.prn file, then checked the box and printed the same email to a second *.prn file, then compared the two files. The only difference in the PJL commands was that “@PJL SET SEPARATORPAGE=OFF” was present with advanced printing features enabled, and absent with advanced printing features disabled.

I found the separator page line to be an interesting difference, as banner pages/separator pages had been suggested as a possible cause, but our drivers were not configured to print separator pages. (http://www.oasq.com/PJL-SET-JOBATTR-thread-252568-1-1.html)

So, that’s where the issue currently stands. I’m waiting to see if turning off advanced printing features has any effect. To be thorough, I need to test whether the UPD PS driver prints without error and whether the problem continues with a printer connected via TCP/IP and with a manually installed driver. I can also bring the printers up to the latest version of the firmware, although this would be a less satisfactory resolution, as we have a variety of printer models and not all of them have firmware updates available.

Update 17 Feb. 2012

The Application event log on the print server contains a number of errors, though we’re unsure of whether there is a direct correlation between the errors and attempts by Windows 7 users to print, or jobs in the spooler being processed, or any other activity.

Description:
Faulting application name: PrintIsolationHost.exe, version: 6.1.7600.16385, time stamp: 0x4a5bd3b1
Faulting module name: hpzuiwn7.dll, version: 0.3.7071.0, time stamp: 0x4a5bdfcb
Exception code: 0xc0000005
Fault offset: 0x00000000000d6971
Faulting process id: 0x900
Faulting application start time: 0x01ccea9860e17377
Faulting application path: C:\Windows\system32\PrintIsolationHost.exe
Faulting module path: C:\Windows\system32\spool\DRIVERS\x64\3\hpzuiwn7.dll
Report Id: 3eaa21e6-568c-11e1-b7a4-005056a50027

It certainly does look like the 64-bit HP driver is at fault here. More searching has turned up a number of reports of this error with HP’s UPD PCL6 driver, going back to 2010.

Because we have a small number of Windows 7 users, we’re removing the network printers from the Windows 7 machines temporarily, to see if the server stabilizes.

Update 21 Feb. 2012

We were able to take a closer look at the print server today. We searched the registry for hpzuiwn7.dll and noted the printers that had this DLL listed among the supporting files. Many, but not all, of the printers included this DLL. We also reviewed the printers in Print Management and made an odd discovery. There seemed to be two varieties of the model-specific PCL 6 driver in use: one is named “HP LaserJet 4250 PCL 6” and the other is “HP LaserJet 4250 PCL6“. The difference in the naming is that the later driver has a space between PCL 6. While most of the printers used the UPD, a handful were using one of the model-specific drivers. When we looked at the Additional Drivers, we found that one of them had only the 64-bit version available. I expect that only 32-bit workstations are printing to those printers, so I’m not sure how they even functioned, but it would seem that the next step would be to either add the matching 32-bit drivers for that model printer or change the assigned driver to UPD PCL 6. I suspect that we were not diligent enough about exactly matching the printer driver names (let alone the version numbers) when we were installing drivers on the server.

Update 1 Mar. 2012

After installing the missing 32-bit driver that complemented the stray 64-bit driver, all of the printing problems, including the error messages in the Application log on the server, have subsided.

In Windows, the Num Lock key state (on or off) can be set in the registry. It can be set in either of two locations, depending on when you wish to set the state, or both, if you want to force the state at boot and change it after the user logs in.

The Num Lock key state after logon can be set as a registry value for the current user in the key HKEY_CURRENT_USER\Control Panel\Keyboard. To set the state of the Num Lock key before logon (the key state will be set before the Ctrl+Alt+Del screen), change the registry value in the key HKEY_USERS\.Default\Control Panel\Keyboard. For both keys, the data for the InitialKeyboardIndicators value determines the state of the NumLock key. There are three possible settings.

0 = Num Lock is turned OFF after/at logon.
1 = Disable Num Lock.
2 = Num Lock is turned ON after/at logon.

A registry merge file that sets Num Lock on for the current user after logon is below.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Control Panel\Keyboard]
"InitialKeyboardIndicators"="2"

It’s also (typically) possible to configure the Num Lock key state in the BIOS, although I personally don’t see the advantage of setting in the BIOS something that is configurable in Windows.

Note that users of full-sized keyboards with distinct Num keypads generally prefer to have the Num Lock key enabled and laptop users typically have Num Lock disabled. Much like the Function key is used to change the behavior of certain laptop keys, laptop keyboards without dedicated Num keypads map numbers to regular character keys. This could potentially cause some confusion, when users begin hitting the letter keys and get numbers instead.

Update 2015-01-02: About a month ago, in early December, 2014, Google announced that it was working on a new anti-spam API that is intended to replace the traditional CAPTCHA challenge as a method for humans to prove that they are not robots. This is very good news.
This week, I noticed that Akismet is adding a hidden input field to the comment form that contains a timestamp (although the plugin’s PHP puts the initial INPUT element within a P element set to DISPLAY:NONE, when the plugin’s JavaScript updates the value with the current timestamp, the INPUT element jumps outside of that P element). The injected code looks something like this:
<input type=”hidden” id=”ak_js” name=”ak_js” value=”1420256728989″>
I haven’t yet dug into the Akismet code to discover what it’s doing with the timestamp, but I’d be pleased if Akismet is attempting to differentiate humans from bots based on behavior.
Update 2015-01-10: To test the effectiveness of the current version of Akismet, I disabled the anti-spam plugin described in this post on 1/2/2015 and re-enabled it on 1/10/2015. In the span of 8 days, Akismet identified 1,153 spam comments and missed 15 more. These latest numbers continue to support my position that Akismet is not enough to stop spam comments.

In the endless battle against WordPress comment spam, I’ve developed and then refined a few different methods for preventing spam from getting to the database to begin with. My philosophy has always been that a human visitor and a spam bot behave differently (after all, the bots we’re dealing with are not Nexus-6 model androids here), and an effective spam-prevention method should be able to recognize the differences. I also have a dislike for CAPTCHA methods that require a human visitor to prove, via an intentionally difficult test, that they aren’t a bot. The ideal method, I feel, would be invisible to a human visitor, but still accurately identify comments submitted by bots.

Spam on ardamis.com in early 2012 - before and after

Spam on ardamis.com - before and after

A brief history of spam fighting

The most successful and simple method I found was a server-side system for reducing comment spam by using a handshake method involving timestamps on hidden form fields that I implemented in 2007. The general idea was that a bot would submit a comment more quickly than a human visitor, so if the comment was submitted too soon after the post page was loaded, the comment was rejected. A human caught in this trap would be able to click the Back button on the browser, wait a few seconds, and resubmit. This proved to be very effective on ardamis.com, cutting the number of spam comments intercepted by Akismet per day to nearly zero. For a long time, the only problem was that it required modifying a core WordPress file: wp-comments-post.php. Each time WordPress was updated, the core file was replaced. If I didn’t then go back and make my modifications again, I would lose the spam protection until I made the changes. As it became easier to update WordPress (via a single click in the admin panel) and I updated it more frequently, editing the core file became more of a nuisance.

A huge facepalm

When Google began weighting page load times as part of its ranking algorithm, I implemented the WP Super Cache caching plugin on ardamis.com and configured it to use .htaccess and mod_rewrite to serve cache files. Page load times certainly decreased, but the amount of spam detected by Akismet increased. After a while, I realized that this was because the spam bots were submitting comments from static, cached pages, and the timestamps on those pages, which had been generated server-side with PHP, were already minutes old when the page was requested. The form processing script, which normally rejects comments that are submitted too quickly to be written by a human visitor, happily accepted the timestamps. Even worse, a second function of my anti-spam method also rejected comments that were submitted 10 minutes or more after the page was loaded. Of course, most of the visitors were being served cached pages that were already more than 10 minutes old, so even legitimate comments were being rejected. Using PHP to generate my timestamps obviously was not going to work if I wanted to keep serving cached pages.

JavaScript to the rescue

Generating real-time timestamps on cached pages requires JavaScript. But instead of a reliable server clock setting the timestamp, the time is coming from the visitor’s system, which can’t be trusted to be accurate. Merely changing the comment form to use JavaScript to generate the first timestamp wouldn’t work, because verifying a timestamp generated on the client-side against one generated server-side would be disastrous.

Replacing the PHP-generated timestamps with JavaScript-generated timestamps would require substantial changes to the system.

Traditional client-side form validation using JavaScript happens when the form is submitted. If the validation fails, the form is not submitted, and the visitor typically gets an alert with suggestions on how to make the form acceptable. If the validation passes, the form submission continues without bothering the visitor. To get our two timestamps, we can generate a first timestamp when the page loads and compare it to a second timestamp generated when the form is submitted. If the visitor submits the form too quickly, we can display an alert showing the number of seconds remaining until the form can be successfully submitted. This client-side validation should hopefully be invisible to most visitors who choose to leave comments, but at the very least, far less irritating than a CAPTCHA system.

It took me two tries to get it right, but I’m going to discuss the less successful method first to point out its flaws.

Method One (not good enough)

Here’s how the original system flowed.

  1. Generate a first JS timestamp when the page is loaded.
  2. Generate a second JS timestamp when the form is submitted.
  3. Before the form contents are sent to the server, compare the two timestamps, and if enough time has passed, write a pre-determined passcode to a hidden INPUT element, then submit the form.
  4. After the form contents are sent to the server, use server-side logic to verify that the passcode is present and valid.

The problem was that it seemed that certain bots could parse JavaScript enough to drop the pre-determined passcode into the hidden form field before submitting the form, circumventing the timestamps completely and defeating the system.

Because the timestamps were only compared on the client-side, it also failed to adhere to one of the basic tenants of form validation – that the input must be checked on both the client-side and the server-side.

Method Two (better)

Rather than having the server-side validation be merely a check to confirm that the passcode is present, method two compares the timestamps a second time on the server side. Instead of a single hidden input, we now have two – one for each timestamp. This is intended to prevent a bot from figuring out the ultimate validation mechanism by simply parsing the JavaScript. Finally, the hidden fields are not in the HTML of the page when it’s sent to the browser, but are added to the form via jQuery, which makes it easier to implement and may act as another layer of obfuscation.

  1. Generate a first JS timestamp when the page is loaded and write it to a hidden form field.
  2. Generate a second JS timestamp when the form is submitted and write it to a hidden form field.
  3. Before the form contents are sent to the server, compare the two timestamps, and if enough time has passed, submit the form (client-side validation).
  4. On the form processing page, use server-side logic to compare the timestamps a second time (server-side validation).

This timestamp handshake works more like it did in the proven-effective server-side-only method. We still have to pass something from the comment form to the processing script, but it’s not too obvious from the HTML what is being done with it. Furthermore, even if a bot suspects that the timestamps are being compared, there is no telling from the HTML what the threshold is for distinguishing a valid comment from one that is invalid. (The JavaScript could be parsed by a bot, but the server-side check cannot be, making it possible to require a slightly longer amount of time to elapse in order to pass the server-side check.)

The same downside plagued me

For a long time, far longer than I care to admit, I stubbornly continued to modify the core file wp-comments-post.php to provide the server-side processing. But creating the timestamps and parsing them with a plug-in turned out to be a simple matter of two functions, and in June of 2013 I finally got around to doing it the right way.

The code

The plugin, in all its simplicity, is only 100 lines. Just copy this code into a text editor, save it as a .php file (the name isn’t important) and upload it to the /wp-content/plugins directory and activate it. Feel free to edit it however you like to suit your needs.

<?php

/*
Plugin Name: Timestamp Comment Filter
Plugin URI: //ardamis.com/2011/08/27/a-cache-proof-method-for-reducing-comment-spam/
Description: This plugin measures the amount of time between when the post page loads and the comment is submitted, then rejects any comment that was submitted faster than a human probably would or could.
Version: 0.1
Author: Oliver Baty
Author URI: //ardamis.com

    Copyright 2013  Oliver Baty  (email : obbaty@gmail.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

// http://wordpress.stackexchange.com/questions/6723/how-to-add-a-policy-text-just-before-the-comments
function ard_add_javascript(){

	?>
	
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    ardGenTS1();
});
 
function ardGenTS1() {
    // prepare the form
    $('#commentform').append('<input type="hidden" name="ardTS1" id="ardTS1" value="1" />');
    $('#commentform').append('<input type="hidden" name="ardTS2" id="ardTS2" value="1" />');
    $('#commentform').attr('onsubmit', 'return validate()');
    // set a first timestamp when the page loads
    var ardTS1 = (new Date).getTime();
    document.getElementById("ardTS1").value = ardTS1;
}
 
function validate() {
    // read the first timestamp
    var ardTS1 = document.getElementById("ardTS1").value;
//  alert ('ardTS1: ' + ardTS1);
    // generate the second timestamp
    var ardTS2 = (new Date).getTime();
    document.getElementById("ardTS2").value = ardTS2;
//  alert ('ardTS2: ' + document.getElementById("ardTS2").value);
    // find the difference
    var diff = ardTS2 - ardTS1;
    var elapsed = Math.round(diff / 1000);
    var remaining = 10 - elapsed;
//  alert ('diff: ' + diff + '\n\n elapsed:' + elapsed);
    // check whether enough time has elapsed
    if (diff > 10000) {
        // submit the form
        return true;
    }else{
        // display an alert if the form is submitted within 10 seconds
        alert("This site is protected by an anti-spam feature that requires 10 seconds to have elapsed between the page load and the form submission. \n\n Please close this alert window.  The form may be resubmitted successfully in " + remaining + " seconds.");
        // prevent the form from being submitted
        return false;
    }
}
</script>
	
	<?php
}

add_action('comment_form_before','ard_add_javascript');

// http://wordpress.stackexchange.com/questions/89236/disable-wordpress-comments-api
function ard_parse_timestamps(){

	// Set up the elapsed time, in miliseconds, that is the threshold for determining whether a comment was submitted by a human
	$intThreshold = 10000;
	
	// Set up a message to be displayed if the comment is blocked
	$strMessage = '<strong>ERROR</strong>:  this site uses JavaScript validation to reduce comment spam by rejecting comments that appear to be submitted by an automated method.  Either your browser has JavaScript disabled or the comment appeared to be submitted by a bot.';
	
	$ardTS1 = ( isset($_POST['ardTS1']) ) ? trim($_POST['ardTS1']) : 1;
	$ardTS2 = ( isset($_POST['ardTS2']) ) ? trim($_POST['ardTS2']) : 2;
	$ardTS = $ardTS2 - $ardTS1;
	 
	if ( $ardTS < $intThreshold ) {
	// If the difference of the timestamps is not more than 10 seconds, exit
		wp_die( __($strMessage) );
	}
}
add_action('pre_comment_on_post', 'ard_parse_timestamps');

?>

That’s it. Not so bad, right?

Final thoughts

The screen-shot at the beginning of the post shows the number of spam comments submitted to ardamis.com and detected by Akismet each day from the end of January, 2012, to the beginning of March, 2012. The dramatic drop-off around Jan 20 was when I implemented the method described in this post. The flare-up around Feb 20 was when I updated WordPress and forgot to replace the modified core file for about a week, illustrating one of the hazards of changing core files.

If you would rather not add any hidden form fields to the comment form, you could consider appending the two timestamps to the end of the comment_post_ID field. Because its contents are cast as an integer in wp-comments-post.php when value of the $comment_post_ID variable is set, WordPress won’t be bothered by the extra data at the end of the field, so long as the post ID comes first and is followed by a space. You could then just explode the contents of the comment_post_ID field on the space character, then compare the last two elements of the array.

If you don’t object to meddling with a core file in order to obtain a little extra protection, you can rename the wp-comments-post.php file and change the path in the comment form’s action attribute. I’ve posted logs showing that some bots just try to post spam directly to the wp-comments-post.php file, so renaming that file is an easy way to cut down on spam. Just remember to come back and delete the wp-comments-post.php file each time you update WordPress.

I’m running XAMPP 1.7.4 [PHP: 5.3.5] (not as a service) on 64-bit Windows 7 Professional.

I installed XAMPP to E:\xampp, and I have pinned the XAMPP Control Panel (xampp-control.exe) to the taskbar for easier access, but starting up xampp-control.exe from that shortcut throws an error:

XAMPP Control

XAMPP Component Status Check failure [3].

Current directory: E:\xampp

Run this program only from your XAMPP root directory.

[OK] [Cancel]

Strangely enough, I even get this error even when running xampp-control.exe from my XAMPP root directory, which really is E:\xampp.

The last post in the thread at http://www.apachefriends.org/f/viewtopic.php?f=16&t=44320&sid=a41029c6a36bbf5b3bb5817f37842340&start=60 offers a simple solution: change the Install_Dir value under HKEY_LOCAL_MACHINE to point to C:\xampp. According to the thread, the error message is due to a bug where the Install_Dir is checked against a hard-coded path on C:\. That may or may not be the case, but the suggested work-around seems to be effective.

Here’s a registry merge for Windows 7 64-bit that will make the change for you.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\xampp]
"Install_Dir"="C:\\xampp"

Now xampp-control.exe launches without the error, and I haven’t noticed anything (PHP, MySQL, etc.) not working because of the bogus path.

While making changes to my WordPress theme, I noticed that the error_log file in my theme folder contained dozens of PHP Fatal error lines:

...
[01-Jun-2011 14:25:15] PHP Fatal error:  Call to undefined function  get_header() in /home/accountname/public_html/ardamis.com/wp-content/themes/ars/index.php on line 7
[01-Jun-2011 20:58:23] PHP Fatal error:  Call to undefined function  get_header() in /home/accountname/public_html/ardamis.com/wp-content/themes/ars/index.php on line 7
...

The first seven lines of my theme’s index.php file:

<?php ini_set('display_errors', 0); ?>
<?php
/**
 * @package WordPress
 * @subpackage Ars_Theme
*/
get_header(); ?>

I realized that the error was being generated each time that my theme’s index.php file was called directly, and that the error was caused by the theme’s inability to locate the WordPress get_header function (which is completely normal). Thankfully, the descriptive error wasn’t being output to the browser, but was only being logged to the error_log file, due to the inclusion of the ini_set(‘display_errors’, 0); line. I had learned this the hard way a few months ago when I found that calling the theme’s index.php file directly would generate an error message, output to the browser, that would reveal my hosting account username as part of the absolute path to the file throwing the error.

I decided the best way to handle this would be to check to see if the file could find the get_header function, and if it could not, simply redirect the visitor to the site’s home page. The code I used to do this:

<?php ini_set('display_errors', 0); ?>
<?php
/**
* @package WordPress
* @subpackage Ars_Theme
*/
if (function_exists('get_header')) {
	get_header();
}else{
    /* Redirect browser */
    header("Location: http://" . $_SERVER['HTTP_HOST'] . "");
    /* Make sure that code below does not get executed when we redirect. */
    exit;
}; ?>

So there you have it. No more fatal errors due to get_header when loading the WordPress theme’s index.php file directly. And if something else in the file should throw an error, ini_set(‘display_errors’, 0); means it still won’t be sent to the browser.

Just a few notes to myself about monitoring web sites for infections/malware and potential vulnerabilities.

Tools for detecting infections on web sites

Google Webmaster Tools

Your first stop should be here, as I’ve personally witnessed alerts show up in Webmaster Tools, even when all the following tools gave the site a passing grade. If your site is registered here, and Google finds weird pages on your site, an alert will appear. You can also have the messages forwarded to your email account on file, by choosing the Forward option under the All Messages area of the Home page.

Google Webmaster Tools Hack Alert

Google Safe Browsing

The Google Safe Browsing report for ardamis.com: http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=ardamis.com

Norton Safe Web

https://safeweb.norton.com/

The Norton Safe Web report for ardamis.com: https://safeweb.norton.com/report/show?url=ardamis.com

Tools for analyzing a site for vulnerabilities

Sucuri Site Check

http://sitecheck.sucuri.net/scanner/

The Sucuri report for ardamis.com: http://sitecheck.sucuri.net/scanner/?scan=www.ardamis.com.

I’ve written a few tutorials lately on how to reduce page load times. While I use Google’s Page Speed Firefox/Firebug plugin for evaluating pages for load times, there are times when I want a second opinion, or want to point a client to a tool. This post is a collection of links to online tools for testing web page performance.

Page Speed Online

http://pagespeed.googlelabs.com/

Google’s wonderful Page Speed tool, once only available as a Firefox browser Add-on, finally arrives as an online tool. Achieving a high score (ardamis.com is a 96/100) should be on every web developer’s list of things to do before the culmination of a project.

Enter a URL and Page Speed Online will run performance tests based on a set of best practices known to reduce page load times.

  • Optimizing caching – keeping your application’s data and logic off the network altogether
  • Minimizing round-trip times – reducing the number of serial request-response cycles
  • Minimizing request overhead – reducing upload size
  • Minimizing payload size – reducing the size of responses, downloads, and cached pages
  • Optimizing browser rendering – improving the browser’s layout of a page

WebPagetest

http://www.webpagetest.org/

WebPagetest is an excellent application for users who want the same sort of detailed reporting that one gets with Page Speed.

  • Load time speed test on first view (cold cache) and repeat view (hot cache), first byte and start render
  • Optimization checklist
  • Enable keep-alive, HTML compression, image compression, cache static content, combine JavaScript and CSS, and use of CDN
  • Waterfall
  • Response headers for each request

Load Impact

http://loadimpact.com/pageanalyzer.php

Load Impact is an online load testing service that lets you load- and stress test your website over the Internet. The page analyzer analyzes your web page performance by emulating how a web browser would load your page and all resources referenced in it. The page and its referenced resources are loaded and important performance metrics are measured and displayed in a load-bar diagram along with other per-resource attributes such as URL, size, compression ratio and HTTP status code.

ByteCheck

http://www.bytecheck.com/

ByteCheck is a super minimal site that return your page’s all-important time to first byte (TTFB). Time to first byte is the time it takes for a browser to start receiving information after it has started to make the request to the server, and is responsible for a visitor’s first impression that a page is fast- or slow-loading.

Web Page Analyzer

http://websiteoptimization.com/services/analyze/

My opinion is that the Web Page Analyzer report is good for beginners without much technical knowledge of things like gzip compression and Expires headers. It’s a bit dated, and is primarily concerned with basics like how many images a page contains. It tells you how fast you can expect your page to load for dial-up visitors, which strikes me as quaint and not particularly useful.

  • Total HTTP requests
  • Total size
  • Total size per object type (CSS, JavaScript, images, etc.)
  • Analysis of number of files and file size as compared to recommended limits

The Performance Grader

http://www.joomlaperformance.com/component/option,com_performance/Itemid,52/

This is another simplistic analysis of a site, like Web Page Analyzer, that returns its analysis in the form of pass/fail grades on about 14 different tests. I expect that it would be useful for developers who want to show a client a third-party’s analysis of their work, if the third-party is not terribly technically savvy.

One unique thing about this tool, though, is that it totals up the size of all images referenced in CSS files (even those that the current page isn’t using).

  • HTML Size
  • Total Size
  • Total Requests
  • Generation Time
  • Number of Hosts
  • Number of Images
  • Size of Images
  • Number of CSS Files
  • Size of CSS Files
  • Number of Script Files
  • Size of Script Files
  • HTML Encoding
  • Valid HTML
  • Frames

I had set up a hard drive with two Windows XP installations on separate partitions and used GRUB to choose between them at boot. Eventually, I needed only one of these installations and wanted to clone/copy it to a separate drive. I happened to have an old copy of Ghost 2003, so I used that to clone the partition I wanted to keep.

But when I tried to boot that install, all I got was the word GRUB on an otherwise blank screen after the POST.

I did some Googling and found the How to remove GRUB loader!? post at ntcompatible.com.

Basically, you can get around this problem by replacing the boot sector and MBR.

  1. Boot into Recovery Console with the XP install media by choosing the Repair option
  2. Choose the installation to work on
  3. At the command prompt (assuming your installation is on C:), enter: fixboot c:
  4. Proceed through any warnings
  5. At the command prompt, enter: map
  6. Record the name of the device on which you will be writing the new master boot record
  7. At the command prompt, enter: fixmbr [device_name] (where the device name is something like DeviceHardDisk0
  8. Proceed through any warnings
  9. Exit Recovery Console and reboot

Resources: Windows XP Professional Product Documentation – fixboot and Windows XP Professional Product Documentation – fixmbr