Decoded: Sopwith (1984) by David L. Clark Source file: SWAUTO.C Beginner friendly, line-by-line code walkthrough by MaiZure SWAUTO.C defines functions for the AI planes that fight the player Original code: http://davidlclark.com/page/sopwith-source-code Original code with line numbers http://www.maizure.org/projects/decoded-sopwith/SWAUTO_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 COMMENT 28 COMMENT 29 COMMENT 30 Includes the main game header (sw.h) 31 BLANK 32 Import the sine table defined in SWMAIN.C 33 Import the current ground array 34 Import the base ground array 35 Import the object list 36 Import the plane object pointers 37 Import the AI plane tracking array 38 Import the target array 39 Import the left AI territory markers 40 Import the right AI territory markers 41 Import the object pointers for the lists 42 Import the display functions 43 Import the key delay 44 Import the current play mode 45 Import the victory flag 46 Import the victory countdown timer 47 Import the game speed 48 Import the computer plane flag 49 Import the player plane flag 50 Import the current object index 51 Import the performance counters 52 BLANK 53 BLANK 54 Declare a local flag for course corrections 55 Declare a local flag for returning to base 56 Declare a local object to hold a computer instance 57 Declare a local variable for course adjustment 58 BLANK 59 BLANK 60 BLANK 61 BLANK MAIN AI CONTROL 62 Declare and define swauto with one argument 63 First argument is the pointer to the input object (AI plane) 64 BLOCK START - swauto, perform AI actions 65 Declare a local variable 66 BLANK 67 Plane under control is not returning to base 68 BLANK 69 If there is a valid target within range... 70 Attack the target 71 Otherwise... 72 If plane isn't at home.. 73 It should cruise around 74 BLANK 75 Assume there is no target until the next AI loop 76 BLOCK END - swauto 77 BLANK 78 BLANK 79 BLANK 80 BLANK 81 BLANK AI ATTACK 82 Declare attack with two arguments 83 Both arguments are pointers, the attacker and the target 84 BLOCK START - attack, engage the player 85 Declare a local object pointer 86 BLANK 87 Course adjust ticks 16 units as a time, one per step through 240 88 Point to the input target 89 If the object is moving... 90 The shooter should aim... 91 A few pixels ahead of the targets x 92 And a few pixels ahead of the target y 93 Since we're attacking, the target is not a long way ahead 94 Otherwise the target isn't moving so.. 95 Aim slightly above the target 96 BLOCK END - attack 97 BLANK 98 BLANK 99 BLANK 100 BLANK AI CRUISING 101 Declare and define cruise with one argument 102 Argument is the pointer to the AI plane 103 BLOCK START - cruise, fly towards the target (player) 104 Declare a local variable for the crusing object's x coordinate 105 BLANK 106 Course adjust ticks 16 units as a time, one per step through 240 107 Capture the current object's x coordinate 108 If the plane is less than 1/3rd of the way across the map 109 It should cruise towards the 1/3 mark (go right) 110 But if it's beyond the 2/3rd point 111 It should cruise towards the 2/3rs point (go left) 112 Offset slightly based on course adjustment 113 It should fly around the top of the map 114 With no particular target 115 BLOCK END - cruise 116 BLANK 117 BLANK 118 BLANK 119 BLANK AI RETURN TO BASE 120 Declares and defines gohome with one argument 121 Argument is the pointer to the AI plane 122 BLOCK START - gohome, return to base 123 Declare local pointers to the plane and potential targets 124 BLANK 125 If the plane is already at home.. 126 Return, because we're already there 127 BLANK 128 Point to the current plane 129 BLANK 130 Course adjust ticks 16 units as a time, one per step through 240 131 BLOCK START - Arrive at base, if plane is within 16 x pixels of base.. 132 and within 16 y pixels of base... 133 BLOCK START - Player RTB, If it's the player 134 Initialize player plane 135 Reset the display 136 BLOCK END - Player RTB 137 Other if it's the computer plane... 138 Initialize the plane at base 139 It must be a multiplayer plane...? 140 Initialize that plane at base 141 Return 142 BLOCK END - Arrive at base 143 Set return to base flag to true 144 Aim towards the 145 BLOCK END - gohome 146 BLANK 147 BLANK 148 BLANK 149 BLANK 150 BLANK AI SHOOTING 151 Declare and define shoot with one argument 152 Argument 1 is the target to shoot at 153 BLOCK START - shoot, attack the player 154 Declare local objects to mirror the shooter and target 155 Declare local variables for the position of both shooter and target 156 Declare local variables to hold speed and angle of either object 157 Delare local variable to last turning state 158 Declare a local variable to hold current turn/range and an iterator 159 BLANK 160 BLANK 161 Copy the global computer plane object to the local attacker object 162 Copy the target object to the local target object 163 Set our speed variable to the shooter speed plus the bullet speed 164 Update our shooter mirror object's movement vector with bullet movement characteristics to mimic a potential shot. Start with x input 165 Then y input 166 Update the shooter's start x position to halfway in to the graphic 167 Update the shooter's start y position to halfway in to the graphic 168 BLANK 169 Set our local angle variable to the target's angle 170 Set our local speed variable to the target's speed 171 Set our previous angle to a temporary variable 172 BLOCK START - Predict shot, simulate a bullet hitting the target 173 Update bullet position. 174 BLOCK START - Turning target, If the target is flying... 175 Or wounded... 176 And it is turning.. 177 Then check it's orientation to determine it's turn direction 178 Adjust bullet angle for negative turn 179 Otherwise.. 180 Adjust bullet angle for positive turn 181 New angle may have wrapped, take the mod 182 Update the target's x movement 183 Update the target's y movement 184 BLOCK END - Turning target 185 Update the target's position 186 Store the target's range 187 If the range is beyond our interesting (too high or low) 188 We can't hit on the current vector so return fail 189 Otherwise If the bullet is beyond the target's start x 190 And before the target's end x 191 And beyond the target's start y 192 And before the target's end y 193 Return a positive value based on distance 194 BLANK 195 BLOCK END - Predict shot 196 We're here, so it missed. Return fail 197 BLOCK END - shoot 198 BLANK 199 BLANK 200 BLANK 201 BLANK ABSOLUTE VALUE UTILITY 202 Declare and define abs with one argument 203 Argument 1 is an integer 204 BLOCK START - abs, absolute value utility 205 Return the absolute value of the input 206 BLOCK END - abs 207 BLANK 208 BLANK 209 BLANK 210 BLANK 211 BLANK 212 BLANK 213 BLANK AI AIMING 214 Declare aim with five arguments 215 Arguments 1 and 4 are pointers to the attacker and target 216 Arguments 2 and 3 are the target's x and y coordinates 217 Argument 5 is a condition flag, usually false on init and true later 218 BLOCK START - aim, line up shot against player 219 Declare a local pointer the aiming and target objects 220 Declare local variables for range and indicies 221 Declare local variables for temporary positions 222 Declare local variables for speed and sngle 223 Declare a local array for turning states 224 Declare local arrays for all states of the game used to test aim actions 225 BLANK 226 Point to the input aiming object 227 BLANK 228 Initialize course correction to false 229 BLANK 230 If the aiming plane is stalled... 231 And it's not facing generally downward 232 Try to pull up 233 And speed up 234 Return from aiming (don't bother) 235 End of stalled plane case 236 BLANK 237 Set the temp x to the aiming plane's x value 238 Set the temp y to the aiming plane's y value 239 BLOCK START - Far aiming, if the target is further than 160 pixels... 240 If the object is moving left... 241 If the object has no hit count then... 242 Set its hit counter to 1 or 2 depending on altitude 243 Recursively aim up or down depending on the hit counter 244 Either up or down and set it for long aim 245 End case for left movement 246 Clear hitcounter 247 Otherwise, recursively aim 150 pixels in front.. 248 And consider the plane's altitude.. 249 along with course adjustment. Set for long shot 250 BLOCK END - Far aiming 251 If this isn't a far aim then... 252 Reset plane hitcount tracker 253 BLANK 254 If the aiming plane is moving... 255 Then apply course correction for minor y variances... 256 Push the object's start y towards zero 257 Otherwise we should check x 258 Correct for minor variances in x... 259 Push the x towards zero 260 BLANK 261 Copy the aiming object to the global temporary object structure. We're about to modify the copy for aiming projections from the real object 262 If the object is at max speed.. 263 And is a plane... 264 Then set the temp speed variable to game max 265 Otherwise, it's not a plane or it's not moving 266 If the speed is somehow slower than game minimum 267 Set our temp speed variable to game minimum 268 BLANK 269 Remove target checks for now 270 BLOCK START - Test movement choices, Loop through all movement choices 271 The angle is the base angle... 272 Plus the positive or negative flat position 273 Wrapping the angles if necessary 274 Update the test plane's movement vector for its new angle 275 Perform a single move step along the new vector 276 Calculate the new range to target with the updated settings 277 Calculate the new altitude off the ground 278 Calculate the crash possibility 279 We've tracked the case to recopy the old one to test the next case 280 BLOCK END - Test movement choices 281 BLANK 282 BLANK 283 If the aim target is valid and the aimer has a good shot lined up.. 284 If the plane has missiles... 285 Then set the missile target 286 Otherwise... 287 Fire the guns at the target 288 BLANK 289 Set the minimum range to a temp value 290 BLOCK START - Check for best range (positive), Loop through tested cases 291 If the tested range is positive... 292 But less than our test range.. 293 and doesn't result in a crash 294 Then the new minimum range 295 Save best choice so far in n 296 BLOCK END - Check for best range (positive) 297 If the positive pass didn't result in a good choice... 298 Check the negative side 299 BLOCK START - Check for best range (negative), loop through tested cases 300 If the tested range is negative... 301 And is better than the temporary (or otherwise set case) 302 And the choice doesn't result in a crash... 303 Save this case as the new best 304 Save best choice in n 305 BLOCK END - Check for best range (negative) 306 End range check 307 BLANK 308 If the test plane's speed is too low 309 Change to maximum 310 BLANK 311 If a movement choice was found... 312 and the plane wasn't moving at max speed 313 Set it to max speed 314 Otherwise we didn't find a good movement choice to make, therefore 315 If the plane is accelerating... 316 Let off the gas 317 BLANK 318 Set the base choice to 0 319 If choice 1 had a higher altitude result, 320 Set the new altitude to that of the 1 case 321 Set the 1 case as the choice 322 End case for choosing 1 323 If the 2nd test choice beat one (or base) 324 Then choose case 2 325 End default AI movement choice 326 BLANK 327 Set the plane's flap position to the chosen case 328 If it is a plane and no change was made... 329 If the plane is moving... 330 Then fly the plane right side up (flip if necessary). Barrel roll!! 331 BLANK 332 BLOCK END - aim 333 BLANK 334 BLANK 335 BLANK 336 Declare static local target index anchors 337 BLANK 338 BLANK 339 BLANK TEST FOR TARGETS 340 Declare cleartargs with no arguments 341 BLOCK START - cleartargs 342 Set targets left to -2 343 BLOCK END - cleartargs 344 BLANK 345 BLANK 346 BLANK 347 Declare testtargs with 2 arguments 348 Arguments are the x and y position of the tester (y is unused) 349 BLOCK START - testtargs, tests for possible target within input range 350 Declare local variables for index, target left x, and target right y 351 BLANK 352 x left is a point 32 pixels + difficulty game speed to the left of input 353 x right is 32 pixels + difficulty game speed to the right of input 354 BLANK 355 Set target left index to a temp value 356 Set target right index to a temp value 357 Loop through all targets to find the first valid target within range 358 If the target being checked has an x greater than our test window.. 359 Set the target left index to the current loop index 360 End the loop 361 End target left check 362 BLANK 363 If no target left was found.. 364 Then there can't possibly be a target right so end test 365 BLANK 366 Find the target right index starting where we left off 367 If the target is before the right hand window.. 368 Set target right to i-1, since we've incremented already 369 BLOCK END - testtargs 370 BLANK 371 BLANK 372 BLANK 373 BLANK TEST FOR CRASH 374 Declare tstcrash with four arguments 375 Arguments 2, 3, and 4 are x, y, and altitude above ground 376 Argument 1 is the pointer to the plane doing the test 377 BLOCK START - tstcrash, tests for possible collision with targets 378 Declare a local pointer to an object 379 Declare temporary x and y point tests 380 BLANK 381 If the input altitude is greater than 50... 382 ...then crashing isn't possible 383 BLANK 384 If the input altitude is below 22... 385 Then crashing must have occurred with the ground 386 BLANK 387 Point to the input plane 388 If target's haven't been checked... 389 Sweep the map for possible targets that may have been collided with 390 BLANK 391 Set xl to 32 pixels before the plane 392 Set xr to 32 pixels after the plane 393 BLANK 394 BLOCK START - Sweep through candidate targets, set from testtarg 395 If the the target is before the plane... 396 Then we missed, so continue sweep to next target 397 If the target is beyond our right side.. 398 Then we also missed and there's no more targets, return false 399 A standing building is 16 pixels tall but a destroyed building is 8 400 If the plane is below the building height... 401 Then we crashed 402 BLOCK END - Sweep through candidate targets 403 We're here so we didnt' find a target 404 BLOCK END - tstcrash 405 BLANK 406 BLANK 407 BLANK 408 BLANK 409 BLANK RANGE CHECK 410 Declare range with four arguments 411 Arguments are the origin (x,y) and the target (x,y) 412 BLOCK START - range, checks for range to target 413 Declare local integers for delta x and y 414 Declare a local temporary swap variable 415 BLANK 416 Delta y is the absolute value of the difference of origin and target y 417 Add 50% to delta y 418 If both delta x and delta y are less than 125.. 419 Then return the total distance 420 BLANK 421 But, if the target is far above or below the plane... 422 Save x to temporary 423 Swap y 424 Swap x 425 End case for vertical check 426 BLANK 427 Return the distance to compensate for the screen aspect 428 BLOCK END - range 429 EOF˙