Decoded: Sopwith (1984) by David L. Clark Source file: SWMAIN.C Beginner friendly, line-by-line code walkthrough by MaiZure SWMAIN.C is the main entry point to the program, which kicks off initialization and also includes the game loop at the end Original code: http://davidlclark.com/page/sopwith-source-code Original code with line numbers http://www.maizure.org/projects/decoded-sopwith/SWMAIN_linenum.txt 1 COMMENT 2 COMMENT 3 BLANK 4 COMMENT 5 COMMENT 6 COMMENT 7 COMMENT 8 COMMENT 9 COMMENT 10 COMMENT 11 COMMENT 12 COMMENT 13 COMMENT 14 BLANK 15 COMMENT 16 BLANK 17 COMMENT 18 COMMENT 19 COMMENT 20 COMMENT 21 COMMENT 22 COMMENT 23 COMMENT 24 COMMENT 25 COMMENT 26 COMMENT 27 Include main game header (sw.h) 28 BLANK 29 BLANK 30 BLANK SOPWITH DECLARES MANY GLOBALS 31 Declares global variable for playmode (novice, single, multiple, async) 32 Declares global GAMES object for tracking game state 33 Declares global OBJECTS status array 34 Declares global target count array (used in collision loop) 35 Declares global for the screen mode. Not clear this is meaningfully used 36 Declares global for tick mode. Not clear that this is used 37 Declares global counters used in movement and networking 38 Declares global counters used for movement...mostly deprecated it seems 39 BLANK 40 Declares global game number counter. Generally each game per session gets more difficult 41 Declares global offsets for each game number 42 Declares global range variable 43 BLANK 44 Declares global structure for multiplayer communications 45 Begins a preprocessor case for IBM PCs 46 Declares a global 8k display buffer for the IBM PC 47 Ends case for the IBM PC 48 Begins a preprocessor case for the Atari 49 Declares a global 16k display buffer for the Atari 50 Ends case for the Atari 51 BLANK 52 Declares a global integer to hold a keystroke 53 Declares a pointer for the multiplayer network buffer 54 BLANK 55 Begins a preprocessor case for IBM PCs 56 Declares a global address for the IBM PC disk controller 57 Ends case for the IBM PC 58 Begins a preprocessor case for the Atari 59 Declares a global address for the Atarti controller 60 Ends case for the Atari 61 BLANK 62 Declares a global used to track delay for multiplayer sync 63 Declares a global boolean for hi-resolution screen (40 vs 80 char width) 64 Declares a global boolean for display position -- not used 65 Declares a global boolean used to skip the title screen 66 Declares a global variable to hold debug infromation - not normally used 67 Declares a global boolean for sound on/off 68 Declares a global boolean to report game object usage (debug) 69 Declares a global boolean for joystick 70 Declares a global boolean for IBM type keyboards 71 Declares a global boolean for action gameplay state 72 Declares a global boolean for print screen keypress action 73 Declares a global for handling a keyboard press interrupt 74 Declares a global for missile usage 75 BLANK 76 Declares globals for left and right screen boundary positions 77 Declares a global for screen shift amount 78 Declares a global boolean for display initilization status 79 BLANK 80 Declares a global pointer to an object struct (not used) 81 Declares a global pointer to the game objects arrays 82 Declares a global pointer to player object arrays 83 Declares global pointers for object structure endpoints 84 Declares global pointers for an uninitialized object 85 Declares global pointerss for objects to be destroyed 86 Declares global pointers for objects in list by x position 87 BLANK 88 Declares a global array for potential AI targets 89 Declared a global array for left enemy territory boundaries (AI) 90 Sets array values based on positions 91 End of array 92 Declared a global array for right enemy territory boundaries (AI) 93 Sets array values based on positions 94 End of array 95 BLANK 96 Declares a global pointer to the highest allocated object in memory 97 Declares a global array for the end game stats per player 98 Declares a global counter variable for delaying for the ending sequence 99 Declares a global pointer to the player 100 Declares a global index for the current object 101 Declares a global boolean for current objects player status 102 Declares a global boolean for current objects computer status 103 Declares a display status array indexed by objects 104 Declares a global boolean for the end game sequence 105 Declares a global boolean for force redrawing of the ground 106 Declares global pointers to the history log i/o 107 Declares a global random seed used for generating exploding objects 108 BLANK 109 Declares a global delay threshold for keyboard input 110 Declares a global delay counter for keyboard input 111 Declares a global holding the end game status of the current object 112 Declares a global for the number of lives left 113 Declares a global for splatted birds 114 Declares a global counter for bird splats on screen (crash in to flock) 115 Declares a global for the splattered ox 116 Declares a global flag for the splattered ox (triggers splat display) 117 BLANK 118 BLOCK START - Precomputed sine table as integers [-256 - 256] 119 sin of 0, 22.5, 45, and 67.5 * 256 120 sin of 90, 112.5, 135, and 157.5 * 256 121 sin of 180, 202.5, 225, and 247.5 * 256 122 sin of 270, 292.5, 315, and 337.5 * 256 123 BLOCK END - Precomputed sine table as integers [-256 - 256] 124 BLANK 125 Declares a jump buffer to manipulate function calls (see setjmp.h) 126 COMMENT 127 BLANK 128 Imports a global procedure from SWUTIL.ASM for keyboard interrupts 129 BLANK 130 Begins a preprocessor case for IBM PCs 131 Imports a global system flag from BMBLIB.C 132 Ends a preprocessor case for IBM PCs 133 Begins a preprocessor case for the Atart 134 Declares a global system flag 135 Ends a preprocessor case for Atari 136 BLANK 137 BLANK 138 Main entry point with the standard argument count and element vector 139 Argument counter variable 140 Argument vector pointer THE MAIN ENTRY POINT 141 BLOCK START - main 142 Prototype for malloc (behavior is compiler dependent...conflicts, etc) 143 BLANK 144 Allocates memory for a 100 object pool/slab (why 100 and not MAX_OBJS?) 145 Sets the system type to DOS 146 BLANK 147 Calls the big init function for the game 148 Saves the current environment (top-level main) in to the env buffer THE GAME LOOP 149 BLOCK START - Game loop. Infinite loop...FOREVER is 'for (;;)' in std.h 150 BLANK 151 COMMENT 152 COMMENT 153 COMMENT 154 COMMENT 155 Delays game for 'movemax' cycles (normally set to 15 in SWINIT) 156 Disables interrupts 157 Resets move tick to 0 158 Enables interrupts 159 BLANK 160 Moves all objects (SWMOVE.C) 161 Checks the status of the joystick (SWUTIL.ASM) 162 Updates the display (SWGRPH.ASM) 163 Checks the status of the joystick again 164 Processes collisions (SWCOLLSN.C) 165 Checks the status of the joystick yet again 166 Disables interrupts 167 BLOCK START - Print screen. Enters block if print screen was triggered 168 Resets the print flag 169 Resets the interrupt vector for koveride (for default printscreen) 170 Enables interrupts 171 Executes the print screen (SWUTIL.ASM) 172 Disable interrupts 173 Restores the application overrided keyboard interrupt 174 Segment arguments for the interrupt override 175 BLOCK END - Print screen 176 Enables interrupts 177 Performs sound operations 178 BLOCK END - Game Loop 179 BLOCK END - main 180 BLANK˙