Commits

Palmer, 2E0EOL committed 4990e78

Code taken from http://svn.daybologic.co.uk/trac/bships/browser/branches/hg-bin-trims?rev=12
Binaries, resources and compiler-specific redistributables have been removed.

  • Participants

Comments (0)

Files changed (27)

!GetProc.com

Binary file added.
+#ifndef __INC_ASM_ROUTINES_H
+#define __INC_ASM_ROUTINES_H
+//------------------------------------------------------------------------------
+extern "C" void ApcVgaRs(void); // Resets to VGA mode
+//------------------------------------------------------------------------------
+#endif // __INC_ASM_ROUTINES_H
+#ifndef __INC_BGLOBALS_H
+#define __INC_BGLOBALS_H
+//------------------------------------------------------------------------------
+#include <conio.h>
+#include "Configs.h"
+#include "GameCode.h" // for game related types
+//------------------------------------------------------------------------------
+//BSHIPS BGLOBALS
+
+/* Declarations of all global data that is allowed to spread the entire
+application, all of this data & funcs. are in BGLOBALS.OBJ/.CPP */
+
+// External data
+extern BOOL _OverlordDebug;
+extern BOOL _InitStepDebug;
+extern unsigned int _MenuCommand;
+#ifdef __NO_NAMESPACES__
+extern TCfgBin* _CfgBin;
+#else
+extern Configs::TCfgBin* _CfgBin;
+#endif
+extern TGame* _GamePtr; // A global pointer to the game for external access
+
+// External Functions
+extern void DispWarnLine(const char* Warning, int OldTextColor = WHITE); // failed test, but not fatal
+
+// Parameters
+#define _MENUCOMMAND_SAFE		  	0x0000 // Use this if the talk back should be ignored
+#define _MENUCOMMAND_TERMINATE 	0x0001 // Terminate (normally) the program
+//------------------------------------------------------------------------------
+#endif // __INC_BGLOBALS_H
+/* Use of BShips .INI files, used to ensure identifier consistancy */
+//------------------------------------------------------------------------------
+#ifndef __INC_BSHIPS_INI_H
+#define __INC_BSHIPS_INI_H // Sentry
+
+#include "Headers\DIniFile.h" // Generic .INI API
+//------------------------------------------------------------------------------
+// Files
+#define INI_FILE "BShpCfg.ini"
+// Sections
+#define INI_OPTIONS_SECTION "Options"
+// Keys
+#define INI_IMAGE_FADE_KEY "ImageFade"
+// Key defaults
+#define INI_IMAGE_FADE_DEFAULTVAUE 1
+//------------------------------------------------------------------------------
+#endif // __INC_BSHIPS_INI_H
+LICENSE AGREEMENT FOR BSHIPS
+----------------------------
+BShips by David Duncan Ross Palmer
+Copyright 1998, Daybo Logic, all rights reserved.
+
+
+COPYRIGHT
+---------
+All executable code is the copyrighted inctilectual property of Daybo Logic,
+the company owned by David Duncan Ross Palmer and Neil John Abbott.  All
+resources such as images and sounds are copyrighted also.  Unauthorised
+copying or distribution without express written permission from Daybo Logic
+is strictly prohibited by UK law and international treaty agreements.  If a
+violation is discovered it will be persued to the maximum extent of the law.
+
+Disassembly / decompilation or modification of executable code and / or
+resources is prohibited.
+
+YOU CANNOT SAY THAT YOU HAVE NOT BEEN WARNED ABOUT THE LEGAL CONSEQUENCES
+OF THE ISSUES DISCUSSED IN THIS DOCUMENT, YOU SHOULD READ IT CAREFULLY BUT
+THIS IS YOUR PROBLEM.  I HAVE MADE SURE THAT THE DOCUMENT IS HERE AS THE
+PROGRAM WILL NOT START WITHOUT IT.  YOU CANNOT SAY THE DOCUMENT WAS NOT
+SUPPLIED TO YOU, SO I SUGGEST YOU READ IT.

BSHPCFG.BIN

Binary file added.
+#ifndef __INC_BSHIPS_H
+#define __INC_BSHIPS_H
+
+#include "Headers\PathHdlr.h"
+#include "Stds\CBoolean.H"
+/*
+  -------------------------------
+  | BSHIPS MAIN HEADER          |
+  | by David Duncan Ross Palmer |
+  | Copyright 1998 Daybo Logic  |
+  -------------------------------
+*/
+
+// VERSION
+#define BSHIPS_VER_STR "1.00"
+#define BSHIPS_VER_NUM 1
+#define BSHIPS_BUILD_STR "1.00.000 D [Development - NOT FOR RELEASE]"
+
+// MAIN RETURN VALUES
+#define MAINRET_MISSING_ESSENTIAL_FILES 1 // Missing essential files, such as the graphics driver.
+#define MAINRET_CHIP_INSUFFICIENT 2 // One or more hardware chips not good enough for the software.
+#define MAINRET_PIRATE_COPY 3 // Pirate copy, license not found or modified one found
+#define MAINRET_INIT_FAIL 4 // Game initialization failure
+#define MAINRET_CORRUPT_PACKAGE 5 // One or more distributed end-files are corrupt
+#define MAINRET_INSUFFICIENT_MEM 6 // Not enough memory to run program smoothly
+
+// functions private to the main CPP
+void MissingFileError(SDOS_FILENAME* NEFile); // Print a missing file statement
+inline BOOL PrimEssFileChk(void); // Primary essential file check
+void DispParameters(void); // Display valid parameters (command-line help)
+BOOL VerifyLicenseAgreement(void);
+BOOL InitGame(void); // Main game initialization routine
+BOOL VerifyIntegralFiles(); // CRC checks for all small essential external files
+BOOL ProcessorTest(void); // Test CPU because I want a 386 and nothing less
+void StdAbortMsg(void); // Standard "* PRESS ANY KEY TO ABORT *" message
+void InitApp(void); // DO NOT CALL THIS FUNCTION
+void UninitApp(void); // DO NOT CALL THIS FUNCTION
+
+#include "BGlobals.h" // Allow access to the global stuff
+
+#endif // __INC_BSHIPS_H
+The .INI file manager for DOS (the class that controls the .INI file has not
+yet been finished by Overlord, until it has, please use BShpCfg.BIN, the
+fixed structure of which is documented and maintanied wihin 'Configs.h'.
+
+The signature of the .BIN format (the first WORD of the file) is 0x2B2C
+or as it appears in the file because of the little endian format:
+0x2C 0x2B
+#ifndef __INC_CONFIGS_H
+#define __INC_CONFIGS_H
+
+#include "Headers\PieCrust.h"
+
+#define BIN_FILE "BShpCfg.BIN"
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+namespace Configs
+{
+#endif
+	typedef struct /* BINs header for config data (CFG_BIN_HEADER) */
+	{
+		char FileIDStr[45]; /* Contains a description of the file */
+		unsigned short Signature; /* Must be 0x2B 0x2C */
+		unsigned short Version; /* The prog. ver. that last updated the header */
+		unsigned long OffsetWordHeader; /* Offset to the WORD header */
+		unsigned long OffsetDWordHeader; /* Offset to the DWORD header */
+		unsigned long OffsetStringHeader; /* Offset to the string header */
+	}CFG_BIN_HEADER;
+
+	typedef struct /* BINs num header for storing numbers (CFG_BIN_NUMHEADER) */
+	{
+		unsigned long OffsetTable; /* Offset to the atual data */
+		unsigned long Entries; /* Number of entries in the table */
+	}CFG_BIN_NUMHEADER;
+
+	typedef struct /* BINs string header for storing strings (CFG_BIN_STRHEADER) */
+	{
+		unsigned long OffsetStrInfTable; /* The address of the string info. table */
+		unsigned long Entries; /* Number of entries in the either table */
+	}CFG_BIN_STRHEADER;
+
+	typedef struct /* BINs String info structure, each entry in the string info table is one of these */
+	{
+		unsigned long OffsetStr; /* The offset of the specific string from the start of the string table */
+		unsigned long LengthStr; /* The length of that specific string */
+	}CFG_BIN_STRINFO;
+
+	#ifdef __NO_NAMESPACES__
+	class TCfgBin : public TAbsBase
+	#else
+	class TCfgBin : public PieCrust::TAbsBase /* Manages the CfgBin (configuration binary data) */
+	#endif
+	{
+	private: /* section empty */
+			int Hcfg; /* File handle for the open file */
+			char* CurrentFilename; /* Stores a COPY of the filename */
+			BOOL OpenFlag; /* Describes the state of the file open/closed */
+		void ReadHeader(void); /* Transfer file header to structure */
+		void WriteHeader(void); /* Transfer structure to file header */
+	public:
+		/* 'structors */
+		TCfgBin(void); /* Constructor */
+		~TCfgBin(void); /* Destructor */
+		/* CMFs for the class user */
+		BOOL SetFilename(char* NewFilename); /* Sets the member 'CurrentFilename' (copies from caller's stack) */
+		char* GetFilename(void); /* Returns a pointer to the member 'CurrentFilename' */
+		void ClearFilename(void); /* Destroys the 'CurrentFilename' member */
+		int Open(void); /* Opens the filename stored in the member 'CurrentFilename' */
+		BOOL Close(void); /* Closes the filename stored in 'CurrentFilename' */
+		BOOL IsOpen(void); /* Returns OpenFlag, so caller can see but not modify the status of this flag */
+		int GetFileHandle(void); /* Gives the caller Hcfg incase he did not collect it at Open() */
+		BOOL ValidateSignature(void); /* Validates the signature and returns true/false depending whether it matched, the signature is always set correctly after this call as well as other things */
+			/* Data members */
+			CFG_BIN_HEADER* Header; /* Maintains the header contents */
+	}; /* end of TCfgBin */
+#ifndef __NO_NAMESPACES__
+} /* namespace Configs */
+#endif
+//------------------------------------------------------------------------------
+#endif /* __INC_CONFIGS_H */
+#ifndef __INC_DRAWGAME_H
+#define __INC_DRAWGAME_H // Sentry
+
+#include "Headers\VPoint.h" // for COORD_XY type
+#include "Headers\DOSgrids.H" // for using DOS grids (TGrid)
+#include "Headers\PieCrust.h"
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+namespace ScreenComponents
+{
+#endif
+	#ifdef __NO_NAMESPACES__
+	class TGridLabels : public TAbsBase
+	#else
+	class TGridLabels : public PieCrust::TAbsBase // Labeling for the grid, specific for this game
+	#endif
+	{
+	private:
+			int LabelBeginX; // for storing values so I can erase the text when the object is destroyed
+			int LabelBeginY; // " "
+			int Spacing; // Used to space letters evenly (in pixels)
+	public:
+		TGridLabels(int InitX, int InitY, int InitSpacing); // Constructor
+		TGridLabels(COORD_XY* InitCoord, int InitSpacing); // Alternative constructor
+		~TGridLabels(void); // Destructor
+		void Refresh(void); // Refresh the labels incase they are overwritten
+	}; // class TGridLabels
+
+	#ifdef __NO_NAMESPACES__
+	class TGridCell : public TAbsBase
+	#else
+	class TGridCell : public PieCrust::TAbsBase// Manages cell clearing and the like
+	#endif
+	{
+	private:
+			COORD_XY* GridArrayPos; // Where this cell is in it's grid owner
+	public:
+			int Spacing;
+		/* structors */
+		TGridCell(COORD_XY* InitGridArrayPos); // constructor
+		TGridCell(int InitGridArrayPosX,int InitGridArrayPosY); // alternative constructor
+		~TGridCell(void); // Destructor
+
+		/* functions for outsiders to call  - Getters & Setters*/
+		void SetGridArrayPos(COORD_XY* NewGridArrayPos);
+		void SetGridArrayPos(int NewGridArrayPosX,int NewGridArrayPosY);
+		COORD_XY* GetGridArrayPos(void);
+		int GetGridArrayPosX(void);
+		int GetGridArrayPosY(void);
+		/* function for outsiders to call  - Draw control */
+		void Erase(void); // Clears the contents of the cell without damaging the borders
+	}; // class TGridCell
+
+	class TBShipsGrid : public TGrid // A grid specific to Bships derived from the generic TGrid for graphics mode
+	{
+	private:
+	// (no declarations)
+	public:
+			TGridCell* GridCell[10][10]; // Cell control for all the cells
+		TBShipsGrid(void); // Constructor
+		~TBShipsGrid(void); // Destructor
+	}; // TBShipsGrid
+
+	#ifdef __NO_NAMESPACES__
+	class TStatusBar : public TAbsBase
+	#else
+	class TStatusBar : public PieCrust::TAbsBase // Controls a status bar on a graphics screen
+	#endif
+	{
+	private:
+			int CurrentDrawColor;
+			int CurrentBackColor;
+			int Height; // Calculate top by : getmaxy() - Height
+			char* Caption; // Text that appears on the statusbar
+		void CleanInterior(void);
+	public:
+		TStatusBar(void); // Constructor
+		TStatusBar(BOOL InitialDrawStyle, const char* InitialCaption = 0); // another constructor
+		~TStatusBar(void); // Destructor
+
+		void SetDrawColor(int DrawColor);
+		inline int GetDrawColor(void);
+		void SetBackColor(int BackColor);
+		inline int GetBackColor(void);
+		void SetHeight(int NewHeight);
+		inline int GetHeight(void);
+		void SetCaption(const char* NewCaption);
+		char* GetCaption(void);
+		unsigned int ReadCaption(char* TransBuf, unsigned int MaxLen);
+		inline BOOL ClearCaption(void); // Zeros pointer (after checks and releases)
+		inline unsigned int GetCaptionLength(void);
+		void Refresh(void);
+		void Erase(void);
+		BOOL AutoRefresh;
+	}; // class TStatusBar
+
+	#ifdef __NO_NAMESPACES__
+	class TScreenComponents : public TAbsBase
+	#else
+	class TScreenComponents : public PieCrust::TAbsBase
+	#endif
+	{
+	public:
+		TScreenComponents(void); // Constructor
+		~TScreenComponents(void); // Destructor
+			TStatusBar* StatusBar; // A status bar at the bottom of the graphics screen
+	};
+#ifndef __NO_NAMESPACES__
+} // end namespace ScreenComponents
+#endif
+//------------------------------------------------------------------------------
+#endif // __INC_DRAWGAME_H - Header declaration
+#ifndef __INC_GAMECODE_H
+#define __INC_GAMECODE_H // Sentry
+//------------------------------------------------------------------------------
+#include "Headers\PieCrust.h"
+#include "DrawGame.h" // for misc. drawing classes
+
+enum TDirection
+{
+   dirHorizontal,
+   dirVertical
+};
+
+typedef struct /* S_SHIP */
+{
+	int X_StartShip; // Where the ship X starts
+   int Y_StartShip; // Where the ship Y starts
+   int Length; // How long the ship is, 0 for only current block
+   TDirection; // Can be dirHorizontal or dirVertical
+} S_SHIP;
+
+#ifdef __NO_NAMESPACES__
+class TPlayer : public TAbsBase
+#else
+class TPlayer : public PieCrust::TAbsBase// A player using the game
+#endif
+{
+private:
+		char* Name;
+		int NumShips; // The number of ships the player has on the board
+	S_SHIP* ShipNum1;
+// The ships this player has (five)
+		S_SHIP* ShipNum2;
+		S_SHIP* ShipNum3;
+		S_SHIP* ShipNum4;
+		S_SHIP* ShipNum5;
+public:
+	TPlayer(const char* TheirName); // Constructor
+	~TPlayer(void); // Destructor
+	void ReadInitialShipPos(const int PlayerNum, const int ShipNum);
+	void WriteName(const char* PlyrName, int LengthOfName); // To set the player's name
+	const char* ReadName(void); // To recover the player's name
+	inline void ClearName(void); // Frees all mem. for name storage
+		int* GridCells[10]; // Will be made to point to the dynamic 2D array
+};
+//------------------------------------------------------------------------------
+#ifdef __NO_NAMESPACES__
+class TGame : public TAbsBase
+#else
+class TGame : public PieCrust::TAbsBase// A class that controls a game
+#endif
+{
+private:
+public:
+	TGame(const char* Plyr1Name, const char* Plyr2Name); // Constructor
+	~TGame(void); // Destructor
+   void Run(void); // Main execution routine for the game logic
+   	TPlayer* Player1; // A player 1 (not yet alloced.)
+		TPlayer* Player2; // and a player 2 (not yet alloced.)
+		#ifdef __NO_NAMESPACES__
+		TScreenComponents* ScreenComponents;
+		#else
+		ScreenComponents::TScreenComponents* ScreenComponents; // Class containing screen components
+      #endif
+};
+//------------------------------------------------------------------------------
+#endif // __INC_GAMECODE_H
+#ifndef __INC_GAMEMENU_H
+#define __INC_GAMEMENU_H
+//------------------------------------------------------------------------------
+#include "Headers\VCirc.h" // for TCircle class
+#include "Headers\PieCrust.h"
+//------------------------------------------------------------------------------
+/* BShips "New style" game menu" class */
+class TCoolFont // Font manager for TGameMenu
+{
+private:
+	textsettingstype* TextSettings; // Structure for storing font info.
+public:
+		TCoolFont(void); // Constructor
+		~TCoolFont(void); // Destructor
+		void SetCoolFont(BOOL FontSwitch, int FontName); // For setting the font or switching it off, use ON & OFF
+};
+
+
+class TGameMenu : public
+#ifndef __NO_NAMESPACES__
+PieCrust::
+#endif
+TAbsBase
+{
+private:
+	char* ItemText[10]; // Space for storing menu texts
+	BOOL (*ItemHandler[10])(void); // Space for item handlers
+   int SelectionMarkerLine; // Line that selection marker is on
+   int Selection; // The current selected item
+   TCircle* LeftSelectionMarker; // The class for the circle (the selection marker)
+   TCircle* RightSelectionMarker;
+   TCoolFont* CoolFont; // class for managing fonts (for use with TGameMenu)
+   	int GetNumItems(void); // Used internally for calculating the number of items to display
+      void PutSelectionMarker(int NewMarkerIndex);
+public:
+	BOOL AllowEsc; // set to false if user cannot use [ESC] to return to a previous menu
+	BOOL AutoRefresh; // Set to true if when text items change Refresh() should be called automatically
+		TGameMenu(void); // Constructor
+		~TGameMenu(void); // Destructor
+		int SetItemText(int ItemEntry, const char* NewItemText); // Sets the text message of a menu item
+   	void ClearItemText(int ItemEntry); // Clear entry (if allocated)
+   	void ClearText(void); // Clears all the text in the menu
+   	void EraseHandler(int HandlerIndex); // Sets the pointer to a handler to zero
+   	BOOL SetHandler(int HandlerIndex, BOOL(*ItemHdlr)(void)); // Sets up a handler for a selection, returns false if the handler is already set
+   	void Reset(void); // Resets the entire menu by clearing all texts and pointers to handlers
+   	void Refresh(void); // Displays/redisplays menu on screen
+   	int ReadSelection(int DefaultSelection = 1); // Main func., menu takes control and returns the used selection, returns -1 if menu was aborted
+};
+
+#define GAMEMENU_INDEX_OUT_OF_BOUNDS 1
+#define GAMEMENU_ALREADY_ALLOCED     2
+#define GAMEMENU_INSUFFICIENT_MEM    3
+#define GAMEMENU_MAXITEMS				 10
+
+#ifndef ON
+	#define ON TRUE
+#endif
+#ifndef OFF
+	#define OFF FALSE
+#endif
+//------------------------------------------------------------------------------
+#endif // __INC_GAMEMENU_H
+#ifndef __INC_LOGOS_H
+#define __INC_LOGOS_H
+
+/* Access to logo functions in LOGOS.OBJ */
+
+extern BOOL LOGO_ExecuteLogo(const char* LogoExecutableName); // Main call for displaying an executable logo
+BOOL LOGO_CRCVerify(int PredefinedID); // Routine to verify CRCs of logos
+extern BOOL LOGO_ExecuteScreen(const char* ScreenExecutableName); // Call this to not wait for a logo, wait for a keypress instead
+
+// Logo IDs
+#define LOGO_DLLGO256ID 0
+#define LOGO_BSHPLGOID 1
+
+#endif // __INC_LOGOS_H
+#include <graphics.h> // BGI
+#include <iostream.h> // cout/cin etc.
+#include <String.H> // For strcmp()
+#include "Stds\DLStdInc.H"
+#pragma hdrstop
+
+#include "BGlobals.h" // Access to all global shtick!
+#include "DOSWL\DosWin.h" // TDOSWindow class
+#include "Headers\ExtKeys.H" // Keys (keyboard input) symbolic constants
+#include "Logos.h" // Access to LOGO_...() functions
+#include "GameCode.H" // Code to run the game
+#include "MenuHand.h"
+
+/* Handlers for TGameMenu */
+//------------------------------------------------------------------------------
+BOOL GAMEMENU_ExitHandler()
+{
+	_MenuCommand = _MENUCOMMAND_TERMINATE; // Suggest the caller should terminate, this is, after all an exit routine
+	return TRUE; // Yes, the main menu can disappear
+}
+//------------------------------------------------------------------------------
+BOOL GAMEMENU_HelpHandler()
+{
+	int GMode = getgraphmode(); // Store the current graphics mode
+	restorecrtmode(); // Goto text mode for execution
+	cout << "WAIT...";
+
+	LOGO_ExecuteScreen("BHELP.SCN"); // Display the help screen
+
+	setgraphmode(GMode); // Restore old graphics mode
+
+	_MenuCommand = _MENUCOMMAND_SAFE; // It's safe, man!
+	return FALSE; // Menu should reappear
+}
+//------------------------------------------------------------------------------
+BOOL GAMEMENU_NewGameHandler()
+{
+	clrscr(); // Get rid of the damn menu
+
+	/* Let's get the names */
+	char* Player1Name = new char[128];
+	char* Player2Name = new char[128];
+	for (int i=1;i<3;i++)
+	{
+		cout << "Enter player " << i << "'s name: ";
+		if (i == 1)
+		{
+			cin >> Player1Name;
+		}
+		else
+		{
+			cin >> Player2Name;
+		}
+	}
+	if (strcmp(Player1Name, Player2Name) == 0)
+	{
+		cout << "What!  You both have the same name?  Bloody schmucks!\n";
+		cout << "PRESS ANY KEY TO CONTINUE";
+		getch();
+	}
+	clrscr(); // Get rid of the name prompts
+	TGame* Game = new TGame(Player1Name, Player2Name); // Create a new game
+	delete[] Player1Name; delete[] Player2Name; // Don't need these TPlayer's now have their pwn copies
+	Game->Run(); // Execute a game
+	delete Game; // The game has most certainly gone now!
+
+	_MenuCommand = _MENUCOMMAND_SAFE; // It's safe, man!
+	return FALSE; // Menu should reappear
+}
+//------------------------------------------------------------------------------
+#ifndef __INC_MENUHANDLERS_H
+#define __INC_MENUHANDLERS_H
+/* Handlers for the TGameMenu class (header) */
+//------------------------------------------------------------------------------
+extern BOOL GAMEMENU_ExitHandler(void);
+extern BOOL GAMEMENU_HelpHandler(void);
+extern BOOL GAMEMENU_NewGameHandler(void);
+//------------------------------------------------------------------------------
+#endif // __INC_MENUHANDLERS_H
+Packing List for BShips 1.00
+----------------------------
+PACKLIST.TXT - This file, the packing list
+BSHIPS.TXT - The license agreement
+!GETPROC.COM - External processor detection logic by Michael Tischer
+BSHIPS.EXE - BShips main executable file, run this
+EGAVGA.BGX - Borland protected mode Graphics Driver
+BSHPLGO.LGO - BShips loading logo
+BOLD.CHR - Borland Bold Character Font
+BHELP.SCN - BShips help screen
+BSHPCFG.INI - Initial configuration file
+DLLGO256.LGO - Daybo Logic logo
+DPMI16BI.OVL - Borland DOS 16-bit Protected Mode support
+RTM.EXE - Borland DOS 16-bit Protected Mode Run-time Machine
+BGI16.DLL - Borland protected mode Graphics Interface
+
+DO NOT ATTEPT TO DELETE ANY OF THESE FILE
+-----------------------------------------
+If you do BShips may not load, either because it refuses or in the case
+of deleting any of the protected mode support facilities it will never
+get the chance to load.
+
+BShips (C) 1998, Overlord D.D.R. Palmer, Daybo Logic, all rights reserved.
+Readme for BShips by Overlord David Duncan Ross Palmer
+------------------------------------------------------
+This game is dedicated to the original concept: Belinda Philips
+
+Credits:
+        Overlord - Myself, for bothering to write the game in C++.
+        Michael Tischer & Bruno Jennrich - For their processor test assembly module.
+        Borland International - For the compiler/linker, RTL, startup code, BGI, BOLD stroked
+				font and EGAVGA device driver.
+
+Greetings to:
+                Andrew Bonner - A football mad mate who gives his greetings
+                                to:
+                                        Andy Cole - He wears No.9 shirt
+                                        Jo - A babe who should go out with
+                                        Andrew.
+                Neil Abbott - My cousin, a good alliance of coding.
+                Stevie Nicks - I think you are georgeous and talented.
+
+
+ERRORS
+------
+If the game does not load because of errors, here's some of the things that
+might go wrong and why:
+
+Graphics errors
+---------------
+These usually occur if an essential driver or font file is lost, in the case
+of this game if the font files are lost the game will still run but the
+normally cool fonts that are used are not there, just plain text.  However
+loss of the the protected mode driver for EGAVGA mode will result in the
+game not loading.  If this happens re-install the game.
+
+If you are really short on memory perhaps a graphics error will occur but
+I think I have trapped this so you will be warned earlier in the init.
+routine.
+
+If you do not have the hardware to operate in a specific graphics mode
+I can assume that you should upgrade!
+
+DPMI16 errors
+-------------
+This game runs in DPMI, (DOS Protected Mode Interface), 16-bit.  I won't
+discuss the details of how this works here because unless you are a
+programmer it will be meaningless.  You need at least a 80386 to run this
+game, although 80286 operation is possible in 16-bit protected mode
+this game contains 80386 instructions and therefore would crash on
+an 80286 machine (unless my processor detection logic gets there first and
+safely terminates the program).  There are lots of different DPMI errors,
+the ones that the user would understand have simple instructions on what to
+do when the DOS extender terminates.  Some of the errors that are very
+simple are explained here in brief:
+
+Stub error (2002): Can't find rtm.exe
+-------------------------------------
+Which means you are running BSHIPS from the wrong directory or you
+have accidently deleted RTM.EXE, which is a DOS extender and the program
+cannot be executed without this as it is build around this DOS extender.
+The DOS extender should be in the directory so protected mode run-time
+may be so.
+
+Stub error (2003): can't find dpmi16bi.ovl
+------------------------------------------
+The DOS Protected Mode Run-Time Overlay is required to switch into protected
+mode.  The program runs in protected mode so nothing can happen without
+this switch.
+
+BShips is 16-bit
+
+Some common 32-bit protected mode mistakes
+------------------------------------------
+You must have an extended memory manager installed (resident) like HIMEM.SYS
+otherwise the overlay cannot be initialized.
+
+Your XMS driver (like HIMEM.SYS) must support DPMI/VCPI.  The Borland
+DOS extender is built around the DPMI API, so when a protected mode
+memory or other request is made it expectes to use this method of talking
+to the XMS manager etc.  If you get an error moaning about the XMS manager
+not supporting this interface you must upgrade the driver before you run
+the game.
+;Assembly routines to link into BSHIPS
+;-------------------------------------
+.386p
+.MODEL large
+
+PUBLIC _ApcVgaRs ;Reset display to standard VGA resolution
+
+.CODE
+
+_ApcVgaRs PROC FAR
+	push bp
+   mov bp,sp
+
+	push ax 			;I'm going to use this, so I'll save it
+   mov ah, 00h 	; Going to call function 0x00
+   mov al, 03h 	;Set to video mode three (VGA textmode)
+   int 10h 			;Call graphics card to change it
+   pop ax 			;Restore changed register for caller
+
+   pop bp
+   ret
+_ApcVgaRs ENDP
+
+END
+/* BSHIPS GLOBAL DATA & FUNCTIONS STORAGE */
+#include <conio.h>
+#include <dos.h>
+#include "Stds\DLStdInc.H"
+
+#pragma hdrstop
+#include "BGlobals.h" // Declare dontents
+#include "Configs.H"
+//------------------------------------------------------------------------------
+// (global data)
+BOOL _OverlordDebug = FALSE; // by default (related to /overlord switch)
+BOOL _InitStepDebug = FALSE; // by default (related to /initstep switch)
+unsigned int _MenuCommand = 0x0000; // this is a condition command that the caller of a menu uses when it disappears, it allows handlers to communicate with it's caller
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin* _CfgBin = (TCfgBin*)NULL; // zero pointer to start with (InitApp) creates on heap
+TGame* _GamePtr = NULL; // A global pointer to the game for external access
+//------------------------------------------------------------------------------
+void DispWarnLine(const char* Warning, int OldTextColor)
+{
+	textcolor(RED + BLINK);
+   cputs("Warning! ");
+   textcolor(RED);
+   cputs(Warning);
+   cputs("\r\n");
+   textcolor(OldTextColor);
+   for (int i=0;i<3;i++)
+   {
+   	sound(3000);
+      sleep(1);
+      nosound();
+      sleep(2);
+   }
+}
+//------------------------------------------------------------------------------
+/*
+  ------------------------------------------
+  | BSHIPS MAIN SOURCE WITH START PROCEDURE |
+  | by David Duncan Ross Palmer             |
+  | Copyright 1998 Daybo Logic              |
+  -------------------------------------------
+*/
+
+#include <dos.h> // sleep, sound etc.
+#include <string.h> // string manipulation functions (char management)
+#include <iostream.h> // I/O stream for cout
+#include <conio.h> // Console control functions
+#include <graphics.h> // This a graphics-mode game
+#include <process.h> // spawnl()
+#include <alloc.h> // Heap allocation funcrions
+#include <stdio.h> // for perror
+#include <Malloc.h> // for stackavail()
+#include "Stds\DLStdInc.H"
+
+#pragma hdrstop // Stop compiling pre-compiled headers
+#include "Headers\ANSISFnc.h" // for CheckFileExistance() & CalcCRC
+#include "Headers\PathHdlr.h" // Used for path functions and SDOSFileName
+#include "DOSWL\doswin.h" // The DOS windowing class
+#include "Logos.h" // Logo control and access
+#include "BGlobals.h" // All app-related global data 'n' func.s
+#include "GameMenu.h" // Header for the new-style game menu class
+#include "MenuHand.H" // Handlers for the TGameMenu class
+#include "BIni.h" // Access to .INI procedures for game
+#include "Configs.h" // Access to binary configuration data
+#include "Headers\Procca.h" // For processor test (DO NOT CALL getproc() or getco() that this declared, for symbolic const.s only!
+#include "BShips.h" // Main program header
+#ifndef __FLAT__
+#	include "AsmRout.h" // Asm routines
+#endif /*!__FLAT__*/
+#ifdef __DPMI16__
+#include "..\DOS16M.H" // DOS16M support functions (just the banner I expect)
+#endif /*__DPMI16__*/
+#include "Headers\TimeDLay.H" // Time delay multi-OS sleep support
+
+#pragma startup InitApp
+#pragma exit UninitApp
+//------------------------------------------------------------------------------
+/* (NON-SHARED GLOBALS PRIVATE TO MODULE !ONLY!) */
+#ifndef __NO_NAMESPACES__
+using namespace SmallFuncs;
+#endif
+
+//------------------------------------------------------------------------------
+int main(int argc, char* argv[])
+{
+	#ifdef __DPMI16__
+	DOS16M_Banner();
+	DelaySecs(3); // Wait 3 secs so user can see prot mode msg
+	#endif /*__DPMI16__*/
+
+	#ifdef __FLAT__
+	clrscr(); // Clear the screen
+	#else
+	ApcVgaRs(); // Reset VGA video
+	#endif /*__FLAT__*/
+	gotoxy(1,1);
+	textbackground(GREEN);
+	textcolor(BLACK);
+	cputs("     BShips "); cputs(BSHIPS_VER_STR); cputs(" by Overlord David Duncan Ross Palmer, (C)1998 Daybo Logic     \r\n");
+	textbackground(BLACK);
+	textcolor(WHITE);
+	gotoxy(1,2); // Just blow the title over the line overflow caused by the cputs above
+	BOOL GoodParams = FALSE; // Used to tell if recognised params. have been entered from the command-line
+	if (argc > 1)
+   {
+   	for (int ParamCyc=1;ParamCyc<argc;ParamCyc++)
+   	{
+   		/* check passed parameters */
+      	if (strcmpi(argv[ParamCyc], "/?") == 0 || strcmpi(argv[ParamCyc], "-?") == 0 || strcmpi(argv[ParamCyc], "-H") == 0 || strcmpi(argv[ParamCyc], "?") == 0) // get help
+      	{
+      		DispParameters();
+         	return 0; // Normal termination
+      	}
+      	if (strcmpi(argv[ParamCyc], "/B") == 0) // Display software build number
+			{
+				cout << "BShips build " << BSHIPS_BUILD_STR << endl;
+				cout << "Built: " << __DATE__ << " - " << __TIME__ << endl;
+         	cout << endl;
+         	cout << "BShips by Overlord David Duncan Ross Palmer of Daybo Logic.\n";
+         	return 0; // Normal termination
+      	}
+         #ifdef __BSHIPS_DEVELOPMENT // Only include the following code if game is still in development
+      	if (strcmpi(argv[ParamCyc], "/OVERLORD") == 0) // Programmer's debug mode (undocumented switch)
+      	{
+      		textbackground(RED);
+      		cputs("<< PROGRAMMER'S TRAPDOOR DEBUGGING MODE >>\r\n");
+         	textbackground(BLACK);
+         	sleep(1); // So I can see it's in trapdoor Overlord mode
+         	_OverlordDebug = TRUE;
+         	if (!GoodParams)
+         		GoodParams = TRUE; // Don't display inv. params. msg.
+      	}
+         #endif // __BSHIPS_DEVELOPMENT
+			if (strcmpi(argv[ParamCyc], "/INITSTEP") == 0) // Step through init. routine
+			{
+      		textbackground(RED);
+         	cputs("<< INITIALIZATION STEP MODE >>\r\n");
+         	textbackground(BLACK);
+         	sleep(1);
+         	_InitStepDebug = TRUE;
+         	if (!GoodParams)
+         		GoodParams = TRUE; // Don't disp. inv. params. msg.
+			}
+			/* >> INSERT MORE PARAMETER HANDLERS HERE */
+			/* At this point, a parameter has been entered but not recognised,
+			unless the 'GoodParams' flag has been set */
+			if (!GoodParams)
+			{
+				cout << "ERROR: Invalid parameter!\n\n";
+				DispParameters();
+				return 0; // Normal termination
+			}
+		} // the for loop
+	} // (argc > 1)
+	cout << "Processor operating mode: ";
+	#if defined (__DPMI16__) || defined (__DPMI32__) || defined (__WIN32__) // In a protected mode?
+	cout << "PROTECTED"; // Output mesaage to state protected mode
+	#else // In a real mode
+	cout << "REAL"; // Output message to state real mode
+	#endif /*__DPMI__*/
+	cout << endl; // End the line of the comment above
+	if (_InitStepDebug) getch();
+	cout << "Program instruction size: ";
+	#if !defined (__DPMI32__) && !defined (__WIN32__) // Not a 32-bit platform
+	cout << "16"; // Say 16-bit
+	#else // 32-bit?
+	cout << "32"; // Say 32-bit
+	#endif
+	cout << "-bit\n"; // Finish off qualifier to 16/32 ie 16-bit so it looks nice
+	if (_InitStepDebug) getch();
+	cout << "Address space: "; // About to state address space
+	#if !defined(__DPMI32__) && !defined(__DPMI16__) && !defined(__WIN32__) // Real mode?
+	cout << "640 Kb";
+	#elif !defined(__DPMI32__) && !defined(__WIN32__) // 16-bit prot mode?
+	cout << "16 Megs";
+	#else // 32-bit prot mode?
+	cout << "4 Gigs";
+	#endif
+	cout << endl; // End statement
+	if (_InitStepDebug) getch();
+	#ifndef __FLAT__
+	cout << "Total program stack: ";
+	if (_stklen)
+		cout << "0x" << hex << _stklen << " (" << dec << _stklen << ") bytes (" << _stklen / 1024 << "K).\n";
+	else
+		cout << "NONE\n";
+	if (_InitStepDebug) getch();
+	#endif /*__FLAT__*/
+	cout << "Available program stack: ";
+	if (stackavail())
+		cout << "0x" << hex << stackavail() << " (" << dec << stackavail() << ") bytes (" << stackavail() / 1024 << "K).\n";
+	else
+		cout << "NONE\n";
+	if (_InitStepDebug) getch();
+	#ifndef __FLAT__
+	cout << "Total program heap: ";
+	if (_heaplen)
+		cout << "0x" << hex << _heaplen << " (" << dec << _heaplen << ") bytes (" << _heaplen / 1024 << "K).\n";
+	else
+		cout << "NONE\n";
+	if (_InitStepDebug) getch();
+   #endif /*__FLAT__*/
+	unsigned long FarCoreRemaining = farcoreleft(); // Read the number of bytes of far core left
+	cout << "Far core remaining: ";
+	if (FarCoreRemaining)
+		cout << "0x" << hex << FarCoreRemaining / 16 << " (" << dec << FarCoreRemaining / 16 << ") paragraphs.\n";
+	else
+		cout << "NONE\n";
+	if (_InitStepDebug) getch();
+	if (FarCoreRemaining / 16 < 0x1000)
+	{
+		cout << "Error: Sorry but you need at least 0x1000 paragraphs of far core to run this\nprogram properly so that all elements can be loaded.\n";
+		StdAbortMsg();
+		return MAINRET_INSUFFICIENT_MEM; // Terminate with this error number
+	}
+	cout << "Heap ";
+	switch (heapcheck()) // Check the heap
+	{
+		case _HEAPCORRUPT :
+		{
+			cout << "is corrupt!\n";
+			StdAbortMsg();
+			abort();
+		}
+		case _HEAPEMPTY :
+		{
+			cout << "is empty, verified.\n";
+			break;
+		}
+		case _HEAPOK :
+		{
+			cout << "verified.\n";
+			break;
+		}
+		default :
+		{
+			cout << "verification error!\n";
+			StdAbortMsg();
+			abort();
+		}
+	} // switch (heapcheck())
+	if (_InitStepDebug) getch();
+	cout << "Primary file check.\n";
+	if (!PrimEssFileChk()) // Check all the essential files
+	{
+		StdAbortMsg();
+		return MAINRET_MISSING_ESSENTIAL_FILES; // terminate with exit code
+	}
+	if (_InitStepDebug) getch();
+	if (!ProcessorTest()) // Test the CPU
+		return MAINRET_CHIP_INSUFFICIENT; // Terminate!
+	if (_InitStepDebug) getch();
+	if (!_OverlordDebug)
+	{
+		if (!VerifyLicenseAgreement())
+   		return MAINRET_PIRATE_COPY;
+      if (_InitStepDebug) getch();
+		if (!VerifyIntegralFiles())
+   		return MAINRET_CORRUPT_PACKAGE;
+   }
+   else
+   {
+   	cout << "Overlord skips CRC procedures to save development time.\n";
+   }
+   if (_InitStepDebug) getch();
+   // Get the .INI file statistics
+   cout << ".INI support API not completed: using .BIN configuration format instead\n";
+   if (_InitStepDebug) getch();
+	if (CheckFileExistance(INI_FILE))
+   {
+   	TDIniFile* INI = new TDIniFile();
+   	unsigned long NumLines = INI->CountLines(INI_FILE);
+      delete INI;
+      cout << "BShpCfg.INI detected, " << NumLines << " line";
+      NumLines == 1 ? cout << "." << endl : cout << "s." << endl;
+   }
+   else
+   {
+   	cout << "BShpCfg.INI file not detected, a new one will be created.\n";
+   }
+   if (_InitStepDebug) getch();
+   if (CheckFileExistance(BIN_FILE))
+   	cout << "BShpCfg.BIN detected.\n";
+   else
+   	cout << "BShpCfg.BIN not found, a new one will be created.\n";
+	_CfgBin->SetFilename(BIN_FILE);
+   int Hcfg = _CfgBin->Open(); // attempt to open .bin
+   if (Hcfg == -1) // error
+   {
+      perror(BIN_FILE); // use errno to print msg
+   }
+   else // Opening .BIN was successful
+   {
+   	_CfgBin->ValidateSignature();
+   }
+   if (_InitStepDebug) getch();
+   cout << "Exec. title sequence.\n";
+   if (!InitGame())
+   {
+   	cout << "Game initialization failure!\n";
+      StdAbortMsg();
+      return MAINRET_INIT_FAIL;
+   }
+   if (_OverlordDebug)
+   	cout << "Game terminated by returning from main()\n";
+   else
+   	cout << "Thanks for playing BShips, goodbye!\n";
+   return 0; // normal exit
+}
+//------------------------------------------------------------------------------
+inline BOOL PrimEssFileChk(void)
+{
+	/* checks all external files that are required by the program
+   and returns FALSE if one or more files are missing */
+   SDOS_FILENAME* SDOSChkFile = new SDOS_FILENAME; // for MissingFileError
+   char* CHARChkFile = new char[12]; // for CheckFileExistance
+	unsigned int MissFileCount = 0; // increment this for every missing file and check at the end
+	#ifndef __NO_NAMESPACES__
+	using namespace SmallFuncs; // Allow access to the small functions library
+   #endif
+   // check DLLGO256.LGO
+   strcpy(SDOSChkFile->FileName, "DLLGO256");
+   strcpy(SDOSChkFile->Extension, "LGO");
+   if (!CheckFileExistance("DLLGO256.LGO"))
+   {
+   	MissFileCount++;
+      MissingFileError(SDOSChkFile);
+   }
+   // check BSHPLGO.LGO
+   strcpy(SDOSChkFile->FileName, "BSHPLGO");
+   strcpy(SDOSChkFile->Extension, "LGO");
+   if (!CheckFileExistance("BSHPLGO.LGO"))
+   {
+   	MissFileCount++;
+      MissingFileError(SDOSChkFile);
+   }
+   // check BHELP.SCN
+   strcpy(SDOSChkFile->FileName, "BHELP");
+   strcpy(SDOSChkFile->Extension, "SCN");
+   if (!CheckFileExistance("BHELP.SCN"))
+   {
+   	MissFileCount++;
+      MissingFileError(SDOSChkFile);
+   }
+   // check !GETPROC.COM
+   strcpy(SDOSChkFile->FileName, "!GETPROC");
+   strcpy(SDOSChkFile->Extension, "COM");
+   if (!CheckFileExistance("!GETPROC.COM"))
+   {
+   	MissFileCount++;
+      MissingFileError(SDOSChkFile);
+   }
+   /* -- ADD OTHER FILE CHECKS AT THIS POINT --- */
+   delete SDOSChkFile;
+   delete[] CHARChkFile; // this is an array, that's why I used delete[] !delete
+   if (MissFileCount) // is non-zero
+   {
+   	cout << "FATAL: ";
+      if (MissFileCount == 1)
+      {
+      	cout << "One essential file is";
+      }
+      else
+      {
+      	cout << MissFileCount << " essential files are";
+      }
+      cout << " missing, the program will terminate.\n";
+      return FALSE; // indicate to caller that check failed
+   }
+   return TRUE; // all files found successfully
+}
+//------------------------------------------------------------------------------
+void MissingFileError(SDOS_FILENAME* NEFile/*non-encountered file*/)
+{
+	/* Used to print missing file errors during the PrimaryEssentialFileChk() */
+   cout << "ERROR: Missing file " << NEFile->FileName << "." << NEFile->Extension << endl;
+}
+//------------------------------------------------------------------------------
+void DispParameters()
+{
+	/* Display all valid parameters */
+	cout << "/?, -?, -H or ?  Get command-line help (this)\n";
+   cout << "/B               Display software build number (very specific build)\n";
+   cout << "/INITSTEP        Step through init. routine to look for an error (debug)\n";
+}
+//------------------------------------------------------------------------------
+BOOL VerifyLicenseAgreement()
+{
+	cout << "Verifying license agreement."; // NOTE: Don't end line, will add to dots to indicate progress
+	if (!CheckFileExistance("BShips.txt"))
+	{
+		cout << "\nLicense agreement not found!\n";
+		#ifndef __NO_NAMESPACES__
+		using namespaces Doswl; // Access to my DOS windowing library
+		#endif
+		TDOSWindow* DOSWindow = new TDOSWindow(); // Prepare to show a DOS window
+		char* Line1 = new char[128];
+		char* Line2 = new char[128];
+		char* Line3 = new char[128];
+		DOSWindow->SetHeight(5);
+		strcpy(Line1, "A license agreement for BShips has not been found");
+		strcpy(Line2, "attempted software piracy or any other violations");
+      strcpy(Line3, "is illegal and prosecutions will be persued.");
+      DOSWindow->SetWidth(DOSWindow->GetExpectedWidth(Line1));
+      DOSWindow->SetBackgroundColor(RED);
+      DOSWindow->SetForegroundColor(YELLOW);
+      DOSWindow->MoveToCentre();
+      DOSWindow->Show();
+      DOSWindow->PutText(1, Line1); delete[] Line1;
+      DOSWindow->PutText(2, Line2); delete[] Line2;
+      DOSWindow->PutText(3, Line3); delete[] Line3;
+      sound(100);
+      sleep(15);
+      nosound();
+      getch();
+      delete DOSWindow;
+      return FALSE;
+   } /* (!CheckFileExistance("BShips.txt")) */
+   // Verify license agreement now
+	if (CalcFileChecksum("BShips.txt") != 0x15033L) // CRCGaugeProc is a pointer to a function that is called on every loop and should take the percent done value
+   {
+   	cout << "\nLicense agreement fails CRC check, it must have been tampered or damaged!\n";
+   	return FALSE;
+   }
+	cout << "Licence verified correctly.\n";
+	return TRUE;
+}
+//------------------------------------------------------------------------------
+BOOL InitGame()
+{
+	/* MAIN GAME INIT. PROCEDURE */
+	#ifndef __NO_NAMESPACES__
+	using namespace Doswl; // Access to my DOS windowing library
+	#endif
+
+	TDOSWindow* EntWin = new TDOSWindow();
+   EntWin->SetHeight(3);
+   char* EntMsg = new char[19];
+   strcpy(EntMsg, "ENTERING BSHIPS...");
+   EntWin->SetWidth(EntWin->GetExpectedWidth(EntMsg));
+   EntWin->SetForegroundColor(BLACK);
+   EntWin->SetBackgroundColor(GREEN);
+   EntWin->MoveToCentre();
+   EntWin->Show();
+   EntWin->PutText(1, EntMsg);
+   delete[] EntMsg;
+   if (!_OverlordDebug)
+   	sleep(3);
+
+   int VGAcpy = VGA; // Make a copy of these varibles
+   int VGAMEDcpy = VGAMED; // to get an addressable expression to send to initgraph()
+	delete EntWin; // 'ENTERING...' box destroyed
+
+   if (!_OverlordDebug)
+   {
+   	LOGO_ExecuteLogo("DLLGO256.LGO");  // Display the Daybo Logic logo
+      cout << "WAIT...";
+		LOGO_ExecuteLogo("BSHPLGO.LGO");  // Display the BShips logo
+   }
+   cout << "WAIT...";
+	initgraph(&VGAcpy, &VGAMEDcpy, ""); // Init. graphics mode int VGA 640*480   return FALSE;
+   int GraphErrCode = graphresult();
+   if (GraphErrCode != grOk)
+	{
+   	/* A graphics error has occured */
+      cout << "Graphics error: "
+      	<< grapherrormsg(GraphErrCode) << endl;
+      return FALSE; // Initialization failure, game terminates
+   }
+
+   /* MAIN INIT. GOES HERE */
+   TGameMenu* GameMainMenu = new TGameMenu;
+   /* A GameMenu object has a maximum capacity of 10 items,
+   fill five of these for the main menu. */
+   GameMainMenu->SetItemText(1, "New game");
+   GameMainMenu->SetHandler(1, GAMEMENU_NewGameHandler);
+   GameMainMenu->SetItemText(2, "Options");
+   GameMainMenu->SetItemText(3, "Load game");
+	GameMainMenu->SetItemText(4, "Save game");
+   GameMainMenu->SetItemText(5, "Help");
+   GameMainMenu->SetHandler(5, GAMEMENU_HelpHandler);
+   GameMainMenu->SetItemText(6, "Exit");
+   GameMainMenu->SetHandler(6, GAMEMENU_ExitHandler);
+   /* Set general settings for the menu */
+   GameMainMenu->AllowEsc = FALSE; // Don't allow [ESC] inturrupts
+   ReDispMainMenu: // Jump to here to get another menu choice
+   GameMainMenu->Refresh(); // This really means "show" because it wasn't already there
+   GameMainMenu->ReadSelection(); // Passes control to the menu until it returns a user selection
+   switch (_MenuCommand)
+   {
+   	case _MENUCOMMAND_TERMINATE : // Terminate the program normally
+      {
+      	break; // By breaking from the switch the function then returns TRUE and the game terminates
+      }
+      case _MENUCOMMAND_SAFE : // Ignore talkback
+      {
+			/* Jumps back to the piece of code that controls the menu, refresh it and wait for another return */
+      	goto ReDispMainMenu;
+      }
+      // Add new menu talk back commands here
+      default :
+      {
+      	cout << "Unknown MenuCommand code " << _MenuCommand << endl;
+      }
+   } // switch (MenuCommand)
+   delete GameMainMenu; // Release memory used by menu
+
+   closegraph(); // Return to text mode
+   return TRUE; // Game init. was successful
+}
+//------------------------------------------------------------------------------
+BOOL VerifyIntegralFiles()
+{
+	cout << "CRC checking Daybo Logic logo.";
+	if (LOGO_CRCVerify(LOGO_DLLGO256ID))
+	{
+		cout << "OK\n";
+		/* Note that I do not return, otherwise more checks don't work */
+	}
+	else
+	{
+		cout << "\nCRC failure!  Daybo Logic logo is corrupt.\n";
+		return FALSE;
+	}
+
+	if (_InitStepDebug) getch();
+
+	cout << "CRC checking BShips loading logo.";
+	if (LOGO_CRCVerify(LOGO_BSHPLGOID))
+	{
+		cout << "OK\n";
+		return TRUE; // The last CRC routine is the only one who may return TRUE
+	}
+	else
+	{
+		cout << "\nCRC failure!  BShips loading logo is corrupt.\n";
+		return FALSE;
+	}
+	//return FALSE; // safety
+}
+//------------------------------------------------------------------------------
+BOOL ProcessorTest()
+{
+	BOOL CPUSuff = FALSE; // Init. var to see if CPU suffices
+	switch(spawnl(P_WAIT, "!GetProc.com", "!GetProc.com", NULL))
+	{
+		case p_8086 :
+      {
+      	cout << "8086";
+         CPUSuff = FALSE; // No this processor is insufficient
+      	break;
+      }
+      case p_8088 :
+      {
+      	cout << "8088";
+         CPUSuff = FALSE; // Insufficient
+         break;
+      }
+      case p_80186 :
+      {
+      	cout << "80186";
+         CPUSuff = FALSE;
+         break;
+      }
+      case p_80286 :
+      {
+      	cout << "80286";
+         CPUSuff = FALSE;
+         break;
+      }
+      case p_80386 :
+      {
+      	cout << "80386";
+         CPUSuff = TRUE; // This is the minimum requirement
+         break;
+      }
+      case p_80486 :
+      {
+      	cout << "i486 or smarter";
+         CPUSuff = TRUE;
+         break;
+      }
+      case p_v20 :
+      {
+      	cout << "NEC V20";
+         CPUSuff = FALSE; // This processor is equivilent to the 8086
+         break;
+      }
+      case p_v30 :
+      {
+      	cout << "NEC V30";
+         CPUSuff = FALSE; // ...and so is this, not good enough
+         break;
+      }
+      case -1 :
+      {
+      	cout << "Can't do CPU test!\n";
+         exit(MAINRET_CHIP_INSUFFICIENT);
+      }
+      default :
+      {
+      	cout << "Unknown";
+         CPUSuff = FALSE; // Don't take a risk
+         break;
+      }
+   } // switch (spawnl("!GETPROC.COM"))
+   cout << " processor detected.\n"; // finish the current sentence
+   if (CPUSuff)
+   {
+   	return TRUE; // It's OK, mate!
+   }
+   else
+	{
+		#ifndef __NO_NAMESPACES__
+      using namespace Doswl;
+		#endif
+		TDOSWindow* dw = new TDOSWindow();
+   	char* Line1 = "This processor is insufficient";
+   	char* Line2 = "you need at least a 80386 to run";
+   	char* Line3 = "the game";
+   	dw->SetHeight(5);
+   	dw->SetWidth(dw->GetExpectedWidth(Line2/*it's the longest*/));
+   	dw->SetForegroundColor(WHITE);
+   	dw->SetBackgroundColor(RED);
+   	dw->MoveToCentre();
+   	dw->Show();
+   	dw->PutText(1, Line1);
+   	dw->PutText(2, Line2);
+   	dw->PutText(3, Line3);
+   	sound(1000);
+   	sleep(1);
+   	nosound();
+   	getch();
+   	delete dw;
+   	return FALSE; // Don't allow main to cont. terminate
+   }
+}
+//------------------------------------------------------------------------------
+void StdAbortMsg()
+{
+	cout << endl;
+   textcolor(YELLOW + BLINK);
+   sound(2750);
+   cputs("* PRESS ANY KEY TO ABORT *\r\n");
+   delay(100);
+   nosound();
+	getch();
+}
+//------------------------------------------------------------------------------
+void InitApp() // called before _main()
+{
+	/* Create app. global objects on the heap */
+	_CfgBin = new
+	#ifndef __NO_NAMESPACES__
+	Configs::
+   #endif
+	TCfgBin;
+}
+//------------------------------------------------------------------------------
+void UninitApp() // called after return from _main()
+{
+	delete _CfgBin; // Object's destructor ensures file is closed
+}
+//0-----------------------------------------------------------------------------
+;************************************************************************
+;*               BShips Configuration File: BSHPCFG.INI                 *
+;* original distribution copy written by Overlord D. D. R. Palmer CPPP  *
+;* ASM BASIC.  Copyright 1998, Daybo Logic, all rights reserved.        *
+;************************************************************************
+;* This file is normally modified by BShips when configuration data     *
+;* should be saved between sessions.  It is in a text format so that    *
+;* users can change some of the technical parameters, I shall explain   *
+;* the format of the file language in a minute.  Non-technical users    *
+;* must not modify this file or (as the program becomes more complex)   *
+;* BShips may not operate correctly if invalid things are set.          *
+;************************************************************************
+;* FILE FORMAT: The langauge elements used to communicate with the      *
+;* program consist of these elements:                                   *
+;*                                                                      *
+;*    ; - A comment.                                                    *
+;*        Anything following this semi-colon on a line is ignored as a  *
+;*        remark or comment as doesn't matter because the part of the   *
+;*        program that reads the .INI does not give this stuff to the   *
+;*        main program.                                                 *
+;*                                                                      *
+;*    [SectionIdentifer] - A string or numerical value that represents  *
+;*        the begining of a new section, all values must be within a    *
+;*        section or they will not be accessable to the program.        *
+;*                                                                      *
+;*    Key=Value - Key is a fixed name that the program looks for, a     *
+;*        string or numerical identifier.  Value is the value that is   *
+;*        assigned to this key.                                         *
+;************************************************************************
+
+[Options] ;User options accessable from the 'Options' menu
+ImageFade=1 ;boolean to fade in/out of image screens or not
+
+;End of configuration file
+/* Configs is temporary, maybe to reuse when the .INI manager is sorted out */
+//------------------------------------------------------------------------------
+#include <mem.h> // For the setmem function (used for zeroing structures
+#include <string.h> // String management functions
+#include <fcntl.h>
+#include <io.h>
+#include <sys\stat.h> // mode
+#include <errno.h> // Access to errno global variable
+#pragma hdrstop
+
+#include "BShips.H" // For version ino
+#include "Configs.h" /* Include the declaration of the class and related structures */
+//------------------------------------------------------------------------------
+/* The definition of the TCfgBin class */
+#ifdef __NO_NAMESPACES__
+TCfgBin::TCfgBin()
+#else
+Configs::TCfgBin::TCfgBin() // class constructor
+#endif
+{
+	// Create all dynamic stuff on the heap now...
+	Header = new CFG_BIN_HEADER;
+
+	// Initialization of members
+	setmem(Header, sizeof(*Header), 0x00); // zero this header
+	Hcfg = 0; // No file handle yet
+	CurrentFilename = 0; // Points to nothing
+	OpenFlag = FALSE; // File !open
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+Configs::TCfgBin::~TCfgBin() // class destructor
+#else
+TCfgBin::~TCfgBin()
+#endif
+{
+	/* Destructor tasks */
+	if (OpenFlag) // If a file is open
+		Close(); // Close it
+
+   // dynamic memory release
+   delete Header; // Release header (it's on the heap)
+}
+//------------------------------------------------------------------------------
+BOOL /*Return type of func */
+#ifndef __NO_NAMESPACES__
+Configs:: /* Namespace modifier */
+#endif
+TCfgBin::SetFilename(char* NewFilename)
+{
+	/* Sets the member CurrentFilename */
+   if (OpenFlag) // If this filename is already open
+   	return FALSE; // Do not allow the name to be changed
+   if (CurrentFilename) // The filename is allocated!
+   {
+   	delete[] CurrentFilename; // Release dyn. mem. array
+      CurrentFilename = 0; // Pointer is no longer valid
+   }
+   if (NewFilename) // Caller sent a new name
+   {
+   	CurrentFilename = new char[strlen(NewFilename)+1]; // Allocate just enough memory on the heap
+      strcpy(CurrentFilename, NewFilename); // Copy the filename to this address
+   }
+	return TRUE; // Successful copy, filename has changed
+}
+//------------------------------------------------------------------------------
+char* /* func return type */
+#ifndef __NO_NAMESPACES__
+Configs:: /* Namespace modifier */
+#endif
+TCfgBin::GetFilename() // Returns 'CurrentFilename'
+{
+	/* CALLERS: Please DON'T modify the contents of the memory array */
+	return CurrentFilename; // Simply give pointer
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::ClearFilename() // Wipes out 'CurrentFilename'
+{
+	/* Don't worry, all dyn. mem will be released */
+   if (CurrentFilename) // If there's anything to worry about anyway
+   {
+   	delete[] CurrentFilename; // Release memory
+      CurrentFilename = 0; // Pointer is invalid
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+BOOL
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::IsOpen()
+{
+	return OpenFlag;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::ReadHeader()
+{
+	if (OpenFlag) // The file must be open for this
+	{
+   	/* Transfer file header to structure, first seek to the begining
+   	of the file */
+      lseek(Hcfg, 0x0, SEEK_SET); // Goto file start
+      read(Hcfg, Header, sizeof(*Header)); // Read structure
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::WriteHeader()
+{
+	if (OpenFlag) // The file must be open for this
+   {
+   	/* Transfer structure to file header, first seek to the begining
+      of the file */
+      lseek(Hcfg, 0x0, SEEK_SET); // Goto file start
+      write(Hcfg, Header, sizeof(*Header)); // Write header to disk
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+BOOL
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::Close()
+{
+	/* Closes the open file (Hcfg) */
+   if (OpenFlag) // If the file is open
+   {
+   	WriteHeader(); // Update the file before closing it
+   	close(Hcfg); // Actually close the file
+      Hcfg = 0; // Zeros the handle to avoid later use
+		OpenFlag = FALSE; // Indicate the
+		return TRUE; // OK
+	}
+	return FALSE; // Failed, file was not already open
+}
+//------------------------------------------------------------------------------
+int
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::GetFileHandle()
+{
+	return Hcfg; // Give to caller
+}
+//------------------------------------------------------------------------------
+int
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::Open()
+{
+	if (CurrentFilename && !OpenFlag) // A filename is required and the previous file must be closed
+   {
+   	Hcfg = open(CurrentFilename, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
+      if (Hcfg == -1)
+      {
+      	/* An error? */
+         Hcfg = 0; // No handle
+         return -1; // Allow caller to know there's an error
+      }
+      else // No error
+      {
+      	errno = 0; // No error
+      }
+      OpenFlag = TRUE; // Remember file is open
+      ReadHeader(); // Read header into Header structure
+      return Hcfg; // Give handle to caller
+   }
+   return 0; /* Failed to open file, no handle returned but don't change
+   Hcfg because it might be a valid file handle */
+}
+//------------------------------------------------------------------------------
+BOOL
+#ifndef __NO_NAMESPACES__
+Configs::
+#endif
+TCfgBin::ValidateSignature()
+{
+	/* returns false as a warning is signature is wrong, true if it's
+	what is expected, sets to correct signatue regardless after call,
+   other information that is always the same in the header will be
+   corrected also but are not checked */
+   if (!OpenFlag) // File must be open
+   {
+   	errno = EBADF; // Bad file number
+		return FALSE; // Failed because file was not open
+   }
+
+   unsigned short CopyOfSig = Header->Signature; // Copy signature
+
+   /* Set to expected */
+   strcpy(Header->FileIDStr, "BShips binary configuration information\0x1a");
+   Header->Signature = 0x2B2C; // Set the sig. to what is expected
+   Header->Version = BSHIPS_VER_NUM; // Update version
+
+   if (CopyOfSig == 0x2B2C) // Signature is expected?
+		return TRUE; // Yes old signature was OK
+   return FALSE; // No old signature was EVIL!!
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+#include <String.h>
+#include <graphics.h>
+#pragma hdrstop
+#include "DrawGame.h"
+//------------------------------------------------------------------------------
+/* Functions & classes for drawing on-screen game components */
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridLabels::TGridLabels(int InitX, int InitY, int InitSpacing) // Constructor
+{
+   LabelBeginX = InitX;
+   LabelBeginY = InitY;
+   Spacing = InitSpacing;
+
+   Refresh(); // draws the identifiers
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridLabels::TGridLabels(COORD_XY* InitCoord, int InitSpacing) // alternative constructor (for difficult users)
+{
+   LabelBeginX = InitCoord->X;
+   LabelBeginY = InitCoord->Y;
+   Spacing = InitSpacing;
+
+   Refresh(); // draws the identifiers
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridLabels::~TGridLabels() // Destrcutor
+{
+	int OldCol = getcolor(); // What is the current drawing color?
+   setcolor(getbkcolor()); // Start drawing with the background color to erase
+   Refresh(); // Draws the grid with the bkcolor - smart way to erase
+   setcolor(OldCol); // Better set the colors to normal or the caller won't be happy!
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridLabels::Refresh()
+{
+	/* vars */
+	int HStartLab = LabelBeginY + 10;
+   int VStartLab = LabelBeginX - 10;
+   char* LabelYStr = "0123456789";
+   char* LabelXStr = "ABCDEFGHIJ";
+   char Holder[2]; // A char and a NULL for temp storage
+
+   /* code */
+   Holder[1] = *"\0"; // Put a NULL in the end of the holder
+   for (int i=0;i<10;i++) // loop through all the chars
+   {
+   	Holder[0] = LabelXStr[i]; // Put the character in the holder
+   	outtextxy(HStartLab,LabelBeginX, (const char*)Holder);
+      LabelBeginY += Spacing; // Goto pos ready for next char
+
+      Holder[0] = LabelYStr[i]; // Put the char in the holder
+   	outtextxy(LabelBeginY,VStartLab, (const char*)Holder);
+      LabelBeginX += Spacing; // Goto pos. ready for next char.
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+/******************************************************
+ * TGridCell class by Overlord, manages cell clearing *
+ * and the like, make 10^2 of these to manage 100     *
+ * cells of these in the grid - MAKE DYNAMICALLY      *
+ * AS THERE WON'T BE ENOUGH SPACE ON THE STACK.       *
+ ******************************************************/
+//-----------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::TGridCell(COORD_XY* InitGridArrayPos) // Constructor
+{
+	/* Heap allocation */
+   GridArrayPos = new COORD_XY;
+
+   /* init. */
+   GridArrayPos->X = InitGridArrayPos->X;
+   GridArrayPos->Y = InitGridArrayPos->Y;
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::TGridCell(int InitGridArrayPosX,int InitGridArrayPosY) // Alternative constructor
+{
+	/* Heap allocation */
+   GridArrayPos = new COORD_XY;
+
+   /* init. */
+   GridArrayPos->X = InitGridArrayPosX;
+   GridArrayPos->Y = InitGridArrayPosY;
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::~TGridCell() // Destructor
+{
+	/* Heap deallocation */
+	delete GridArrayPos;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::SetGridArrayPos(COORD_XY* NewGridArrayPos)
+{
+	GridArrayPos->X = NewGridArrayPos->X;
+   GridArrayPos->Y = NewGridArrayPos->Y;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::SetGridArrayPos(int NewGridArrayPosX,int NewGridArrayPosY)
+{
+	GridArrayPos->X = NewGridArrayPosX;
+   GridArrayPos->Y = NewGridArrayPosY;
+}
+//------------------------------------------------------------------------------
+COORD_XY*
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::GetGridArrayPos()
+{
+	return GridArrayPos; // CALLER: Please don't free this address
+   // or things will be SERIOUSLY BUGGERED!
+}
+//------------------------------------------------------------------------------
+int
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::GetGridArrayPosX()
+{
+	return GridArrayPos->X;
+}
+//------------------------------------------------------------------------------
+int
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::GetGridArrayPosY()
+{
+	return GridArrayPos->Y;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TGridCell::Erase() // Clears the contents of the cell without damaging the borders
+{
+	int DrawColor = getbkcolor(); // Prepare to draw with the background color to erase
+	/* erase the contents of the cell by putting pixels of the background
+   color in the inside */
+   for (int HWay=(GridArrayPos->X-1);HWay<Spacing;HWay++)
+   {
+   	for (int VWay=(GridArrayPos->Y-1);VWay<Spacing;VWay++)
+      {
+      	putpixel(HWay,VWay, DrawColor);
+      }
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+/*****************************************************
+ * TBShipsGrid class, derived from TGrid, this class *
+ * has been customised for BShips.                   *
+ *****************************************************/
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TBShipsGrid::TBShipsGrid() // Constructor
+{
+	/* Specific constructor for TBShipsGrid */
+   for (int i=0;i<10;i++)
+   {
+   	for (int j=0;j<10;j++)
+      {
+      	GridCell[i][j] = new TGridCell(  ((j+1)*CellWidth),((j+1)*CellHeight)  );
+         GridCell[i][j]->Spacing = CellHeight;
+      }
+   }
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TBShipsGrid::~TBShipsGrid() // Destructor
+{
+	/* specific destructor for TBShipsGrid */
+   for (int i=0;i<10;i++)
+   {
+   	for (int j=0;j<10;j++)
+      {
+      	delete GridCell[i][j];
+      }
+   }
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+/* TScreenComponents class contains objects on the screen */
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TScreenComponents::TScreenComponents() // Constructor
+{
+	StatusBar = new TStatusBar();
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TScreenComponents::~TScreenComponents() // Destructors
+{
+	delete StatusBar;
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+/* TStatusBar class controls the status bar */
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::TStatusBar() // Constructor
+{
+	CurrentDrawColor = WHITE; // Default draw color
+	CurrentBackColor = BLACK; // Default back color
+	Height = 20; // Default height
+	Caption = 0; // Zero the pointer
+	AutoRefresh = TRUE; // Refreshing is my job by default unless the object user changes this to false
+
+	/* Other stuff that has to be done here */
+	Refresh(); // In this constructor, AutoRefresh is always true, so don't query it
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::TStatusBar(BOOL InitialDrawStyle, const char* InitialCaption) // another constructor
+{
+	/* initialization */
+	CurrentDrawColor = WHITE; // Default draw color
+   CurrentBackColor = BLACK; // Default back color
+   Height = 20; // Default height
+   Caption = (char*)InitialCaption;
+   AutoRefresh = InitialDrawStyle;
+
+   /* Other stuff that has to be done here */
+   if (AutoRefresh) Refresh(); // Draw the status bar (if allowed to)
+}
+//------------------------------------------------------------------------------
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::~TStatusBar() // Destructor
+{
+	/* Stuff that has to be done at this point */
+   if (AutoRefresh) // Is it my job to clean up the screen?
+   	Erase(); // As object is destructed clean up the screen
+
+	/* Memory release */
+   if (Caption) delete[] Caption;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::SetDrawColor(int DrawColor)
+{
+	if (DrawColor != CurrentDrawColor) // New is not old?
+   {
+   	CurrentDrawColor = DrawColor; // Set the new color
+   	if (AutoRefresh) // should I refresh, or leave it to caller?
+      	Refresh(); // Refreshs with new color
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+inline int
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::GetDrawColor()
+{
+	return CurrentDrawColor;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::SetBackColor(int BackColor)
+{
+	if (BackColor != CurrentBackColor) // New is not old?
+   {
+   	CurrentBackColor = BackColor; // Set the new color
+      if (AutoRefresh) // My job to refresh?
+      	Refresh(); // If so, do so
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+inline int
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::GetBackColor()
+{
+	return CurrentBackColor;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::SetHeight(int NewHeight)
+{
+	if (NewHeight != Height) // New is not old?
+   {
+   	Height = NewHeight; // Set the new height
+      if (AutoRefresh) // should I refresh, or leave it it caller
+      	Refresh(); // Refresh with new height
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+inline int
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::GetHeight()
+{
+	return Height;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::SetCaption(const char* NewCaption)
+{
+	if (Caption) // Already assigned?
+		delete[] Caption; // Release memory
+	if (NewCaption == 0) // Zero pointer (clear)
+	{
+		Caption = 0; // Zero pointer
+		return;
+	}
+	Caption = new char[strlen(NewCaption)+1]; // Allocate space for new caption
+   strcpy(Caption, NewCaption); // Copy data across
+
+   if (AutoRefresh) // It's my job to refresh eh?
+   	Refresh(); // Then do it
+	return;
+}
+//------------------------------------------------------------------------------
+char*
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::GetCaption() // Returns a pointer to the caption so that it may be read by the object user
+{
+	return Caption; // WARNING! The caller may alter the string now he knows the address, but nothing will change unless he manually refreshes with a call to ScreenComponents::TStatusBar::Refresh()
+}
+//------------------------------------------------------------------------------
+unsigned int
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::ReadCaption(char* TransBuf, unsigned int MaxLen)
+{
+	if (!Caption) // No caption?!
+   	return 0; // No char.s copied then
+
+   if (MaxLen < (strlen(Caption)+1)) // Not enough space in buffer
+   	return 0; // Insufficient buffer space, so don't do anything (you'll see this on trace)
+
+	strcpy(TransBuf, Caption); // Copy the buffer for the caller
+   return strlen(TransBuf); // Return the ammount copied
+}
+//------------------------------------------------------------------------------
+inline BOOL
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::ClearCaption()
+{
+	// Returns false if the caption was not allocated already
+   if (!Caption)
+		return FALSE;
+	delete[] Caption;
+	Caption = 0;
+	return TRUE;
+}
+//------------------------------------------------------------------------------
+inline unsigned int
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::GetCaptionLength()
+{
+	if (Caption)
+		return strlen(Caption);
+	return 0;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::Refresh() // Draws / redraws the component on the graphics screen
+{
+	// Collect some info to avoid multiple calls to the same functions
+   const int maxx = getmaxx();
+   const int maxy = getmaxy();
+
+   /* Set up the draw color */
+   int OriginalColor = getcolor(); // Save current drawing color for BGI
+   setcolor(CurrentDrawColor); // Set the color to the one we are supposed to use
+	/* draw top line */
+	line(1, maxy - Height, maxx, maxy - Height);
+   /* draw bottom line */
+   line(1, maxy, maxx, maxy);
+   /* draw left line */
+   line(1, maxy - Height, 1, maxx);
+   /* draw right line */
+   line(maxx, maxy - Height, maxx, maxy);
+   /* Before we draw inside the status bar, purge it to prevent
+   old data from clogging the background */
+   CleanInterior();
+   /* Put the caption on the status bar */
+   if (Caption)
+   	outtextxy(5, (maxy - (Height/2)) - (textheight(Caption)/2), Caption);
+
+   setcolor(OriginalColor); // Restore stuff before our color messing
+   return; // That's it!
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::Erase() // Erases the component from the screen by refreshing with black
+{
+	int OldDrawColor = CurrentDrawColor; // Save the current objuser's draw color selection
+   CurrentDrawColor = BLACK; // Prepare to draw with black
+   Refresh(); // Refreshes with black
+   CurrentDrawColor = OldDrawColor; // Restore the old color
+	return;
+}
+//------------------------------------------------------------------------------
+void
+#ifndef __NO_NAMESPACES__
+ScreenComponents::
+#endif
+TStatusBar::CleanInterior()
+{
+	const int maxx = getmaxx(); // Constants for speed instead of
+   const int maxy = getmaxy(); // repeated function calling
+
+   // Do vertical first (that means inside, H outermost loop)
+	for (int i=2;    i<maxx-1;    i++)
+   {
+   	for (int j=maxy-(Height-3);    j<maxy-1;    j++)
+      {
+      	putpixel(i,j, CurrentBackColor);
+      }
+   }
+   return;
+}
+//------------------------------------------------------------------------------
+#include <String.h> // String manipulation functions
+#include <conio.h> // Console I/O clrcsr() etc.
+#include <stdlib.h> // for atoi()
+#include <graphics.h> // drawing functions
+#include <Stdio.h> // Standard I/O
+#include "Stds\DLStdInc.H"
+#pragma hdrstop
+
+#include "Headers\PieCrust.h" // Absolute essential powertools
+#include "DrawGame.H" // for drawing various game components
+#include "Headers\DOSGrids.h" // For drawing a grid on the screen
+#include "DOSwl\\DosWin.h"
+#include "GameCode.h"
+#include "BGlobals.h" // Global data access
+//------------------------------------------------------------------------------
+/* Main game code for the BShips game by David Duncan Ross Palmer,
+(Overlord). Unit started 16/02/1998.
+Copyright (C) 1998, Daybo Logic, all rights reserved. */
+//------------------------------------------------------------------------------
+/*																										 *
+ *			The TGame class definition   													    *
+ *																										 */
+//------------------------------------------------------------------------------
+TGame::TGame(const char* Plyr1Name, const char* Plyr2Name)
+{
+	// Constructor for TGame
+
+   // Create the players
+   Player1 = new TPlayer(Plyr1Name); // Create player object
+   Player1->SetParentThis(this); // Register parent with absolute base class TAbsBase
+   Player2 = new TPlayer(Plyr2Name);
+   Player2->SetParentThis(this);
+	ScreenComponents = new
+	#ifndef __NO_NAMESPACES__
+	ScreenComponents::
+	#endif
+	TScreenComponents(); // Create all the screen components
+   ScreenComponents->SetParentThis(this); // The game owns the screen components
+   _GamePtr = this; // Register game address globally
+}
+//------------------------------------------------------------------------------
+TGame::~TGame()
+{
+	// Destructor for TGame
+   _GamePtr = 0; // Indicates globally game no longer exists
+
+   // Delete the players
+   delete Player1;
+   delete Player2;
+   delete ScreenComponents;
+}
+//------------------------------------------------------------------------------
+void TGame::Run()
+{
+	/* Main game logic loop */
+	#ifndef __NO_NAMESPACES__
+	ScreenComponents::
+	#endif
+	TBShipsGrid* Grid = new
+	#ifndef __NO_NAMESPACES__
+	ScreenComponents::
+	#endif
+	TBShipsGrid(); // Make a grid to display
+   Grid->SetParentThis(this); // The game owns the BShips grid (OK mate!)
+   Grid->SetTop(12);
+   Grid->SetLeft(20);
+   Grid->SetNumCols(10); Grid->SetNumRows(10);
+   Grid->SetCellDims(30);
+   Grid->Show();
+	Grid->GridCell[0][0]->Erase();
+	#ifndef __NO_NAMESPACES__
+	ScreenComponents::
+   #endif
+	TGridLabels* GridLabels = new
+	#ifndef __NO_NAMESPACES__
+	ScreenComponents::
+	#endif
+	TGridLabels(14/*x*/,1/*y*/,Grid->GetCellDims()/*spacing*/); // Put some labels on the grid (part of the drawing components in DrawGame.CPP