Pages

Saturday, July 30, 2011

Ethernet with r8101 module and RealTek 8101E in Linux with a HP 2000 219dx

HP has at least two laptop models that use the RealTek 8101E Fast Ethernet for their ports. One is the "g4 1117dx," and another is the "2000 219dx." 

On a Dell mini 9 running Ubuntu 11.04 (2.6.38-10-generic), the r8169 module works out-of-the-box when an ethernet cable is plugged in. This is not the case with either HP laptop, even though r8169.c mentions the 8101 model. 

It has been discussed elsewhere that ethernet devices using the r8169 module may be disabled in Windows after a reboot. Enabling "Wake on LAN," removing the battery and power supply, and waiting for some time allows the hardware to work in Linux. While I did not try the suggested solution with the former HP model, it did not work with the latter. 

As for wireless, it would have likely been easier to set up. While neither HP laptop works out-of-the-box with wireless in Ubuntu 11.04, using an external adapter and running software update enables the internal wireless on both machines.

With the LFS LiveCD, it's a toss-up: wireless or wired? I wanted to save the adapter for another day, so ethernet it is.

I used a HOWTO on the Debian forums leading me to this driver, and copied the tarball to an external flash drive. Mount the drive from LFS LiveCD and copy it to a convenient location like $LFS/opt.

Make sure you have partition(s) on the hard drive set up before mounting the external. You'll be producing files during extraction and compilation, so you'll need a place to put them. The CD-R has already been written with the LiveCD OS; it can't be written to twice. 

Here's the order of commands I used:

$ mkdir -v /mnt/usb
$ mount -v -t ext3 /dev/sdb1 /mnt/usb
$ cp -v /mnt/usb/r8101-driver.tar.gz $LFS/usr/src && cd $LFS/opt
$ tar xjf r8101-driver.tar.gz
$ cd r8101-driver.tar.gz/

The LFS LiveCD uses kernel 2.6.22.5, while the current kernel version is something like 3.0. Between 2.6.22.5 and 2.6.38, the symbol DMA_32BIT_MASK changed to DMA_BIT_MASK. You'll need to change all references to DMA_BIT_MASK(xx) to DMA_32BIT_MASK in ./src/r8101_n.c, about seven in all. Otherwise, while compilation succeeds, modprobe results in a "Undefined symbol" error. 

Now you're ready to run the included shell script:

$ ./autorun.sh

The script will remove the r8169 module that was detected earlier, rename it as a backup file, and load r8101. If you're successful, the ethernet port will glow white. :) Use lsmod to confirm that r8101 is loaded, and lsmod | grep r8169 to make sure the old one is not. 

Ping still won't detect a host, so 

$ ifconfig eth0 up
$ dhcpcd 

And you should be in business - that is, downloading the programs for LFS 6.8.


Thursday, March 24, 2011

Miniatures grid with PHP and MySQL

After reading "PHP & MySQL for Dummies," I created a miniatures grid for use via the browser:



This article covers general patterns and suggestions for further improvement. The code is certainly refactorable.

The strongest feature of PHP and MySQL is that it combines a server-side scripting language with a persistent data store. You can imagine the database as a global variable - and it might as well be, since it's as easily accessible as one. When to query the database is up to the programmer and his discipline.

Here is a general flowchart of a typical user case through the PHP files:



The two biggest parts of the grid project involve user interaction: logging in, and doing actions with the grid. Squares can be blackened to represent walls, and miniatures can be added or removed. The primary view is an HTML table that dispgrid.php spits out. Only minor adjustments are needed to accommodate adding or removing miniatures, and for editing squares:



Thanks to the database, I only have to worry about a small number of variables. That lets me collect and transfer data in two ways: through forms, and via session variables. I store database queries with an associative array, which is very useful in PHP: utterly convenient, as the code will show.

I control access to individual PHP files by testing whether a username session variable has been set. It is only set at the beginning with a successful login. In any other circumstance, kick the user back to the login page.


Session variable 'loggedin' is only set here if password matches the one from the database.

Every PHP file checks for this session variable at the beginning, and boots the user out if it is not set.

With PHP, I can generate dynamic content; in this case, an HTML table that populates relevant cells with information from the database. The foreach lets me iterate through the rows returned from a database query




With forms, session variables and a persistent store, "pseudo" multi-user interfaces like this grid can be simulated. Every refresh of the view is a new hit on the database, pulling in the most recent data. This works because the grid depends on the turn-based mechanic of these kinds of games.

Hopefully this code helps get you started on the path to web apps, or to clear some assumptions. The best thing to do is to jump in! :)



Go forth... and conquer.

Further Investigation
AJAX for automatic refresh
SVG and <canvas>
jQuery drag-and-drop with pathfinding
Refined user interface
Colored squares
Randomized dungeons
Faster painting than checkboxes
Additional tables in the database
Zend, or object-oriented PHP
Security

Code
PHP files (grid.zip) [MediaFire]
MySQL Database file [MediaFire]
Update August 2011: Old links died; uploaded as a folder. [MediaFire]
Update October 2011: Old link died. SQL file included. [MediaFire]

Reference
"PHP & MySQL for Dummies" [Amazon Affiliate Link]

Monday, February 14, 2011

Tandem sprite movement in Allegro 5

My friends and I worked on a flixel game called "Deaf Bastard," which featured a composer who moved notes. The player controlled two sprites simultaneously. Pressing left made one note move left, and made the other note move right. The former was called the "direct note," and the latter was called the "inverse note." Our last build here.



We hit a technical challenge early on, because flixel as-is checked for collisions after positions were updated. Both of the notes' positions were incremented even if one note collided against a wall. So you could bang the direct note repeatedly against the ceiling, and the inverse note would "creep" down. Without preservation of note positions, the game mechanics were inconsistent.

Compounding this difficulty was the seeming complexity of determining which note would collide against a wall first. Each note was independently updated. The distance traversed in each frame was hard to predict, and therefore hard to undo.

I never could figure it out, but with Allegro 5 I tried again.


This implementation uses two features to avoid creep and to maintain consistent note movement: states to permit a note's position to be updated (that is, to be moved), and events triggered by released keys.

During each iteration of the game loop, we first determine the direction of the note. If the note is moving down, it is affected by a positive velocity along the y-axis. We predict the note's future position by adding the note's (current) y-position and its speed. There is a collision if the note passes the floor boundary, designated by the #define symbol HEIGHT.


All of my drawing functions assume the sprite's position is at its center. In order to calculate boundaries, I have to add or subtract SPRITE_HEIGHT/2 or SPRITE_WIDTH/2 as needed.

If there is an imminent collision, we do some bookkeeping: zero the note's speed, and reset its position to be flush with the floor. We set the note's vertical state to DO_NOT_UPDATE_V, which denies permission to update position, at least in this loop (explained next). We also prevent the player from moving the note with the left or right key. Since this is a floor collision, the player can't move left or right until he releases the up key (explained in last code snippet). 


This is the crux of the matter: one note collided, which means the other note should not move. We use a state variable to control permission. In our final code snippet, we look at reenabling the player's left-right input if he releases the up key. This by the design of the mechanic: the player should not be able to move notes further if they collide against any wall.



We need the zerospeed() function call because the next iteration of the game loop leads directly back to the notes updating their positions. The player releases the up key, fine; but in the next frame the note's y-speed remains non-zero, therefore yspd > 0, therefore predy > HEIGHT, therefore lockedkeys = true. Perpetually so, which means the player is never able to move the notes left or right. You can see this for yourself by commenting out zerospeed() above and re-compiling.

Files
deaf.c
deaf.h

Compilation
gcc deaf.c -o deaf.out -L/usr/local/lib -lallegro -lallegro_main -lallegro_primitives


(This is assuming your shared libraries are in /usr/local/lib/ directory.)


Further Investigations
  • Does it work when notes are placed in different initial positions?
  • Implement checkpath().
  • Go back and do it in flixel.
Reference
Game Programming All-in-One, 3e by Jonathan Harbour [Amazon Affiliate Link]

Credits
Original flixel version: All of the architecture, design and initial coding was done by Josh Helpert, with co-design and graphics by dcb.

Update. Added a link to the swf file.
Update August 2011. Added Reference section and an Amazon affiliate link.

Saturday, January 15, 2011

TrueType fonts in Allegro 5 and Mac OS X

I tried the font tutorial, but couldn't run it due to a failed assertion. Despite linking against liballegro_font.dylib and liballegro_ttf.dylib with the linker flags -lallegro_font and -lallegro_ttf, and subsequent success in compilation, the executable immediately quits with an "Abort trap": 





While the tutorial uses a straight font name, on Mac OS X the font path must be fully specified. So if you want to use Arial, the string should be "/Library/Fonts/Arial.ttf". 






A lot prettier fonts than the default in Allegro 4.x. :)

Friday, January 14, 2011

Compiling Allegro 5 with Mac OS X Snow Leopard (10.6.6)

This tutorial takes you through building Allegro 5.0.0rc4 and compiling your first Allegro program. You will need the following:

The steps of the tutorial are as follows: 
  1. Extract Allegro source files, and install CMake.
  2. Use the CMake GUI to specify the Clang compiler, and to generate the makefile.
  3. Run make and make install at the command-line.
  4. Write and run your first Allegro 5 program.
Extract Allegro source and install CMake

  1. Open Terminal.
  2. cd ~/Downloads/
  3. tar xvzf allegro-5.0.0rc4.tar.gz
  4. cd allegro-5.0.0rc4.tar.gz
  5. mkdir Build
  6. cd Build
  7. Double-click on the cmake .dmg file and install CMake.
The cd command, change directory, takes you inside the Downloads/ folder. The command tar with the x option specifies an extraction operation. (tar can also list, add or create compressed files.) The additional options v, z, f specify the following, respectively: 
  • Show me what you're extracting.
  • z because it's a gzip file. Notice the filename has a .gz extension.
  • f because I'll supply you with the filename.
The Allegro README recommends building in a separate build directory, so we make the directory with mkdir. If you mess up during the build process, you just have to delete one folder; it's cleaner. We then go into the Build/ directory so that everything is built in this location. 

Installing CMake from a .dmg file should be self-explanatory.

Specify Clang as our compiler and generate the Makefile
  1. Launch the CMake application from your Applications folder. 
  2. In the Source field, enter /Users/your-login-name/Downloads/allegro-5.0.0rc4
  3. In the Build field, enter /Users/your-login-name/Downloads/allegro-5.0.0rc4/Build
  4. Click Generate - and when you do, a dialog like this should appear: 

If this dialog does not appear, make sure your Build/ directory is empty. This dialog needs to appear in order for you to specify Clang ("cee-lang") as your compiler of choice. It has to do with gcc being the default compiler and Snow Leopard being a 64-bit OS.

When this dialog appears, be sure to select "Specify native compilers." Clang comes with Snow Leopard; we just need to tell CMake that we will use Clang as our C compiler instead of the GNU C compiler. Click Continue. 

In the next dialog, in the C text field, enter the path to the clang tool: /Developer/usr/bin/clang


Click Done, and CMake should create nine files in the build directory. You can use ls to list them.


Make and make install

  1. Still in the Build/ directory, type sudo cmake .
  2. sudo make
  3. sudo make install
Alright, now take a look at the /usr/local/lib directory. Note the pattern of each filename:
  • lib
  • allegro or allegro_something
  • .dylib
Write and run your first Allegro program
  1. Create a text file alleg5test.c and enter this code listing.
  2. gcc alleg5test.c -o alleg5test -L/usr/local/lib -lallegro -lallegro_main
  3. ./alleg5test

You should get a window with a black background to show up. If you did, congratulations!

Check out the pattern of the flags: a -l ("dash-el") followed by allegro_. I guess all of them are the .dylib files from /usr/local/lib. Hmm.

You might be able to adjust this tutorial to work with Xcode, and then to create an Allegro template. (Hint: See my previous tutorial on Flixel.)

I hope this saves you some time. Go through the tutorials, and go make some games!

References

Updates

  • 1/15/2011: Removed -lz option from the long gcc above. That would have told the linker to look for a library named "z." Lol.
  • 1/15/2011: Much shorter gcc invocation. Originally gcc alleg5test.c -o alleg5test -lallegro -lallegro_font -lallegro_main -lallegro_primitives -lallegro_image -framework AppKit -framework OpenGL /usr/lib/libIOKit.dylib -framework Cocoa, but not all of these are needed (at least for our small program). Compare with Allegro 4.4, where you did gcc helloworld.c `allegro-config --libs`. The output of allegro-config 4.4.1 was -L/usr/local/lib -framework Cocoa -lalleg-main -lalleg. Similar, no? 
  • 1/15/2011: I can't compile the bitmap tutorial at the Allegro wiki. My error message is, "Undefined symbols: _al_set_clear_to_color." Strange. Oops, typo. gg. There's a al_clear_to_color() function; I was just practicing my speed typing.
  • 1/15/2011: Added an extra step, sudo cmake ., because there's no Makefile after CMake creates its nine files.
  • 1/22/2011: Took out the "-framework Cocoa" switch in gcc. Don't need it.
Now, if only there was a allegro-config that could do for Allegro 5 what it did for Allegro 4.4. (If you're up to it, write a program allegro5-config that outputs the appropriate arguments to gcc, place it in /usr/local/bin, and then try gcc alleg5test.c `allegro5-config [--libs]`. It might not even have to be a program, but just a shell script.)