Purple Martians
Technical Code Descriptions
Project Organization
Software and Libraries
Allegro
MinGW-w64
Code::Blocks
libnet
zlib
Source files
Class Naming Conventions
Main
Game Objects
Software and Libraries
Purple Martians is written in C++ and is complied with gcc, the gnu C compiler.
It uses the Allegro game library for display creation, drawing, input, sound, etc...
Because Allegro is a cross platform library, I use the exact same source code to generate the windows and linux versions.
On windows, I use MinGW-w64 port of gcc.
I use Code::Blocks as my IDE, it has windows and linux versions, and the same project file works for both.
All software used is free and open source.
Allegro
Allegro - A Game Programming Library
Allegro is a cross-platform library mainly aimed at video game and multimedia programming. It handles common, low-level tasks such as creating windows, accepting user input, loading data, drawing images, playing sounds, etc. and generally abstracting away the underlying platform. However, Allegro is not a game engine: you are free to design and structure your program as you like.
MinGW-w64
MinGW-w64 - A complete runtime environment for GCC & LLVM for 32 and 64 bit Windows
Mingw-w64 is an advancement of the original mingw.org project, created to support the GCC compiler on Windows systems. It has forked it in 2007 in order to provide support for 64 bits and new APIs. It has since then gained widespread use and distribution.
Code::Blocks
Code::Blocks - The free C/C++ and Fortran IDE.
Code::Blocks is a free C/C++ and Fortran IDE built to meet the most demanding needs of its users. It is designed to be very extensible and fully configurable.
libnet
libnet 0.10.2 - A generic interface to a variety of network drivers.
zlib
zlib - A Massively Spiffy Yet Delicately Unobtrusive Compression Library
Source files
All the source and header files are in the 'src' directory and all compile and link to a single executable.
'pm.exe' for windows
'pm' for linux
Class Naming Conventions
Classes are declared and defined in a pair of .cpp and .h files with the same name as the class.
Then an instance is defined and externally declared.
For example, class name: 'mwFont'
Declared in 'mwFont.h'
// mwFont.h
class mwFont
{
public:
void load_fonts(void);
ALLEGRO_FONT *pixl;
};
extern mwFont mFont;
Implemented in 'mwFont.cpp'
// mwFont.cpp
#include "mwFont.h"
mwFont mFont;
void mwFont::load_fonts(void)
{
al_destroy_font(pixl);
pixl = al_load_ttf_font("bitmaps/PixelGosub.otf", 7, ALLEGRO_TTF_MONOCHROME | ALLEGRO_TTF_NO_KERNING);
if (!pixl) mInput.m_err("Failed to load font from bitmaps/PixelGosub.otf");
.....
}
An instance 'mFont' is defined in 'mwFont.cpp' and externally declared in 'mwFont.h'
Then any source file that uses mwFont just needs to include:
#include "mwFont.h"
And then it refers to the object members like:
mFont.load_fonts()
mFont.pixl
Main
The function 'main' is found in the file: 'main.cpp'.
int main(int argument_count, char **argument_array)
{
mMain.pm_main(argument_count, argument_array);
}
It just directly calls 'mMain.pm_main'
int mwMain::pm_main(int argument_count, char **argument_array)
{
proc_command_line_args1(argument_count, argument_array); // these args get processed before initial setup is called
if (initial_setup())
{
proc_command_line_args2(argument_count, argument_array); // these args get processed after initial setup is called
if (mLoop.state[0] == 0) // nothing set by command line args
{
mLoop.state[1] = mLoop.state[0] = 1; // set up for menu
}
mLoop.main_loop();
}
if (mLog.autosave_log_on_program_exit) mLog.save_log_file();
mConfig.save();
final_wrapup();
exit(0);
}
Game Objects
There are 5 categories of game objects:
Players
class: mwPlayer
instance: mPlayer
files:
mwPlayer.h
mwPlayer.cpp
There are data structures for 8 players.
The class contains two arrays of structures for each player. One local and one synced in netgame.
struct psyn syn[NUM_PLAYERS];
struct ploc loc[NUM_PLAYERS];
Enemies
class: mwEnemy
instance: mEnemy
files:
mwEnemy.h
mwEnemy.cpp
mwEnemyArchwagon.cpp
mwEnemyCannon.cpp
mwEnemyCloner.cpp
mwEnemyEditorFnx.cpp
mwEnemyFlapper.cpp
mwEnemyFnx.cpp
mwEnemyJumpworm.cpp
mwEnemyTrakbot.cpp
mwEnemyVinePod.cpp
There are data structures for 100 enemies.
Each enemy has an array of 32 integers and 16 floats
int Ei[100][32]; // enemy ints
float Ef[100][16]; // enemy floats
Items
class: mwItem
instance: mItem
files:
mwItem.h
mwItem.cpp
mwItemBombRocket.cpp
mwItemDoor.cpp
mwItemEditorFnx.cpp
mwItemKeySwitch.cpp
mwItemMessage.cpp
mwItemStartExitGate.cpp
mwItemTrigger.cpp
There are data structures for 500 items.
Each item has an array of 16 integers and 4 floats
int item[500][16]; // item ints
float itemf[500][4]; // item floats
Shots
class: mwShot
instance: mShot
files:
mwShot.h
mwShot.cpp
There are data structures for 50 player shots and 50 enemy shots
struct eshot e[50];
struct pshot p[50];
Lifts
class: mwLift
instance: mLift
files:
mwLift.h
mwLift.cpp
There are data structures for 40 lifts, each containing 40 lift steps
struct lift cur[NUM_LIFTS];
struct lift_step stp[NUM_LIFTS][40];