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];