Open Game Source: Fanwor

by Dennis Payne

Name: Fanwor
Version: 1.11
Authors: Thomas Huth
License: GPL
Operating System: Linux and Atari computers
Website: http://www.crosswinds.net/~thothy/unix/fanwor_e.html

Game

Fanwor is the third incarnation of an action-adventure game by Thomas Huth. The game owes it's existence to the 1999 Magic Game Contest to remake a classic game for the old Atari computers. Fanwor attempts to mimic the original Legend of Zelda. Although many of the features of Zelda are not implemented, the game is fully playable and captures the look of the original.

First Impressions

During college I worked with a couple friends on a Legend of Zelda clone. Eventually that project faltered and I began working on Troll Bridge. Fanwor developed with a completely different world view. Although our Legend of Zelda project ran under DOS, we didn't have nearly as limited resources as the older Atari computers.

Supporting such low system requirement, requires a much more resource conscious approach. Globals become your friends because arguments to functions take space on the stack. Dynamic allocation is error prone and complicated so it too is generally tossed. Basically the entire game architecture is narrowed down to the necessary core.

Included with source files is fwsource.txt. The document explains what compilers were used, the organization of the files, and future goals. The source code is acknowledged to be lightly documented and sometimes only in german. System dependent files are stored in the arch directory with an appropriate subdirectory for each system. Except for the missing joystick assembly routines in the atari subdirectory, the document is acurate and a good starting point.

River Crossing

Fanwor wasn't designed to be cross platform. When designing or adapting a program to be cross platform, it is usually best to abstract the operating system and hardware to the necessary functions. The author did just that except he duplicated the header files in the two architectures. Additionally the header files are slightly different by adding system include files and extern declarations. Here is a patch to create a common set of includes(1).

One minor issue of portability is not handled by the arch files, binary file reading. Binary file reading needs to know if the file was written on a machine with a different endianess and adjust accordingly. By writing a known 16 or 32-bit number at the beginning of the data file, the program can automatically detect this change without knowing its endianess. For example, Fanwor's room files use the hexadecimal number 4641574F. If the value is read as 4F574146, then the endianess is different and byte swapping is needed. This technique also prevents the need to write a binary file writing routine. Each system can simple save natively and convert during reading.

Fanwor does have a few potential problems for portability. The first is that long is 64-bit on some machines instead of 32-bit. Since the size of the C types are not guaranteed, the code either cannot assume a size or must create typedefs that can guarantee the size. The other problem is the caused by reading structures with a single fread. On some architecture it is more efficient or even required that certain data types are aligned to specific positions in memory. Rather than trouble the programmer, the compiler automatically pads the structure for efficiency. For example if you created struct one, as shown below, only five bytes would be needed to hold the values assuming 32-bit longs.

struct one                             struct two
{                                      {
 char onebyte;                          char onebyte;
 long twobyte;                          char padding[3];
};                                      long twobyte;
                                       };

On many 32-bit systems the actually structure would be eight bytes and resemble struct two. By reading structures directly Fanwor could read data into the padding created by the compiler. To ensure correct loading, applications must read the individual members of the structure separately.

Converting the Heretic

In general, Troll Bridge has a more advanced game engine. Getting Fanwor to equal footing would require a fair amount of work. Since Troll Bridge was designed from the start to be mostly data driven with a shared library for monsters and items, I decided to convert Fanwor. The conversion posed more problematic than I expected.

The Nintendo uses 16 by 16 sprites. With the 320 by 200 display of Troll Bridge, 20 sprites fill the screen horizontally. As only 16 sprites across need to be supported, the sprites were increased to 20 by 16. Fanwor used to have 16 by 16 sprites but has upgraded to 32 by 32. None of the sprites really took advantage of the enhanced image size so they shrunk without much adverse effect.

Fanwor groups images together and stores them in a large bitmap. For example, all the background tiles are stored in ground.bmp. This made shrinking the images easy but they needed to be split apart for Troll Bridge. This wasn't the first time I needed to split an image. The splitpcx utility I created required a little work to handle really large images but otherwise worked fine. Considering it's usefulness, the program has been added to the Troll Bridge distribution.

Size problems were found in number of vertical tiles as well. Both Legend of Zelda and Fanwor have 16 by 11 background tiles. Experience has shown me that fitting all the tiles on a 320 by 200 display is difficult. When designing Troll Bridge, I purposely dropped the bottom row to simplify things. After contemplating several elaborate schemes to support both sizes, I decided to keep things simple. The bottom row of the Fanwor screens was eliminated.

A new utility room2scr was created to transfer all the level data to the new format. Converting just the background tiles of the surface world to Troll Bridge proved rather easy. But without items, monsters, and entrances to other levels, wandering the world is somewhat dull. Fanwor stores all the extra information in a collection of LEVEL_EINTRAGs. The first byte of the structure is the eintrtyp which determines what type the entity is. There are three used types in Fanwor, monster, door, and item. The source code includes some references to a fourth type, people, but they are not implemented (2).

The door type is actually analogous to an exit in Troll Bridge otherwise the conversion seems straight forward. Life is never that simple though. Thomas Huth's implementation of doors acts differently than the Troll Bridge equivalent. In Fanwor if any part of the main character sprite touches the door square, he is transported through. Since the character never fully reaches the exit area, the effect is a bit jarring. Troll Bridge on the other hand requires the character to enter the exact square of the exit. Because of this difference some modification to the transportation coordinates is needed to look correct.

However, an addition correction must be made. On the initial screen the character can travel to an empty room. The room has a two square opening. With the Fanwor implementation two exits can completely block the opening. Troll Bridge isn't that lucky. Someone travelling in between the two square would avoid activating either exit. In such cases extra exits must be created to completely seal the corridor.

Item conversion went much more smoothly. There are only 8 gems as items. Each gem can only be pickup once. Troll Bridge doesn't allow you to specify items in a particular room but it can accomplish the same with a secret script. When a character enters the room the unset or set script is run for each secret depending on it's value. By default all secrets are unset. The gem object is created by the unset script. Once the object is picked up, the secret is set so that the gem will not reappear.

Troll Bridge items are a bit more powerful. Their effects are programmed in the plugin instead of hard-coded in the program. The Fanwor gems were quickly implemented to do nothing which is not correct since they normally increase the character's hit points. The game plugin should also contain the logic for the monsters but there was insufficient time to convert the enemies. Besides that would make for a difficult game since the character doesn't start with a weapon in Troll Bridge.

Leftovers

Fanwor's most compelling feature over Troll Bridge is music and sound effects. Compiling the game under Linux requires the development versions of SDL and the SDL_Mixer. Interesting as the LGDC's recent poll found the #1 complaint about installing games is the use of bleeding edge libraries. This is actually one of the reasons I haven't implemented music and sound.

The Troll Bridge conversion is available here. There is currently no way to specify sprites, levels, or plugins. To use the files you will need to create symbolic links to the appropriate files. Instructions are provided with the files.

Footnotes

(1) You will still need to delete the old header files, fwgraph.h, fwgui.h, fwguiini.h, and fwmusic.h from each of the arch subdirectories.

(2) Actually the data files for Fanwor have two other of other entity types also unimplemented. I'm not sure what there purpose was.

Back to OGS


Copyright (c) 2000 Dennis Payne / Identical Software