Monday, January 07, 2008

Pimp my School Desktop

Ah, the first day back at school... I'm starting my second term of the school year and thought I'd celebrate by making my desktop environment just the way I like it on the university Linux computers. That means I'd have a leet hacker desktop that provides me with interesting information and no overhead. I ended up settling on Fluxbox for the window manager and gkrellm for system information. Unfortunately, I'm unable to use it on the Solaris workstations but at least it works on the CentOS Linux computers. Let's get started!

First we'll download the required source files:
wget prdownloads.sourceforge.net/fluxbox/fluxbox-1.0.0.tar.bz2
wget members.dslextreme.com/users/billw/gkrellm/gkrellm-2.3.1.tar.bz2


If these download locations change, you can just visit http://fluxbox.sourceforge.net and http://gkrellm.net and manually download the source files.

For our second step, we'll install fluxbox in our home directory. Normally, we'd want to install it system wide, but since we're merely users and not administrators of the system, this will have to do. To begin our installation, unpack the source files.

tar xvjf fluxbox-1.0.0.tar.bz2

x means extract, v means be verbose, j means use bz2 decompression, and f means we're dealing with a file. So that you don't consume your entire disk quota, you may wish to compile programs in the /tmp directory where space may be a little more abundant.

mv fluxbox-1.0.0 /tmp

Configure the pending installation for your operating system and architecture.

./configure --prefix=/home/username

Replace username with the path to the home directory that we will be using. If unsure, we can check what it is, by opening a terminal, and without changing directories, enter the command pwd, which stands for print working directory. By prefixing our configuration, we're stating that instead of installing the software to the root directory of the system, we want to install it in our home directory where it won't be erased. The rest of the installation is pretty straight forward.

make
make install


make compiles the source code and make install finally installs it in our home directory.

Let's customize a few things to make our fluxbox installation pretty and usable. Create a .xsession file in your home directory with the following contents to have it startup automatically upon login:

# Wallpaper
# if -a doesn't stretch, try -c to at least make it centered
# www.digitalblasphemy.com is a great place for wallpapers!
# Remember, fluxbox's themes have the ability to overwrite our background!
# To turn off the background from a given them, you may wish to comment
# out the lines beginning with background with a preceeding # from
# ~/share/fluxbox/styles/theme_in_use
/home/username/bin/fbsetbg -a /home/username/bg.jpg &

# System monitor (we'll install that next)
/home/username/bin/gkrellm &

# Fluxbox - It's what leet hackers use!
/home/username/bin/fluxbox


Notice the & used at the end of all, but the last, commands? This tells the computer to keep executing the next command instead of waiting for the current one to finish. We don't use & on the last command because if we were to continue past it, and indeed once it completes, our X session will terminate. By the way, if you mess something up where you can't login graphically. You would probably want to ssh in to the computer from a remote location and use your favorite text editor to fix the configuration file. Remember, when logging in, be sure to choose the system default session so that our custom .xsession file is used to setup the environment. In fact, choosing a different session may help out if you get yourself into a bind from incorrectly creating the session configuration. Also, notice how we're using the full filename of each command instead of the relative path? If you want to be able to execute the programs that the fluxbox installation put in your home directory without providing the full path after logging in, you would also need to create the following .bash_profile file in your home directory:

PATH=$PATH:/home/username/bin
export PATH


The first line appends the binary files directory, which the Fluxbox installation would have setup if it didn't already exist, to our path so that Linux will check it for executables we want to run. The second line exports our updated PATH variable to the environment so that the changes take effect after the script completes.

Alright, our desktop environment should be humming along now. If it's not, please feel free to comment on this post and maybe we can figure out the problem together. Onward to setting up gkrellm for all sorts of useful system information that can be displayed on the desktop!

Again, I recommend unpacking the source to the /tmp directory.

tar xvjf gkrellm-2.3.1.tar.bz2
mv gkrellm-2.3.1 /tmp


By reading the included INSTALL file, I found that gkrellm doesn't use a configure script like most Unix programs do. Recall that we used configure's prefix switch to set the installation path before. It turns out that we can achieve the same result with make in this case!

make
make PREFIX=/home/username install


Once gkrellm is installed and running (our .xsession file above will start it), let's right it and choose Configuration. Here we can enable the saving of it's location upon exit and, in the Properties tab, we can choose to keep it hidden from the taskbar and desktop pager.

Lastly, we should probably remove the unpacked source from the /tmp directory to free up the space we borrowed.

cd /tmp
rm -rv fluxbox-1.0.0 gkrellm-2.3.1


-r means recursive and -v means be verbose.

That's all! Now you too have a leet hacker desktop at school :)

Thursday, January 03, 2008

Wifi on the Command Line

This article demonstrates how one can setup a fairly secure wireless connection using the GNU/Linux command line.

Before we get started though, I must say that dd-wrt makes for an interesting upgrade to many different kinds of routers. Even my Linksys WRT54Gv8, purchased in 2007, is supported by dd-wrt version 24 and above. This firmware provides everything from a telnet login to useage graphs to Quality of Service priority settings. If you're brave, as a faulty upload could brick your router, I recommend it!

The first step in setting up a wireless connection in linux is discovering what wireless hardware your computer has. Here, lspci is helpful. After installing this utility, I get the following results:

$ lspci
02:04.0 Ethernet controller: Atheros Communications, Inc. AR5212 802.11abg NIC (rev 01)


That's interesting; so I'm using an Atheros chipset for wireless on my computer. Sometimes lspci will find unknown hardware. Naturally if your wireless card is unknown it's not going to be very useful. If you find yourself in this situation, you may need to recompile your kernel with support for the wireless chipset according to it's documentation or simply install a distro specific program that can automatically set it up for you.

Once Linux recognizes your wireless card, we can use wpa_supplicant to translate with any WPA or WPA2 protocols in use by the router. As each wifi setup differs, I recommend to read the following man pages and use the information to setup your configuration file.

$ man wpa_supplicant
$ man wpa_supplicant.conf


Now to setup that configuration file. Remeber, your configuration file may be very different so please read those man pages!

vim /etc/wpa_supplicant/wpa_supplicant.conf

# Home sweet home network, featuring a WPA/WPA2 Personal connection!
network={
ssid="Protoss Pylon"
scan_ssid=1
key_mgmt=WPA-PSK # WPA/WPA2 Personal
psk="yaa123_3311" # Passkey
priority=1000
}

# This is a network block that connects to any unsecured access point.
# We give it a low priority so any defined blocks are preferred.
network={
key_mgmt=NONE
priority=-9999999
}


Once we have configured wpa_supplicant, we can run it in the background using the switches mentioned in the man pages.

# wpa_supplicant -Dmadwifi -iath0 -c/etc/wpa_supplicant/wpa_supplicant.conf &

Also, please remember that you must still run your DHCP client to request an IP address. wpa_supplicant just takes care of WPA encryption.

# dhcpcd ath0

I recommend reviewing your distro's documentation regarding setting up wifi automatically during boot as each seems to do things differently. Happy hacking from remote locations.

Saturday, December 29, 2007

Identifying Hardware

CPU Architecture


Installing Gentoo Linux reminds me that there are times when a GNU/Linux user can benefit from knowing the details of their hardware. uname is a great command to accomplish this.

$ uname -a # a for all information
Linux livecd 2.6.19-gentoo-r5 #1 SMP Thu Apr 5 15:05:48 UTC 2007 i686 Intel(R) Celeron(R) Celeron(R) CPU 2.93GHz GenuineIntel GNU/Linux


Here, uname tells us that a LiveCD is running with Linux kernel version 2.6.19-gentoo-r5. It's compiled for i686 multiprocessor systems. The processor in use is a Intel Celeron and it's clocked at 2.93GHz.

PCI Bus


Another great command for learning about your hardware is lspci. If your Linux kernel isn't using some of the hardware on your computer, you may find that lspci won't list any details about those certain pieces of hardware, however. Here's an example of it in use:

# lspci -v
00:00.0 Host bridge: ATI Technologies Inc R200 AGP Bridge [Mobility Radeon 7000 IGP] (rev 05)
Flags: bus master, 66MHz, medium devsel, latency 64
Memory at b0000000 (32-bit, prefetchable) [size=64M]
Memory at b4000000 (32-bit, prefetchable) [size=4K]
Capabilities: [a0] AGP version 2.0


For brevity, I've only included the first piece of hardware found on the PCI bus. We can also list the hardware in a tree, which is great for seeing what pieces run through various busses.

# lspci -tv

The -v switch just makes the output a little more verbose.

Tuesday, December 25, 2007

Searching

Finding Files with an Index


Linux provides an easy way to create an index of files for fast future searching. updatedb would have been used in the past, and still can be, but a newer implementation just uses it as an alias to call slocate with a switch. What's slocate? It stands for secure locate and is like the original locate command, which searches through the index for a given file, except that it doesn't list files that one has no permission to view.

# slocate -u # update file index

Once the file index is up to date, one can find any given file quickly using the following command.

$ slocate filename # locate any file with filename in its name

You may wish to review the man page for slocate as well because this command supports things like case insensitive search and regular expressions!

Finding Files without an Index


But what if we don't have an index of which to search through for the desired files? We can still use the find command. Here's an example:

$ find / -iname filename

Here, find is instructed to start searching at the root of the file tree for files with the name of filename, while ignoring their case.

Binary Files


whereis is a great command for locating binary files that are stored in a standard path. For example, if we want to find where the ls command is:

$ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz


This tells us that the ls command has the path of /bin and the man pages are located in /usr/share/man/man1/ls.1.gz.

Finding Commands


There are times when one may wish to find a suitable program for a given task. For example, I may wish to find commands that deal with searching.

$ apropos search
apropos (1) - search the manual page names and descriptions
badblocks (8) - search a device for bad blocks
bzegrep (1) - search possibly bzip2 compressed files for a regular expression


Here apropos shows us that apropos itself, badblocks, and bzegrep can be used to search for different types of things. Remember, if you install new programs with new man pages, be sure to run mandb to update the list that apropos searches through.

Sunday, December 23, 2007

Linux I/O Redirection


Redirection with Files


Let's get started with a few simple examples of redirection:

command > filename # Redirect command's output to a new or overwritten file
command < filename # Use filename's contents as standard input for command


The first command would overwrite an existing file. So what if we want to only append command's output to a file?

command >> filename # Append command's output to filename

If you're a C++ programmer, you can remember the difference between this and the first output redirection command by recalling that C++ uses the >> operator to add to a stream, not replace it.

Speaking of C++, it uses three main streams:
stdin: 0
stdout: 1
stderr: 2

If we want to save standard error to a file, we can:

command 2> error_output

We could do the same with standard output, or even redirect standard error to standard output:

command 2>&1

And that's the basics of using I/O redirection with files. What if we want to send the output of one command to another as it's input? Linux allows us to do this using pipes.

Pipes


We can pipe the output of one command into the input of another:

first_command | second_command

We could even create a named pipe that delivers one command's output to another as input. The cool thing about named pipes is that they allow programs in different terminals and among different users to communicate. As Linux treats named pipes as ordinary files, we can even set their permissions!

mkfifo name_of_pipe # create a named pipe
command > name_of_pipe # direct output to named pipe as if it's a file
command < name_of_pipe # accept input from named pipe; can be done as different user


Now you have the basics of redirection with files and pipes! Have a nice day :)

Thursday, December 20, 2007

C++ Reference
Who's sick of always having to think about C++ syntax instead of getting into the flow of coding an idea? I am, so I put a reference sheet together. If you'd like a copy please feel free to email me at my full name in lower case and without spaces at gmail (dot) com.

Wednesday, December 19, 2007


Hero of Allacrost: Engine Overview

Until today, I would have had to shamefully admit that I a have barely considered another person's code beside my own. I'm not talking about example code. Rather, I'm referring to looking at another person or group's large-scale program and attempting to figure out how they structured it at a high level. If you haven't done this yourself, I can say from my my recent experience that it's an eye opener for considering different ways of doing things. Most importantly it allows one to see how a successful program is designed.

Today I'll be reviewing Hero of Allacrost. It's an up and coming C++ RPG in the Open Source world. Although it's not a full game as of yet, a tech demo has been released and the team is well on it's way to expanding it into a full story-driven game.

Originally when I had decided to look into how an RPG game engine was designed, I thought it would require slogging through code multiple times in a chaotic attempt to understand the engine's structure. Thanks to the work by some easy to understand authors gaining insight into their engine turned out to be rather painless, much to my relief.

Allacrost makes extensive use of the singleton design pattern. The defining point of singleton classes is that they can only be instantiated once. Attempting to instantiate them again common returns a pointer to the already instantiated instance. Allacrost has audio, video, scripting, input, global, mode, and system singletons, among others. They are instantiated in main.cpp so that whatever uses them later on doesn't have to worry about setting them up. One can pretty much guess what these singleton's do, based on their names, except for the mode singleton, which leads us to the next defining point of the Allacrost engine.

Allacrost uses a concept of game modes. Example modes include map exploration, battling, shopping, paused gameplay, the menu screen, and even quit confirmation. Multiple modes can exist at the same time on a stack, with the mode at the top being the one that the game actually runs. Each mode requires three functions:
  • Reset(): Prepares a mode, which has just reached the top of the mode stack, for use again.
  • Update(): Allows a mode to do its processing.
  • Draw(): Draws a mode.
The real power of modes is evident in the idea that the engine can be expanded to include new modes in the future.

Speaking of updating a mode, Allacrost uses time-based movement as opposed to fixed movement. This allows the game to take advantage of fast computers while at least running on older computers. From reading the Allacrost Quick Start Guide, I learned that the sleep function, which would be required with fixed movement on fast computers, has a varying accuracy across different operating systems. Besides any modern operating system will divide processing power between the running processes. Allacrost still makes use of the sleep function while in pause mode due to it's low use of the processor.

The input singleton accepts input from a keyboard or joystick and provides it to the rest of the engine in a queue of commands, such as move up. Each command has three accessors: pressed, released, and state. A command is pressed during the first main loop iteration that it is detected in. Released is similar. That leaves state, which is only true if the button triggering a given command is currently down.

The audio singleton makes use of the OpenAL and Ogg Vorbis libraries. It treats sound and music similarly, but distinctly and with differing features. While one song can play at a time, there may be a number of sound effects in use at once. To keep things simple, as all programs that are actually completed must, Allacrost refers to music and sound files by filename, excluding path and extension. All music files are stored in a single directory, while sound files are stored in another. There are no category folders for audio beyond that. Audio can be played, paused, stopped, and unloaded, among other things.

Next up, we have the video singleton. OpenGL is used for graphics, DevIL for images, and SDL_ttf for fonts. One common problem game programmers face is what the heck to do with different screen resolutions. Is a game's difficulty balanced really balanced when you can see more of the map just because you are using a higher screen resolution than someone else. Allacrost gets around this by dividing the screen with a coordinate system. The video singleton has a function that allows the programmer to choose the coordinate system, so for example, the screen can be 32 arbitrary units across and 24 arbitrary units high. The Allacrost team uses this to ease tile placement in map mode. Another point of interest with the video singleton is that it permits drawing on the screen using a cursor that can have it's location set absolutely or relatively, among other things. Relating to the video singleton, the GUI singleton uses unicode for displaying text so that the game can be translated to languages of other alphabets in the future.

What RPG would be complete without a scripting language? Allacrost wouldn't and that's why it uses the Lua scripting language. Of interesting note, Lua is also the Roman goddess whom soldiers would offer their seized weapons to. Anyway, the Lua scripting language can be bound with C++ allowing the Allacrost team to rapidly create game content to fill their engine with. Scripts can be stored in a binary or text mode. It makes no difference to the engine, although binary scripts will naturally run faster. The engine can read them using functions like bool readBool (const char *key) and int readInt (const char *key). The key just identifies what variable in a given table (as Lua calls a scope) should have it's value returned.

Finally, one more topic I feel is of merit in this summary of the Allacrost Getting Started Guide is error handling. The Allacrost team uses their own Exception class, upon which all other exceptions are derived from. If an exception unwinds the stack all the way back to the main game loop, the game crashes with a message. Smaller errors, such as failing to load a file, are handled immediately through the boolean return value of related functions.

With the above said, Hero of Allacrost is definitely a game to keep an eye on. Even if it goes nowhere, the existing documentation and code is something to learn from! Best of luck to the development team. You guys, and girls if there are any, rock!