20 HIMEM: 35070:ADRS = 35070: CALL ADRS: POKE 232,0: POKE 233,145: DEF FN DG(H) = (H / 360 - INT (H / 360)) * 360: DEF FN D(H) = FN DG( FN DG(H + 360)): DEF FN RD(X) = INT (X + .5): DEF FN RN(X) = INT ( RND (1) * X + 1):VA$ = CHR$ (129):VN$ = CHR$ (142):VI$ = CHR$ (137):VP$ = CHR$ (144):VY$ = CHR$ (153):VV$ = CHR$ (150):VW$ = CHR$ (151):VK$ = CHR$ (139):VL$ = CHR$ (140) 40 CX(2) = 1: DEF FN RF(X) = ((3700 - X) / 3700) ^ 2.86: SCALE= 1: ROT= 0:K$(1) = "DETAS":K$(2) = "MILAS":K$(3) = "KAMAS": GOSUB 50000: GOSUB 17000 9999 GOTO 9999 ### not reached? 10000 GOSUB 39000: GOSUB 38000: GOSUB 22000: GOSUB 43000: RETURN ### status/auto 11000 GOSUB 21000: GOSUB 43000: RETURN ### not reached? 12000 GOSUB 39000: GOSUB 21000: GOSUB 43000: RETURN ### not reached? 13000 GOSUB 39000: GOSUB 24000: GOSUB 43000: RETURN ### control/manual 14000 BS = 0: GOSUB 21000: RETURN ### control/auto 15000 BS = 2: GOSUB 21000: RETURN ### clear strings, return to main menu 16000 FOR Z = 1 TO 4:K$(Z) = "": NEXT Z: FOR Z = 1 TO 9:Z$(Z) = "":Z1$(Z) = "": NEXT Z: PRINT VN$VK$V0$: PRINT CHR$ (4);"BLOAD CHAIN,A520": CALL 520"MAIN MENU" 16090 GOTO 16090 ### main UI loop 17000 REM # if all shields are damaged, can't change the way they're controlled 17010 Z(1) = 3:Z(2) = 4:Z(3) = 5:Z(4) = 8:Z(5) = 9:Z(6) = 10:Z(7) = 12: IF D(1) AND D(2) AND D(3) AND D(4) THEN Z(4) = - 8:Z(5) = - 9:Z(6) = - 10 17030 Z = 7:Y = 30: GOSUB 41000:CO = X: GOSUB 39000: ON CO GOSUB 22000,11000,26000,14000,24000,15000,16000: GOTO 17010 ### not reached? 18000 Y = 30: FOR Z = 1 TO 10:Z(Z) = Z + 2: IF Z > 6 THEN Z(Z) = Z(Z) + 2 18020 NEXT Z:Z = 10: IF EN(11) = 0 OR MN = MS THEN Z(7) = - Z(7):Z(9) = - Z(9) 18200 GOSUB 41000:CO = X: ON CO GOSUB 15000,13000,12000,10000,14000,11000,19000,27000,23000,16000: GOTO 18000 ### show auto shield status 21000 REM 21001 GOSUB 38000: HCOLOR= 5: FOR Z = 13 TO 26: HPLOT 27,Z TO 175,Z: NEXT Z: VTAB (3): HTAB (5): PRINT VA$4VK$VN$;"AUTO SHIELD SYSTEMS": VTAB (5): PRINT VI$VA$1VL$" CONTROL: ";VA$4VK$;: PRINT VN$;" ";: IF BS = 0 THEN PRINT "MANUAL" 21040 IF BS = 1 THEN PRINT "SEMI-AUTOMATIC" 21050 IF BS = 2 THEN PRINT "AUTOMATIC" 21060 VTAB (7): PRINT VI$VA$1VL$;" TOTAL SHIELD POWER:";VA$4VN$" "; FN RD(EN(1) + EN(2) + EN(3) + EN(4)): HCOLOR= 1: HPLOT 9,30 TO 193,30 TO 193,41 TO 9,41: HPLOT 9,46 TO 193,46 TO 193,57 TO 9,57 21070 VTAB (9): PRINT VA$1;"SHIELD 1 2 3 4": VTAB (11): PRINT " POWER": PRINT " % OF": PRINT " TOTAL": PRINT " SHLDS": VTAB (11): PRINT VA$4VN$;: FOR X1 = 1 TO 4:X2 = (X1 - 1) * 5 + 8: HTAB (X2): PRINT FN RD(EN(X1));: NEXT X1: HCOLOR= 2: HPLOT 7,60 TO 195,60 21220 HPLOT 7,76 TO 195,76: HPLOT 7,88 TO 195,88: HPLOT 7,112 TO 195,112: HPLOT 52,60 TO 52,112: HPLOT 86,60 TO 86,112: HPLOT 120,60 TO 120,112: HPLOT 154,60 TO 154,112: HCOLOR= 3: FOR Z = 90 TO 100: HPLOT 58,Z TO 79,Z: NEXT Z 21290 HCOLOR= 1: FOR Z = 90 TO 100: HPLOT 93,Z TO 114,Z: NEXT Z: HCOLOR= 2: HPLOT 128,90 TO 148,90 TO 148,100 TO 128,100 TO 128,90: FOR Z = 90 TO 100: HPLOT 168,Z TO 189,Z: NEXT Z: GOSUB 21500: HTAB (1): VTAB (21): PRINT VA$1VL$VN$; TAB( 4);"SHIELD PERCENT CHART";: RETURN ### draw shield bar chart and connecting lines; configures W(n) for each shield to be pixel width of percent bar 21500 W(0) = 20: GOSUB 36000: FOR X1 = 1 TO 4:W(X1) = AS(X1) * 1.6 + W(X1 - 1): NEXT X1: VTAB (14): PRINT VA$4VN$;: FOR X1 = 1 TO 4:X2 = (X1 - 1) * 5 + 8: HTAB (X2): PRINT " ";: HTAB (X2): PRINT FN RD(AS(X1))"%";: NEXT X1: HCOLOR= 3 21565 HPLOT 19,150 TO 181,150 TO 181,157 TO 19,157 TO 19,150: FOR X1 = 151 TO 156: HCOLOR= 3: HPLOT 20,X1 TO W(1),X1: HCOLOR= 1: HPLOT W(1),X1 TO W(2),X1: HCOLOR= 0: HPLOT W(2),X1 TO W(3),X1: HCOLOR= 2: HPLOT W(3),X1 TO 180,X1: NEXT X1: HCOLOR= 3: GOSUB 21700: RETURN ### for each shield, if auto % is assigned, draw line from shield to middle position on bar 21700 FOR X1 = 1 TO 4: IF FN RD(AS(X1)) > = 1 THEN HPLOT 68 + (X1 - 1) * 36,116 TO (W(X1) + W(X1 - 1)) / 2,147 21710 NEXT X1: RETURN ### status/status: show the status of shield N 22000 REM 22010 FOR Z = 1 TO 4:Z(Z) = 14 + Z: NEXT Z:Z = 4:Y = 30: GOSUB 41000:SH = X: GOSUB 38000: PRINT VA$4VK$;: VTAB (3): HTAB (7): PRINT "SHIELD "SH" STATUS": PRINT VA$1;: VTAB (4): HTAB (2): PRINT VI$VL$;"CONDITION:";VN$VA$4VK$" ";:Z1$ = "GREEN":Z = 1: IF EN(SH) = 0 THEN Z1$ = "WHITE":Z = 3 22220 IF D(SH) THEN Z1$ = "RED":Z = 5 22230 PRINT TAB( 21)Z1$: HCOLOR= 2: HPLOT 12,23 TO 192,23 TO 192,32 TO 12,32 TO 12,23: HCOLOR= Z: FOR Z1 = 24 TO 31: HPLOT 86,Z1 TO 135,Z1: NEXT Z1: VTAB (6): HTAB (11): PRINT VL$VN$VA$1;"PWR 0 "VA$2;"2 4 6 8 0" 22250 PRINT VA$1VL$"ACT PWR " FN RD(EN(SH)): PRINT "ALLOC PWR "; FN RD(AL(SH)): PRINT "EFFICENCY "; FN RD(E(SH) * 100)"%":Y = 49:X3 = EN(SH) / MP(SH): HCOLOR= 1: GOSUB 22800:Y = 57:X3 = AL(SH) / MP(SH): HCOLOR= 3: GOSUB 22800 22257 Y = 65:X3 = E(SH): HCOLOR= 2: GOSUB 22800: HCOLOR= 3: HPLOT 114,46 TO 114,72: HPLOT 7,48 TO 185,48: HPLOT 7,56 TO 185,56: HPLOT 7,64 TO 185,64: HPLOT 7,72 TO 185,72: HPLOT 72,48 TO 72,72: HPLOT 185,48 TO 185,72: VTAB (12): PRINT ;"REPAIR DRIODS: "RT(SH) TAB( 19);: IF RT(SH) THEN PRINT VK$;: FOR Z1 = 1 TO RT(SH): PRINT "W";: NEXT Z1 22270 PRINT : PRINT VL$;"DAMAGE STATUS:"; TAB( 19);: IF D(SH) THEN PRINT RP(SH) 22290 IF D(SH) = 0 THEN PRINT "NONE" 22292 HCOLOR= 1: HPLOT 7,96 TO 195,96: HPLOT 7,105 TO 195,105: HPLOT 7,87 TO 195,87: VTAB (15): HTAB (2): PRINT "VESSEL" TAB( 20)"VESSEL": HTAB (2): PRINT "FACING"; TAB( 12)"RANGE" TAB( 20)"SHIELD": HTAB (2): PRINT "SHIELD "SH; TAB( 20)"FACING":X6 = 1: FOR Z1 = 1 TO 3: IF K(Z1) = 0 OR XS(Z1) < > SH THEN 22350 22340 HTAB (2): PRINT K$(Z1);: HTAB (12): PRINT FN RD(DK(Z1));: HTAB (23): PRINT VA$4;YS(Z1);VA$1 22350 NEXT Z1: HPLOT 73,106 TO 73,168: HPLOT 129,106 TO 129,168: HPLOT 7,135 TO 195,135: GOSUB 43000: RETURN ### draw shield status; X3 is ratio of current:max; Y is hplot position 22800 X2 = 114 + X3 * 70: FOR Z1 = Y + 1 TO Y + 5: HPLOT 114,Z1 TO X2,Z1: NEXT Z1: RETURN ### control/semi - set AS(n) percentages for each undamaged shield 24000 REM 24001 AS(1) = 0:AS(2) = 0:AS(3) = 0:AS(4) = 0 # set ZX to last undamaged shield, and SX to second-to-last undamaged shield :ZX = 0:SX = 0: FOR Z = 4 TO 1 STEP - 1: IF ZX < > 0 AND D(Z) = 0 THEN SX = Z: GOTO 24018 24006 IF ZX = 0 AND D(Z) = 0 THEN ZX = Z 24010 NEXT Z # if we got here, only one shield is functional :AS(ZX) = 100: GOSUB 21000: GOTO 24110 # print shield status 24018 BS = 1: GOSUB 21000 # select shield percent for each undamaged shield except last (which gets the remainder) :Z0 = 100: FOR ZY = 1 TO SX: IF D(ZY) THEN 24100 24050 PL = 0:PU = Z0: GOSUB 39000: PRINT "ENTER % FOR SHIELD "ZY;:RT = 1:ZT = 1:C = 1:RC = 0: GOSUB 40000:Z0 = Z0 - RC 24100 NEXT ZY:AS(ZX) = Z0 24110 GOSUB 21500: RETURN # erase line to bar, set AS(ZY)=RC, then redraw bar chart and connecting line 24500 GOSUB 36000: HCOLOR= 0: GOSUB 21700:AS(ZY) = RC: GOSUB 21500: PRINT VY$;: RETURN ### status/position - show all enemies relative to us # clear the screen and compute most distant ship distance into RC/SR 26000 POKE 232,0: POKE 233,145: GOSUB 26900 # draw enemy ships and shield lines : GOSUB 26600 # draw player ship, with shape selected by scale/distance :X0 = 0: HCOLOR= 5: GOSUB 39000:Z5 = 2: IF SR < 1000 THEN Z5 = 1: IF SR < 400 THEN Z5 = 0 26025 GOSUB 39000:SX = 68 / SR:SY = 60 / SR: ROT= 0: SCALE= 1: HCOLOR= 7:X = EH: GOSUB 46000: ROT= R * 8:X = 102 - X(Z5 + 3,R): FOR Z = 1 TO 2: HCOLOR= 6: IF Z = 1 THEN HCOLOR= 0 26035 HCOLOR= 6: DRAW 4 + Z5 AT X,84 - Y(Z5 + 3,R): IF INT (R / 2) < > R / 2 THEN DRAW 4 + Z5 AT X,83 - Y(Z5 + 3,R) 26039 NEXT Z: IF X2 < X1 THEN X2 = X2 + 360 26344 PRINT VA$4VN$VK$;: VTAB (21): HTAB (1): PRINT VA$1VL$" SCALE: " FN RD(SR / 2);" MGM";: HCOLOR= 2: HPLOT 67,163 TO 101,163: GOSUB 43000 26590 RETURN ### draw enemy ships and shield lines ### center point is 102,84 # Z5 is shape to draw; select based on distance bracket 26600 Z5 = 2: IF SR < 1000 THEN Z5 = 1: IF SR < 400 THEN Z5 = 0 26603 SX = 68 / SR:SY = 60 / SR: SCALE= 1: HCOLOR= 3 # should be impossible for DK(Z) to exceed SR; K(Z) check is for dead ship : FOR Z = 1 TO 3: IF DK(Z) > SR OR (CO = 1 AND SH < > Z) OR K(Z) = 0 THEN 26680 # map enemy heading in degrees to ROT 26620 X = KH(Z): GOSUB 46000: ROT= R * 8 # map position to display X/Y :Y = 80 - (KY(Z) - EY) * SY - Y(Z5,R):X = 102 + (KX(Z) - EX) * SX - X(Z5,R): IF X > 200 OR Y > 160 OR X < 1 OR Y < 1 THEN 26680 # shift by a pixel and draw twice as needed to manage color 26630 X = INT (X + .5):Y = INT (Y + .5): IF (X / 2 = INT (X / 2)) THEN X = X + 1 26650 DRAW Z5 + 1 AT X,Y: IF R < > 0 OR R < > 4 THEN DRAW Z5 + 1 AT X,Y - 1 26670 IF INT (R / 2) < > R / 2 THEN DRAW Z5 + 1 AT X,Y + 1 26680 NEXT Z # draw shield lines in purple, rotated by heading EH # draw "fat line", especially in case the line is horizontal :X0 = 6: HCOLOR= 2: FOR Z = 45 TO 315 STEP 90:X1 = FN RD(Z + EH):X = X1: GOSUB 26800: HPLOT X3,X4 TO X5,X6: HPLOT X3 + 1,X4 TO X5 + 1,X6 26765 NEXT Z # label the facings 1/2/3/4 (counter-clockwise, swapping 3/4) :X0 = 0: PRINT VA$4VK$VN$VY$;:X0 = 15: FOR Z1 = 1 TO 4:Z = Z1: IF Z1 = 3 THEN Z = 4: GOTO 26769 26767 IF Z1 = 4 THEN Z = 3 26769 X1 = FN RD((Z1 - 1) * 90 + EH):X = X1: GOSUB 26800:X7 = X3 / 7:X8 = X4 / 8: HTAB (X7): VTAB (X8): PRINT Z;: NEXT Z1 :X0 = 0: RETURN ### given angle X in degrees, and X0 offset from center (at 102,84), set line coordinates into X3,X4 to X5,X6 26800 X3 = COS (X * DR) * (75 - X0) + 102:X5 = COS (X * DR) * 19 + 102:X4 = 84 - SIN (X * DR) * (65 - X0):X6 = 84 - SIN (X * DR) * 15: RETURN ### clear windows; set RC to farthest ship, set SR to RC * 1.01 26900 GOSUB 38000: GOSUB 39000:RC = 1: FOR Z = 1 TO 3: IF RC < DK(Z) THEN RC = DK(Z) 26920 NEXT Z:SR = RC * 1.01: RETURN ### set window to (2,2) - (28,21) (main display window) 36000 PRINT VN$VY$;: VTAB (21): HTAB (28): PRINT VW$;: VTAB (2): HTAB (2): PRINT VV$;: RETURN ### set window to (2,23) - (28,23) (one line "press button" window) 37000 PRINT VN$VY$;: VTAB (23): HTAB (28): PRINT VW$;: VTAB (23): HTAB (2): PRINT VV$;: RETURN ### set to main display window and clear 38000 GOSUB 36000: PRINT VP$;: RETURN ### set to one-line at bottom and clear 39000 GOSUB 37000: PRINT VP$;: RETURN ### select value with paddle 40000 REM 40005 Z1$ = "": PRINT VY$;VA$1;VL$;VN$;:R = PU - PL:RC = PL + R / 2 40020 GOSUB 40100:R1 = 1:R3 = 1 40025 VTAB (23): HTAB (30): PRINT VA$1VI$;VK$;"Y";: HTAB (36): PRINT "X";VN$:X = 135: GOSUB 40100:ZT = 0:R1 = 0:RT = 1 40040 X = PDL (0): IF PEEK ( - 16287) > 127 THEN 40070 40045 IF ZT > 10 THEN ZT = 10 40050 IF X > 20 AND X < 200 THEN R1 = 0:ZT = 0: HTAB (31): VTAB (22): PRINT VA$1VK$"L";: GOTO 40040 40055 Z1$ = "J":R = - 1: IF X > 199 THEN R = 1:Z1$ = "K" 40060 IF R < > R1 THEN ZT = 0 40065 R1 = R:RC = RC + RT * (2 ^ INT (ZT / 2)) * R:ZT = ZT + 1: GOSUB 40100: GOTO 40040 40070 PRINT VA$1;: VTAB (23): HTAB (30): PRINT VK$;VI$;"X";: HTAB (36): PRINT "Y";: POKE 2048,50: POKE 2049,30: CALL 2050: POKE 2048,60: POKE 2049,50: CALL 2050: VTAB (22): HTAB (31): PRINT VN$" ";: PRINT VA$4;: RETURN ### make noise when adjusting values # call with C=1 when updating shield percentages 40100 REM 40105 IF RC > PU THEN RC = PU 40107 IF RC < PL THEN RC = PL 40109 IF RT THEN RC = INT (RC / RT + .5) * RT 40110 IF X2 = RC THEN 40190 40112 X2 = RC:Z1 = RC:Z1 = FN RD(Z1): HTAB (31): VTAB (22): PRINT VA$;1;VK$;Z1$;" ";VL$;Z1;:Y3 = LEN ( STR$ (Z1)): IF Y3 > 6 THEN 40190 40124 Z = 6 - Y3: FOR Y2 = 1 TO Z: PRINT " ";: NEXT Y2:Z9 = 30: IF C THEN Z9 = 10 40125 POKE 2048,(PU - RC) / (PU - PL) * 76 + 75: POKE 2049,Z9: CALL 2050: IF C = 1 THEN GOSUB 24500 40190 RETURN ### select menu item with paddle # find first active item 41000 REM 41006 PRINT VY$VA$1VK$VI$;:Z1$ = "J":Y3 = - 1: FOR Z2 = 1 TO Z: IF Z(Z2) > 0 AND Y3 > 0 THEN X1 = Z2: GOTO 41030 41016 IF Z(Z2) > 0 THEN Y3 = Z2 41020 NEXT Z2 # only one item is available, put it in X1 and auto-select it :X1 = Y3: GOTO 41180 # draw boxes 41030 Z1 = 250 / Z: FOR Z2 = 1 TO Z: HTAB (Y + 1): VTAB ( ABS (Z(Z2))): PRINT "E";: NEXT Z2 # loop 41079 X = INT ( PDL (0) / Z1 + .5): IF X > Z THEN X = Z 41080 IF X < 1 THEN X = 1 41081 IF Z2 > 20 THEN HTAB (Y): VTAB ( ABS (Z(X1))): PRINT " ";: POKE 2048,X1 * 5 + 50: POKE 2049,15: CALL 2050:Z2 = 0: HTAB (Y): PRINT "L"; 41082 Z2 = Z2 + 1: IF X < 1 THEN X = 1 41085 IF PEEK ( - 16287) > 127 THEN 41180 41090 IF Z(X) < 1 THEN GOTO 41079 41100 IF X1 < > X THEN HTAB (Y): VTAB (Z(X1)): PRINT " "; 41105 X1 = X: HTAB (Y): VTAB (Z(X)): PRINT "L";: GOTO 41079 41180 IF X1 < 1 THEN 41185 41183 HTAB (Y): VTAB (Z(X1)): PRINT " F"; 41185 GOSUB 45000:X = X1: RETURN ### wait for button press 43000 GOSUB 39000: VTAB (23): HTAB (8): PRINT VA$;1;VL$"PRESS BUTTON"; 43005 X2 = X2 + 1: IF X2 > 15 THEN VTAB (23): HTAB (6): PRINT VA$(1);VK$;"L";: HTAB (22): PRINT "M";:X2 = 0: POKE 2048,100: POKE 2049,30: CALL 2050 43010 IF X2 = 7 THEN VTAB (23): HTAB (6): PRINT " ";: HTAB (22): PRINT " "; 43020 IF PEEK ( - 16287) < 128 THEN 43005 43030 GOSUB 38000: GOSUB 45000: RETURN 45000 POKE 2048,30: POKE 2049,30: CALL 2050: POKE 2048,80: POKE 2049,50: CALL 2050: RETURN # map angle X in degrees (0 facing +Y axis) to shape rotation R (0-7); multiply by 8 for ROT= 46000 R = 2 - INT (( FN D(X) + 45 / 2) / 45): IF R < 0 THEN R = 8 + R 46030 RETURN ### draw UI frame 50000 POKE 49234,0: POKE 2072,42: POKE 2073,85: CALL 2074:Z$ = VA$ + "1" + VK$ + VI$ + " E" + VA$ + "4": PRINT VY$;: VTAB (1): HTAB (30) 50005 PRINT VV$;: VTAB (24): HTAB (10): PRINT VW$;: VTAB (2): HTAB (1): PRINT VK$VA$3;" STATUS ";: PRINT Z$"STATUS ";: PRINT Z$"AUTO "; 50050 PRINT Z$"POSITION";: PRINT VN$;: VTAB (7): PRINT VK$VA$3;" CONTROL ";: PRINT Z$"MANUAL ";: PRINT Z$"SEMI ";: PRINT Z$"AUTO ";: VTAB (12): PRINT Z$"RETURN ";: VTAB (14): PRINT VN$VK$VA$3;" SHIELD "; 50140 PRINT Z$" 1 ";: PRINT Z$" 2 ";: PRINT Z$" 3 ";: PRINT Z$" 4 ";: VTAB (21): PRINT VA$3; 50141 PRINT " COUNTER ";: PRINT VI$" ";: PRINT VN$" ";: PRINT VI$" ";: PRINT VA$1VK$"X";VL$;"RDY "VK$"X"VL$"ENT"; 50190 PRINT VY$VN$;: VTAB (2): HTAB (2): PRINT VV$;: VTAB (21): HTAB (27): PRINT VW$VP$;: VTAB (23) 50195 HTAB (1): PRINT VN$VV$;: VTAB (23): HTAB (27): PRINT VW$VP$;: PRINT VY$;: VTAB (1): HTAB (12): PRINT VI$VA$3VK$;"DEFENSE";: RETURN