'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' S T A R W R E K v1.0 Copyright (C) Sami Ky”stil„ 1998 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' ' See README.TXT for more info. ' ' You may use this code freely, as long as you give me some credit for it. ' ' Any comments & questions can be sent to hiteck@freenet.hut.fi ' 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ '$DYNAMIC DECLARE FUNCTION Multikey% (T%) DECLARE SUB Help () DECLARE SUB DmaState (StopGo%) DECLARE SUB SndSystem () DECLARE SUB WAVPlayDMA (file$, Freq&) DECLARE SUB GetBLASTER (DMA%, Baseport%, IRQ%) DECLARE FUNCTION DMADone% () DECLARE SUB DMAPlay (Segment&, Offset&, Length&, Freq&) DECLARE SUB writedsp (Byte%) DECLARE FUNCTION DSPVersion! () DECLARE FUNCTION Exist% (file$) DECLARE SUB Game () DECLARE SUB ChooseCraft () DECLARE SUB DrawLens (Lens() AS ANY, x%, y%) DECLARE SUB Menu () DECLARE SUB InitLens (Lens() AS ANY, Zoom%, Radius%) DECLARE SUB FadeIN () DECLARE SUB BlackPal () DECLARE SUB FadeOUT () DECLARE SUB ReadPal () DECLARE SUB PalGet (Index%, r%, g%, b%) DECLARE SUB PalSet (Index%, r%, g%, b%) DECLARE FUNCTION SetTimerFreq% (ScanFreq!) DECLARE FUNCTION GetAngle% (x1%, y1%, x2%, y2%) DECLARE SUB DrawExplosion () DECLARE SUB SpawnExplosion (XPos&, YPos&) DECLARE SUB PutSprite (x%, y%, x2%, y2%, XLen%, YLen%, SpriteNum%, Angle%, ColorShift%) DECLARE SUB SpawnShot (Player%) DECLARE SUB DrawShots () DECLARE SUB UpdateHeat (Player%) DECLARE SUB UpdateEnergy (Player%) DECLARE SUB DrawFlame () DECLARE SUB GETVECT (s AS INTEGER, O AS INTEGER, I AS INTEGER) DECLARE SUB Keyboard.In (OLDSEG AS INTEGER, OLDOFF AS INTEGER) DECLARE SUB SETVECT (s AS INTEGER, O AS INTEGER, I AS INTEGER) DECLARE SUB Keyboard.Out (OLDSEG AS INTEGER, OLDOFF AS INTEGER) DECLARE SUB DrawStars () DECLARE SUB MoveShip (XPos&, YPos&, Angle%, XVel&, YVel&, KeyArray%(), Player%) DECLARE SUB FastLoad (file$, Num%) DECLARE SUB SaveSprite (file$, Num%) DEFINT A-Z DECLARE SUB Rotate (x%, y%, x2%, y2%, Angle2%, Scale!) DECLARE SUB LoadPalette (file$) DECLARE FUNCTION GetByte% (VOffset&) DECLARE SUB LoadSprite (file$, XLen%, YLen%, Num%) DECLARE SUB DumpPage () DECLARE SUB FillChar (Segment%, Offset%, Value%, Bytes%) DECLARE SUB MakePalette () DECLARE SUB CloseEMS () DECLARE SUB InitEMS (MemoryNeeded&) DECLARE SUB CopyDataToEMS (FromSegment%, FromOffset%, VOffset&, Bytes%) DECLARE FUNCTION GetPageFrameAddress! (Segment&) DECLARE FUNCTION AllocateEMSPages! (PagesNeeded%, EMMhandle%) DECLARE SUB ChangePage (PageNeeded%) DECLARE SUB MapEMS (EMMhandle%, PhysicalPage%, LogicalPage%) DECLARE SUB Memcopy (fromseg%, FromOffset%, toseg%, ToOffset%, Bytes%) DECLARE FUNCTION DeallocateEMSPages% (Handle%) DECLARE FUNCTION EMMInstalled! () DECLARE FUNCTION EnoughEMSAvail! (PagesNeeded%) DECLARE FUNCTION MapEMSPages! (EMMhandle%, PhysicalPage%, LogicalPage%) DECLARE SUB PutByte (VOffset&, Value!) DEFINT A-Z TYPE RegType ax AS INTEGER bx AS INTEGER cx AS INTEGER dx AS INTEGER bp AS INTEGER si AS INTEGER di AS INTEGER flags AS INTEGER END TYPE TYPE RegTypeX ax AS INTEGER bx AS INTEGER cx AS INTEGER dx AS INTEGER bp AS INTEGER si AS INTEGER di AS INTEGER flags AS INTEGER ds AS INTEGER es AS INTEGER END TYPE TYPE PlayerType XPos AS LONG YPos AS LONG XVel AS LONG YVel AS LONG ScreenY AS LONG ScreenX AS LONG Angle AS INTEGER Energy AS LONG HeatLevel AS SINGLE ShipSpeed AS SINGLE ShipTurnRate AS INTEGER Shot AS INTEGER Craft AS INTEGER Computer AS INTEGER CompOverHeat AS INTEGER OverHeat AS INTEGER END TYPE TYPE CraftType Speed AS SINGLE Turnrate AS SINGLE Shot AS INTEGER Caption AS STRING * 20 END TYPE TYPE StarType x AS LONG y AS LONG Col AS INTEGER END TYPE TYPE StarType2 x AS INTEGER y AS INTEGER z AS SINGLE Rx AS SINGLE Ry AS SINGLE Col AS INTEGER END TYPE TYPE FlameType x AS LONG y AS LONG Col AS INTEGER END TYPE TYPE ShotType x AS LONG y AS LONG Angle AS LONG Col AS LONG Speed AS LONG END TYPE TYPE ExplosionType x AS LONG y AS LONG Radius AS INTEGER Angle AS INTEGER Spin AS INTEGER Col AS INTEGER END TYPE TYPE LensType XOfs AS INTEGER YOfs AS INTEGER Mask AS INTEGER END TYPE '---------------------------------------------------------------------------- ' Constants '---------------------------------------------------------------------------- CONST True = 0 CONST False = NOT True CONST Pi = 22 / 7 CONST Stars = 300 CONST EMMInt = &H67, GetPageFrame = &H4100, GetUnallocPageCount = &H4200 CONST AllocatePages = &H4300, MapPages = &H4400, DeallocatePages = &H4500 DIM SHARED Handle% DIM SHARED Segment& DIM SHARED CurrentPage% DIM SHARED EmsBytes& DIM SHARED Craft(0 TO 5) AS CraftType DIM SHARED Pal AS STRING * 768 DIM SHARED Boom(0 TO 10) AS ExplosionType DIM SHARED Shot(1 TO 2, 0 TO 100) AS ShotType DIM SHARED Flame(1 TO 2, 0 TO 14) AS FlameType DIM SHARED Star(0 TO Stars) AS StarType DIM SHARED Player(1 TO 2) AS PlayerType DIM SHARED ASMMemCopy$ DIM SHARED ASMFillChar$ DIM SHARED Buffer(319, 199) AS STRING * 1 DIM SHARED BGround(319, 199) AS STRING * 1 DIM SHARED Sine(360) AS INTEGER 'SIN table DIM SHARED Cosine(360) AS INTEGER 'COS table DIM SHARED Zoom AS SINGLE DIM SHARED SxPos AS INTEGER DIM SHARED SyPos AS INTEGER DIM SHARED ShotPointer1 AS INTEGER DIM SHARED ShotPointer2 AS INTEGER DIM SHARED ExplosionPointer AS INTEGER DIM SHARED FlamePointer1 AS INTEGER DIM SHARED FlamePointer2 AS INTEGER DIM SHARED FlameX1 AS INTEGER DIM SHARED FlameY1 AS INTEGER DIM SHARED FlameX2 AS INTEGER DIM SHARED FlameY2 AS INTEGER DIM SHARED Blink AS INTEGER DIM SHARED Lens(0 TO 38, 0 TO 38) AS LensType DIM SHARED ShotsFired(1 TO 2) AS LONG CONST BufferLen = 32000 DIM SHARED Char AS STRING * 1 DIM SHARED WavBuffer(0 TO 0) AS STRING * BufferLen DIM SHARED WavFreq& DIM SHARED WavFileHandle& DIM SHARED WavOffset& DIM SHARED WavLength& DIM SHARED PlayingWAV& DIM SHARED Baseport% DIM SHARED LenPort% DIM SHARED Channel% DIM SHARED IRQ% PlayingWAV& = False DIM SHARED ShotsHit(1 TO 2) AS LONG InitLens Lens(), 10, 19 FOR I = 0 TO 360 Sine(I) = SIN(I * Pi / 180) * 1024 Cosine(I) = COS(I * Pi / 180) * 1024 NEXT asm$ = "" asm$ = asm$ + CHR$(85) asm$ = asm$ + CHR$(137) + CHR$(229) asm$ = asm$ + CHR$(30) asm$ = asm$ + CHR$(139) + CHR$(70) + CHR$(10) asm$ = asm$ + CHR$(142) + CHR$(192) asm$ = asm$ + CHR$(139) + CHR$(70) + CHR$(14) asm$ = asm$ + CHR$(142) + CHR$(216) asm$ = asm$ + CHR$(139) + CHR$(118) + CHR$(8) asm$ = asm$ + CHR$(139) + CHR$(126) + CHR$(12) asm$ = asm$ + CHR$(139) + CHR$(78) + CHR$(6) asm$ = asm$ + CHR$(243) asm$ = asm$ + CHR$(164) asm$ = asm$ + CHR$(31) asm$ = asm$ + CHR$(93) asm$ = asm$ + CHR$(203) ASMMemCopy$ = asm$ asm$ = "" asm$ = asm$ + CHR$(85) asm$ = asm$ + CHR$(137) + CHR$(229) asm$ = asm$ + CHR$(139) + CHR$(78) + CHR$(6) asm$ = asm$ + CHR$(139) + CHR$(86) + CHR$(8) asm$ = asm$ + CHR$(139) + CHR$(70) + CHR$(12) asm$ = asm$ + CHR$(30) asm$ = asm$ + CHR$(142) + CHR$(216) asm$ = asm$ + CHR$(139) + CHR$(94) + CHR$(10) asm$ = asm$ + CHR$(136) + CHR$(23) asm$ = asm$ + CHR$(67) asm$ = asm$ + CHR$(226) + CHR$(251) asm$ = asm$ + CHR$(31) asm$ = asm$ + CHR$(93) asm$ = asm$ + CHR$(203) ASMFillChar$ = asm$ SCREEN 0: CLS LOCATE 1, 1, 0, 0, 0 COLOR 15, 1 PRINT STRING$(80, " "); LOCATE 1, 20 PRINT "StarWrek v1.0 Copyright (C) Sami Ky”stil„ 1998" COLOR 7, 0 PRINT PRINT " þ Initializing EMS..." InitEMS 1024& * 1024& * 1 PRINT " þ Reading BLASTER..." GetBLASTER Channel%, Baseport%, IRQ% PRINT " þ Loading graphics... [ ]" COLOR 8 LOCATE 5, 25 PRINT STRING$(12, "þ") LOCATE 5, 25 COLOR 10 FastLoad "craft1.gfx", 0: PRINT "þ"; FastLoad "craft2.gfx", 1: PRINT "þ"; FastLoad "craft3.gfx", 2: PRINT "þ"; FastLoad "craft4.gfx", 3: PRINT "þ"; FastLoad "craft5.gfx", 4: PRINT "þ"; FastLoad "craft6.gfx", 5: PRINT "þ"; FastLoad "craft7.gfx", 6: PRINT "þ"; FastLoad "craft8.gfx", 7: PRINT "þ"; FastLoad "craft9.gfx", 8: PRINT "þ"; FastLoad "craft10.gfx", 9: PRINT "þ"; FastLoad "craft11.gfx", 10: PRINT "þ"; FastLoad "craft12.gfx", 11: PRINT "þ"; SCREEN 13: CLS LoadPalette "logo.pal" ReadPal BlackPal DEF SEG = &HA000 BLOAD "logo.gfx" DEF SEG WAVPlayDMA "logo.raw", 16000 FadeIN DO IF PlayingWAV& = True THEN SndSystem LOOP UNTIL INKEY$ <> "" FadeOUT CLS Craft(0).Speed = .8 'Default ship Craft(0).Turnrate = 15 Craft(0).Shot = 1 Craft(0).Caption = "Klamath " Craft(1).Speed = .9 'Enterprise v.0001 alpha Craft(1).Turnrate = 15 Craft(1).Shot = 2 Craft(1).Caption = "USS Entertainment " Craft(2).Speed = 1.5 'UFO Craft(2).Turnrate = 15 Craft(2).Shot = 1 Craft(2).Caption = "The Roswell Rover " Craft(3).Speed = 1 'V-Ship Craft(3).Turnrate = 15 Craft(3).Shot = 1 Craft(3).Caption = "Da holy V-Ship " Craft(4).Speed = .8 'Tie-fighter Craft(4).Turnrate = 10 Craft(4).Shot = 1 Craft(4).Caption = "Tie-Exorcist " Craft(5).Speed = .6 'Klingon-Klone Craft(5).Turnrate = 8 Craft(5).Shot = 2 Craft(5).Caption = "USS Insourmountable" DO Menu LOOP CloseEMS END REM $STATIC DEFSNG A-Z FUNCTION AllocateEMSPages (PagesNeeded%, EMMhandle%) DIM InRegs AS RegType, OutRegs AS RegType InRegs.ax = AllocatePages InRegs.bx = PagesNeeded% CALL INTERRUPT(EMMInt, InRegs, OutRegs) IF (OutRegs.ax \ 256) = 0 THEN EMMhandle% = OutRegs.dx AllocateEMSPages = ((OutRegs.ax \ 256) = 0) END FUNCTION DEFINT A-Z SUB BlackPal FOR I& = 0 TO 255 OUT &H3C8, I& OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, 0 NEXT END SUB SUB ChangePage (PageNeeded) 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Changes the active EMS page to PageNeeded, unless it is already active. 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IF PageNeeded <> CurrentPage% THEN MapEMS Handle%, 0, PageNeeded CurrentPage% = PageNeeded END IF END SUB SUB ChooseCraft LoadPalette "game.pal" ReadPal BlackPal DEF SEG = &HA000 BLOAD "choose.gfx" DEF SEG Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HFA00 Memcopy VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 XPos = 60 FOR I = 0 TO 11 STEP 2 PutSprite XPos, 50, XPos + 32, 50 + 32, 32, 32, I, 0, 0 PutSprite XPos, 120, XPos + 32, 120 + 32, 32, 32, I + 1, 0, 0 XPos = XPos + 40 NEXT Memcopy VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HA000, 0, &HE100 Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HFA00 Memcopy VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 Selected1 = 0 Selected2 = 1 Done1 = 0 Done2 = 0 Angle = 0 MenuStars = 400 DIM St(0 TO MenuStars) AS StarType2 FOR I = 0 TO MenuStars St(I).x = INT(RND * 40) - 20 St(I).y = INT(RND * 40) - 20 St(I).z = INT(RND * 150) + 1 St(I).Col = (RND * 8) + 32 NEXT FOR I = 0 TO MenuStars x = 160 + (St(I).x / St(I).z) * 512 y = 100 + (St(I).y / St(I).z) * 512 IF x > 0 AND y > 0 AND x < 320 AND y < 200 THEN IF Buffer(x, y) = CHR$(0) THEN Buffer(x, y) = CHR$(St(I).Col) END IF St(I).z = St(I).z - 1 IF St(I).z < 2 THEN St(I).x = INT(RND * 40) - 20 St(I).y = INT(RND * 40) - 20 St(I).z = INT(RND * 150) + 1 St(I).Col = (RND * 8) + 32 END IF NEXT Memcopy VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HA000, 0, &HFA00 Memcopy VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 FadeIN IF Player(2).Computer = 1 THEN Selected2 = (INT(RND * 6)) * 2 + 1 Done2 = 1 END IF DO IF PlayingWAV& = True THEN SndSystem FOR I = 0 TO MenuStars x = 160 + (St(I).x / St(I).z) * 512 y = 100 + (St(I).y / St(I).z) * 512 IF x > 0 AND y > 0 AND x < 320 AND y < 200 THEN IF Buffer(x, y) = CHR$(0) THEN Buffer(x, y) = CHR$(St(I).Col) END IF St(I).z = St(I).z - 1 IF St(I).z < 2 THEN St(I).x = INT(RND * 40) - 20 St(I).y = INT(RND * 40) - 20 St(I).z = INT(RND * 150) + 1 St(I).Col = (RND * 8) + 32 END IF NEXT KeyCode$ = UCASE$(INKEY$) IF KeyCode$ <> "" THEN IF Done1 = 0 THEN IF KeyCode$ = CHR$(0) + CHR$(75) THEN WAVPlayDMA "select.raw", 22050 Selected1 = Selected1 - 2 IF Selected1 < 0 THEN Selected1 = 10 END IF IF KeyCode$ = CHR$(0) + CHR$(77) THEN WAVPlayDMA "select.raw", 22050 Selected1 = Selected1 + 2 IF Selected1 > 10 THEN Selected1 = 0 END IF IF KeyCode$ = "4" THEN WAVPlayDMA "select.raw", 22050 Selected1 = Selected1 - 2 IF Selected1 < 0 THEN Selected1 = 10 END IF IF KeyCode$ = "6" THEN WAVPlayDMA "select.raw", 22050 Selected1 = Selected1 + 2 IF Selected1 > 10 THEN Selected1 = 0 END IF END IF IF Done2 = 0 THEN IF KeyCode$ = "A" THEN WAVPlayDMA "select.raw", 22050 Selected2 = Selected2 - 2 IF Selected2 < 1 THEN Selected2 = 11 END IF IF KeyCode$ = "D" THEN WAVPlayDMA "select.raw", 22050 Selected2 = Selected2 + 2 IF Selected2 > 11 THEN Selected2 = 1 END IF IF KeyCode$ = CHR$(9) AND Done2 = 0 THEN WAVPlayDMA "confirm.raw", 22050 Done2 = 1 END IF END IF END IF DEF SEG = &H40 IF ((PEEK(&H17) AND &H4) / &H4) AND Done1 = 0 THEN WAVPlayDMA "confirm.raw", 22050 Done1 = 1 END IF DEF SEG XPos = 60 + ((Selected1 \ 2) * 40) XPos2 = 60 + ((Selected2 \ 2) * 40) FOR y& = 50 TO 50 + 32 FillChar VARSEG(Buffer(XPos, y&)), VARPTR(Buffer(XPos, y&)), 228, 33 NEXT FOR y& = 120 TO 120 + 32 FillChar VARSEG(Buffer(XPos2, y&)), VARPTR(Buffer(XPos2, y&)), 228, 33 NEXT PutSprite XPos, 50, XPos + 32, 50 + 32, 32, 32, Selected1, Angle, 0 PutSprite XPos2, 120, XPos2 + 32, 120 + 32, 32, 32, Selected2, Angle, 0 WAIT &H3DA, 8 Memcopy VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HA000, 0, &HFA00 Memcopy VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 LOCATE 13, 10: COLOR 7 PRINT Craft(Selected1 \ 2).Caption LOCATE 22, 10: COLOR 7 PRINT Craft((Selected2 - 1) \ 2).Caption IF Done1 = 1 THEN LINE (XPos - 1, 49)-(XPos + 33, 50 + 33), 230, B LINE (XPos - 2, 48)-(XPos + 34, 50 + 34), 232, B LINE (XPos - 3, 47)-(XPos + 35, 50 + 35), 230, B END IF IF Done2 = 1 THEN LINE (XPos2 - 1, 119)-(XPos2 + 33, 120 + 33), 230, B LINE (XPos2 - 2, 118)-(XPos2 + 34, 120 + 34), 232, B LINE (XPos2 - 3, 117)-(XPos2 + 35, 120 + 35), 230, B END IF Angle = Angle + 15 Angle = Angle MOD 360 IF KeyCode$ = CHR$(27) THEN FadeOUT BlackPal CLS Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HFA00 Memcopy &HA000, 0, VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 DumpPage CLS EXIT SUB END IF LOOP UNTIL Done1 = 1 AND Done2 = 1 Player(1).Craft = Selected1 Player(1).Angle = 270 Player(1).XPos = 160 Player(1).YPos = 0 Player(1).XVel = 0 Player(1).YVel = 0 Player(1).Energy = 100 Player(1).HeatLevel = 0 Player(1).ShipSpeed = Craft(Selected1 \ 2).Speed Player(1).ShipTurnRate = Craft(Selected1 \ 2).Turnrate Player(1).Shot = Craft(Selected1 \ 2).Shot Player(1).CompOverHeat = 0 Player(1).OverHeat = 0 Player(2).Angle = 90 Player(2).XPos = -160 Player(2).YPos = 0 Player(2).XVel = 0 Player(2).YVel = 0 Player(2).Energy = 100 Player(2).HeatLevel = 0 Player(2).ShipSpeed = Craft((Selected2 - 1) \ 2).Speed Player(2).ShipTurnRate = Craft((Selected2 - 1) \ 2).Turnrate Player(2).Shot = Craft((Selected2 - 1) \ 2).Shot Player(2).CompOverHeat = 0 Player(2).OverHeat = 0 Player(2).Craft = Selected2 FadeOUT BlackPal CLS Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HFA00 Memcopy &HA000, 0, VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 DumpPage CLS Game END SUB DEFSNG A-Z SUB CloseEMS 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Releases allocated EMS memory, ALWAYS call at the end of the program. 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IF NOT DeallocateEMSPages(Handle%) THEN PRINT "Unable to deallocate EMS Pages!" END IF END SUB SUB CopyDataFromEMS (VOffset&, ToSegment%, ToOffset%, Bytes%) 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Copies an area of data from EMS ' ' VOffset& - Virtual EMS offset ' ToSegment% - Dest. Segment ' ToOffset% - Dest. Offset ' Bytes% - n. of bytes copy 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MapEMS Handle%, 0, VOffset& \ 16384 CurrentPage% = VOffset& \ 16384 Memcopy Segment& - 1 + 1, VOffset& MOD 16384, ToSegment%, ToOffset%, Bytes% END SUB SUB CopyDataToEMS (FromSegment%, FromOffset%, VOffset&, Bytes%) 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Copies an area of data to EMS ' ' FromSegment% - From Segment ' FromOffset% - From Offset ' VOffset& - Virtual EMS offset ' Bytes% - n. of bytes copy 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MapEMS Handle%, 0, VOffset& \ 16384 CurrentPage% = VOffset& \ 16384 Memcopy FromSegment%, FromOffset%, Segment& - 1 + 1, VOffset& MOD 16384, Bytes% END SUB DEFINT A-Z FUNCTION DeallocateEMSPages (Handle%) DIM InRegs AS RegType, OutRegs AS RegType InRegs.ax = DeallocatePages InRegs.dx = Handle% CALL INTERRUPT(EMMInt, InRegs, OutRegs) DeallocateEMSPages = ((OutRegs.ax \ 256) = 0) END FUNCTION FUNCTION DMADone% '---------------------------------------------------------------------------- ' Use to see if a DMA transfer has been completed '---------------------------------------------------------------------------- Count% = INP(LenPort%) Count2% = INP(LenPort%) Count& = CLNG(Count% + 1) * CLNG(Count2% + 1) IF (Count& - 1) >= &HFFFF& THEN junk% = INP(DSPDataAvail%): DMADone% = -1 END FUNCTION SUB DMAPlay (Segment&, Offset&, Length&, Freq&) ' Transfers and plays the contents of the buffer. Length& = Length& - 1 Page% = 0 MemLoc& = Segment& * 16 + Offset& SELECT CASE Channel% CASE 0 PgPort% = &H87 AddPort% = &H0 LenPort% = &H1 ModeReg% = &H48 CASE 1 PgPort% = &H83 AddPort% = &H2 LenPort% = &H3 ModeReg% = &H49 CASE 2 PgPort% = &H81 AddPort% = &H4 LenPort% = &H5 ModeReg% = &H4A CASE 3 PgPort% = &H82 AddPort% = &H6 LenPort% = &H7 ModeReg% = &H4B CASE ELSE PRINT "DMA channels 0-3 only are supported." EXIT SUB END SELECT OUT &HA, &H4 + Channel% OUT &HC, &H0 OUT &HB, ModeReg% OUT AddPort%, MemLoc& AND &HFF OUT AddPort%, (MemLoc& AND &HFFFF&) \ &H100 IF (MemLoc& AND 65536) THEN Page% = Page% + 1 IF (MemLoc& AND 131072) THEN Page% = Page% + 2 IF (MemLoc& AND 262144) THEN Page% = Page% + 4 IF (MemLoc& AND 524288) THEN Page% = Page% + 8 OUT PgPort%, Page% OUT LenPort%, Length& AND &HFF OUT LenPort%, (Length& AND &HFFFF&) \ &H100 OUT &HA, Channel% IF Freq& < 23000 THEN TimeConst% = 256 - 1000000 \ Freq& writedsp &H40 writedsp TimeConst% writedsp &H14 writedsp (Length& AND &HFF) writedsp ((Length& AND &HFFFF&) \ &H100) ELSE IF DSPVersion! >= 3 THEN TimeConst% = ((65536 - 256000000 \ Freq&) AND &HFFFF&) \ &H100 writedsp &H40 writedsp TimeConst% writedsp (Length& AND &HFF) writedsp ((Length& AND &HFFFF&) \ &H100) writedsp &H91 ELSE PRINT "You need a Sound Blaster with a DSP v3.x+ to play at high speed." EXIT SUB END IF END IF END SUB SUB DmaState (StopGo%) ' Stops or continues DMA play. IF StopGo% THEN writedsp &HD4 ELSE writedsp &HD0 END SUB SUB DrawExplosion FOR I& = 0 TO 10 IF Boom(I&).Col > 145 THEN FOR Angle& = 0 TO 360 STEP 30 Angle2& = (Angle& + Boom(I&).Angle) MOD 360 XOffset& = (Boom(I&).x + (Sine(Angle2&) / 1024) * Boom(I&).Radius) x& = SxPos x& = x& + (XOffset& * Zoom) YOffset& = (Boom(I&).y + (Cosine(Angle2&) / 1024) * Boom(I&).Radius) y& = SyPos y& = y& + (YOffset& * Zoom) IF x& > 0 AND x& < 319 AND y& > 0 AND y& < 199 THEN Buffer(x&, y&) = CHR$(Boom(I&).Col) END IF NEXT Boom(I&).Col = Boom(I&).Col - 1 Boom(I&).Radius = Boom(I&).Radius + 5 Boom(I&).Angle = Boom(I&).Angle + Boom(I&).Spin END IF NEXT END SUB SUB DrawFlame FOR I = 0 TO 14 IF SxPos + (Flame(1, I).x * Zoom) > 0 AND SxPos + (Flame(1, I).x * Zoom) < 318 THEN IF SyPos + (Flame(1, I).y * Zoom) > 0 AND SyPos + (Flame(1, I).y * Zoom) < 198 THEN Buffer(SxPos + Flame(1, I).x * Zoom, SyPos + Flame(1, I).y * Zoom) = CHR$(Flame(1, I).Col) Buffer(SxPos + Flame(1, I).x * Zoom + 1, SyPos + Flame(1, I).y * Zoom) = CHR$(Flame(1, I).Col) Buffer(SxPos + Flame(1, I).x * Zoom, SyPos + Flame(1, I).y * Zoom + 1) = CHR$(Flame(1, I).Col) Buffer(SxPos + Flame(1, I).x * Zoom + 1, SyPos + Flame(1, I).y * Zoom + 1) = CHR$(Flame(1, I).Col) END IF END IF Flame(1, I).Col = Flame(1, I).Col - 1 IF Flame(1, I).Col < 145 THEN Flame(1, I).x = -4000: Flame(1, I).y = -4000 NEXT FOR I = 0 TO 14 IF SxPos + (Flame(2, I).x * Zoom) > 0 AND SxPos + (Flame(2, I).x * Zoom) < 318 THEN IF SyPos + (Flame(2, I).y * Zoom) > 0 AND SyPos + (Flame(2, I).y * Zoom) < 198 THEN Buffer(SxPos + Flame(2, I).x * Zoom, SyPos + Flame(2, I).y * Zoom) = CHR$(Flame(2, I).Col) Buffer(SxPos + Flame(2, I).x * Zoom + 1, SyPos + Flame(2, I).y * Zoom) = CHR$(Flame(2, I).Col) Buffer(SxPos + Flame(2, I).x * Zoom, SyPos + Flame(2, I).y * Zoom + 1) = CHR$(Flame(2, I).Col) Buffer(SxPos + Flame(2, I).x * Zoom + 1, SyPos + Flame(2, I).y * Zoom + 1) = CHR$(Flame(2, I).Col) END IF END IF Flame(2, I).Col = Flame(2, I).Col - 1 IF Flame(2, I).Col < 145 THEN Flame(2, I).x = -4000: Flame(2, I).y = -4000 NEXT END SUB SUB DrawLens (Lens() AS LensType, x, y) LensSize = UBOUND(Lens, 1) FOR yy& = 0 TO LensSize FOR xx& = 0 TO LensSize IF Lens(xx&, yy&).Mask = 0 THEN Buffer(xx& + x, yy& + y) = BGround(x + Lens(xx&, yy&).XOfs, y + Lens(xx&, yy&).YOfs) END IF NEXT NEXT END SUB SUB DrawShots FOR I& = 0 TO 100 IF Shot(1, I&).Col > 64& * 1024 THEN IF SxPos + (Shot(1, I&).x * Zoom) > 0 AND SxPos + (Shot(1, I&).x * Zoom) < 319 THEN IF SyPos + (Shot(1, I&).y * Zoom) > 0 AND SyPos + (Shot(1, I&).y * Zoom) < 199 THEN Buffer(SxPos + Shot(1, I&).x * Zoom, SyPos + Shot(1, I&).y * Zoom) = CHR$(Shot(1, I&).Col \ 1024) END IF END IF Shot(1, I&).Col = Shot(1, I&).Col - 100 Shot(1, I&).x = Shot(1, I&).x + (Sine(Shot(1, I&).Angle) / 1024) * Shot(1, I&).Speed Shot(1, I&).y = Shot(1, I&).y - (Cosine(Shot(1, I&).Angle) / 1024) * Shot(1, I&).Speed IF Shot(1, I&).x >= Player(2).XPos - 12 AND Shot(1, I&).x <= Player(2).XPos + 12 THEN IF Shot(1, I&).y >= Player(2).YPos - 12 AND Shot(1, I&).y <= Player(2).YPos + 12 THEN SpawnExplosion Shot(1, I&).x, Shot(1, I&).y Shot(1, I&).x = -4000 Shot(1, I&).y = -4000 ShotsHit(1) = ShotsHit(1) + 1 Player(2).Energy = Player(2).Energy - Player(1).Shot UpdateEnergy 2 WAVPlayDMA "hit2.raw", 11025 END IF END IF END IF NEXT FOR I& = 0 TO 100 IF Shot(2, I&).Col > 48& * 1024 THEN IF SxPos + (Shot(2, I&).x * Zoom) > 0 AND SxPos + (Shot(2, I&).x * Zoom) < 319 THEN IF SyPos + (Shot(2, I&).y * Zoom) > 0 AND SyPos + (Shot(2, I&).y * Zoom) < 199 THEN Buffer(SxPos + Shot(2, I&).x * Zoom, SyPos + Shot(2, I&).y * Zoom) = CHR$(Shot(2, I&).Col \ 1024) END IF END IF Shot(2, I&).Col = Shot(2, I&).Col - 100 Shot(2, I&).x = Shot(2, I&).x + (Sine(Shot(2, I&).Angle) / 1024) * Shot(2, I&).Speed Shot(2, I&).y = Shot(2, I&).y - (Cosine(Shot(2, I&).Angle) / 1024) * Shot(2, I&).Speed IF Shot(2, I&).x >= Player(1).XPos - 12 AND Shot(2, I&).x <= Player(1).XPos + 12 THEN IF Shot(2, I&).y >= Player(1).YPos - 12 AND Shot(2, I&).y <= Player(1).YPos + 12 THEN SpawnExplosion Shot(2, I&).x, Shot(2, I&).y Shot(2, I&).x = -4000 Shot(2, I&).y = -4000 ShotsHit(2) = ShotsHit(2) + 1 Player(1).Energy = Player(1).Energy - Player(2).Shot UpdateEnergy 1 WAVPlayDMA "hit2.raw", 11025 END IF END IF END IF NEXT END SUB SUB DrawStars FOR I = 0 TO Stars IF SxPos + (Star(I).x * Zoom) > 0 AND SxPos + (Star(I).x * Zoom) < 319 THEN IF SyPos + (Star(I).y * Zoom) > 0 AND SyPos + (Star(I).y * Zoom) < 199 THEN Buffer(SxPos + Star(I).x * Zoom, SyPos + Star(I).y * Zoom) = CHR$(Star(I).Col) END IF END IF NEXT END SUB FUNCTION DSPVersion! ' Gets the DSP version. writedsp &HE1 Temp% = ReadDSP% Temp2% = ReadDSP% DSPVersion! = VAL(STR$(Temp%) + "." + STR$(Temp2%)) END FUNCTION SUB DumpPage Memcopy VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HA000, 0, &HE100 Memcopy VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 END SUB DEFSNG A-Z FUNCTION EMMInstalled DIM InRegsX AS RegTypeX, OutRegsX AS RegTypeX InRegsX.ax = &H3567 ' Get vector for INT 67h CALL InterruptX(&H21, InRegsX, OutRegsX) DEF SEG = OutRegsX.es Test$ = CHR$(PEEK(&HA)) + CHR$(PEEK(&HB)) + CHR$(PEEK(&HC)) EMMInstalled = (Test$ = "EMM") END FUNCTION FUNCTION EnoughEMSAvail (PagesNeeded%) DIM InRegs AS RegType, OutRegs AS RegType InRegs.ax = GetUnallocPageCount CALL INTERRUPT(EMMInt, InRegs, OutRegs) EnoughEMSAvail = (((OutRegs.ax \ 256) = 0) AND (OutRegs.bx >= PagesNeeded)) END FUNCTION DEFINT A-Z FUNCTION Exist% (file$) DEFINT A-Z '---------------------------------------------------------------------------- ' Checks if a file exists '---------------------------------------------------------------------------- ' ' File$ - File to check ' '---------------------------------------------------------------------------- ' Returns True if file exists, else False '---------------------------------------------------------------------------- IF file$ = "" THEN Exist = False: EXIT FUNCTION Checkfile = FREEFILE OPEN file$ FOR BINARY AS #Checkfile IF LOF(Checkfile) = 0 THEN Exist = False CLOSE #Checkfile KILL file$ ELSE Exist = True CLOSE #Checkfile END IF END FUNCTION SUB FadeIN FOR fade = 0 TO 63 FOR I& = 0 TO 255 PalGet INT(I&), r%, g%, b% IF r% < ASC(MID$(Pal, I& * 3 + 1, 1)) THEN r% = r% + 1 IF g% < ASC(MID$(Pal, I& * 3 + 2, 1)) THEN g% = g% + 1 IF b% < ASC(MID$(Pal, I& * 3 + 3, 1)) THEN b% = b% + 1 PalSet INT(I&), r%, g%, b% NEXT IF PlayingWAV& = True THEN SndSystem NEXT END SUB SUB FadeOUT FOR fade = 0 TO 63 FOR I& = 0 TO 255 PalGet INT(I&), r%, g%, b% IF r% > 0 THEN r% = r% - 1 IF g% > 0 THEN g% = g% - 1 IF b% > 0 THEN b% = b% - 1 PalSet INT(I&), r%, g%, b% NEXT IF PlayingWAV& = True THEN SndSystem NEXT END SUB SUB FastLoad (file$, Num) OPEN file$ FOR BINARY AS #1 TempBuffer$ = SPACE$(16384) VOffset& = 16384 * (CLNG(Num) * 2) GET #1, , TempBuffer$ FOR I& = 0 TO 16375 PutByte I& + VOffset&, ASC(MID$(TempBuffer$, I& + 1, 1)) NEXT VOffset& = VOffset& + 16384 GET #1, , TempBuffer$ FOR I& = 0 TO 16375 PutByte I& + VOffset&, ASC(MID$(TempBuffer$, I& + 1, 1)) NEXT CLOSE #1 END SUB SUB FillChar (Segment%, Offset%, Value%, Bytes%) DEF SEG = VARSEG(ASMFillChar$) CALL ABSOLUTE(BYVAL Segment%, BYVAL Offset%, BYVAL Value%, BYVAL Bytes%, SADD(ASMFillChar$)) DEF SEG END SUB SUB Game LoadPalette "game.pal" ReadPal foo = Multikey(-1) FOR I = 0 TO 100 Shot(1, I).Col = 0 Shot(2, I).Col = 0 NEXT FOR I = 0 TO 10 Boom(I).Col = 0 NEXT FOR I = 0 TO 14 Flame(1, I).Col = 0 Flame(2, I).Col = 0 NEXT ShotsHit(1) = 0 ShotsHit(2) = 0 ShotsFired(1) = 0 ShotsFired(2) = 0 Gravity = 0 SxPos = 160 SyPos = 100 FOR I = 0 TO Stars Star(I).x = INT(RND * 1280 - 640) Star(I).y = INT(RND * 800 - 400) Star(I).Col = INT(RND * 10 + 20) NEXT Zoom = .1 DIM RawKey AS INTEGER DIM KeyArray(0 TO 255) AS INTEGER FlamePointer1 = 0 FlamePointer2 = 0 BlackPal DEF SEG = &HA000 BLOAD "tausta.gfx" Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HE100 DEF SEG CLS DumpPage DEF SEG = &HA000 BLOAD "Statbar.gfx", 320& * 90& DEF SEG = 0 UpdateEnergy 1 UpdateEnergy 2 UpdateHeat 1 UpdateHeat 2 DrawStars PutSprite SxPos + (Player(2).XPos * Zoom) - 16 * Zoom, SyPos + (Player(2).YPos * Zoom) - 16 * Zoom, SxPos + (Player(2).XPos * Zoom) + 16 * Zoom, SyPos + (Player(2).YPos * Zoom) + 16 * Zoom, 32, 32, Player(2).Craft, Player(2).Angle, 0 PutSprite SxPos + (Player(1).XPos * Zoom) - 16 * Zoom, SyPos + (Player(1).YPos * Zoom) - 16 * Zoom, SxPos + (Player(1).XPos * Zoom) + 17 * Zoom, SyPos + (Player(1).YPos * Zoom) + 16 * Zoom, 32, 32, Player(1).Craft, Player(1).Angle, 0 DumpPage LINE (SxPos + (-660 * Zoom), SyPos + (-420 * Zoom))-(SxPos + (660 * Zoom), SyPos + (420 * Zoom)), 34, B FadeIN FOR Zoom = .1 TO .455555 STEP .02 DrawStars PutSprite SxPos + (Player(2).XPos * Zoom) - 16 * Zoom, SyPos + (Player(2).YPos * Zoom) - 16 * Zoom, SxPos + (Player(2).XPos * Zoom) + 16 * Zoom, SyPos + (Player(2).YPos * Zoom) + 16 * Zoom, 32, 32, Player(2).Craft, Player(2).Angle, 0 PutSprite SxPos + (Player(1).XPos * Zoom) - 16 * Zoom, SyPos + (Player(1).YPos * Zoom) - 16 * Zoom, SxPos + (Player(1).XPos * Zoom) + 17 * Zoom, SyPos + (Player(1).YPos * Zoom) + 16 * Zoom, 32, 32, Player(1).Craft, Player(1).Angle, 0 WAIT &H3DA, 8 DumpPage LINE (SxPos + (-660 * Zoom), SyPos + (-420 * Zoom))-(SxPos + (660 * Zoom), SyPos + (420 * Zoom)), 34, B NEXT DO IF PlayingWAV& = True THEN SndSystem IF INP(&H60) = 1 THEN EXIT DO WHILE LEN(INKEY$): WEND MoveShip Player(1).XPos, Player(1).YPos, Player(1).Angle, Player(1).XVel, Player(1).YVel, KeyArray(), 1 MoveShip Player(2).XPos, Player(2).YPos, Player(2).Angle, Player(2).XVel, Player(2).YVel, KeyArray(), 2 DrawStars DrawShots DrawFlame Player(1).ScreenX = SxPos + (Player(1).XPos * Zoom) Player(1).ScreenY = SyPos + (Player(1).YPos * Zoom) Player(2).ScreenX = SxPos + (Player(2).XPos * Zoom) Player(2).ScreenY = SyPos + (Player(2).YPos * Zoom) Tx = Player(1).ScreenX + (Sine(Player(1).Angle) / 1024) * 30 * Zoom Ty = Player(1).ScreenY - (Cosine(Player(1).Angle) / 1024) * 30 * Zoom IF Tx > 1 AND Tx < 318 AND Ty > 1 AND Ty < 198 THEN Buffer(Tx, Ty) = CHR$(12) Buffer(Tx - 1, Ty) = CHR$(4) Buffer(Tx, Ty - 1) = CHR$(4) Buffer(Tx + 1, Ty) = CHR$(4) Buffer(Tx, Ty + 1) = CHR$(4) END IF Tx = Player(2).ScreenX + (Sine(Player(2).Angle) / 1024) * 30 * Zoom Ty = Player(2).ScreenY - (Cosine(Player(2).Angle) / 1024) * 30 * Zoom FlameX1 = Player(1).XPos - (Sine(Player(1).Angle) / 1024) * 10 * Zoom FlameY1 = Player(1).YPos + (Cosine(Player(1).Angle) / 1024) * 10 * Zoom FlameX2 = Player(2).XPos - (Sine(Player(2).Angle) / 1024) * 10 * Zoom FlameY2 = Player(2).YPos + (Cosine(Player(2).Angle) / 1024) * 10 * Zoom IF Tx > 1 AND Tx < 318 AND Ty > 1 AND Ty < 198 THEN Buffer(Tx, Ty) = CHR$(10) Buffer(Tx - 1, Ty) = CHR$(2) Buffer(Tx, Ty - 1) = CHR$(2) Buffer(Tx + 1, Ty) = CHR$(2) Buffer(Tx, Ty + 1) = CHR$(2) END IF IF (Multikey(72) OR Multikey(80)) AND Player(1).OverHeat = 0 THEN Flame(1, FlamePointer1).x = FlameX1 Flame(1, FlamePointer1).y = FlameY1 Flame(1, FlamePointer1).Col = 158 FlamePointer1 = FlamePointer1 + 1 FlamePointer1 = FlamePointer1 MOD 15 Player(1).HeatLevel = Player(1).HeatLevel + .7 UpdateHeat 1 END IF IF (Multikey(17) OR Multikey(31)) AND Player(2).OverHeat = 0 THEN Flame(2, FlamePointer2).x = FlameX2 Flame(2, FlamePointer2).y = FlameY2 Flame(2, FlamePointer2).Col = 158 FlamePointer2 = FlamePointer2 + 1 FlamePointer2 = FlamePointer2 MOD 15 Player(2).HeatLevel = Player(2).HeatLevel + .7 UpdateHeat 2 END IF IF Player(1).HeatLevel > 0 THEN Player(1).HeatLevel = Player(1).HeatLevel - .5: UpdateHeat 1 IF Player(2).HeatLevel > 0 THEN Player(2).HeatLevel = Player(2).HeatLevel - .5: UpdateHeat 2 IF Player(1).HeatLevel >= 98 THEN Player(1).OverHeat = 1 WAVPlayDMA "alert.raw", 8000 END IF IF Player(2).HeatLevel >= 98 THEN Player(2).OverHeat = 1 WAVPlayDMA "alert.raw", 8000 END IF IF Player(1).HeatLevel < 50 THEN Player(1).OverHeat = 0 END IF IF Player(2).HeatLevel < 50 THEN Player(2).OverHeat = 0 END IF PutSprite SxPos + (Player(2).XPos * Zoom) - 16 * Zoom, SyPos + (Player(2).YPos * Zoom) - 16 * Zoom, SxPos + (Player(2).XPos * Zoom) + 16 * Zoom, SyPos + (Player(2).YPos * Zoom) + 16 * Zoom, 32, 32, Player(2).Craft, Player(2).Angle, 0 PutSprite SxPos + (Player(1).XPos * Zoom) - 16 * Zoom, SyPos + (Player(1).YPos * Zoom) - 16 * Zoom, SxPos + (Player(1).XPos * Zoom) + 17 * Zoom, SyPos + (Player(1).YPos * Zoom) + 16 * Zoom, 32, 32, Player(1).Craft, Player(1).Angle, 0 DrawExplosion WAIT &H3DA, 8 DumpPage LINE (SxPos + (-660 * Zoom), SyPos + (-420 * Zoom))-(SxPos + (660 * Zoom), SyPos + (420 * Zoom)), 34, B Dist = SQR((Player(1).XPos - Player(2).XPos) ^ 2 + (Player(1).YPos - Player(2).YPos) ^ 2) + 40 Zoom = (200 / Dist) - .1 IF Zoom < .2 THEN Zoom = .2 IF Zoom > 1 THEN Zoom = 1 SxPos = 160 - ((Player(1).XPos * Zoom + Player(2).XPos * Zoom)) \ 2 SyPos = 100 - ((Player(1).YPos * Zoom + Player(2).YPos * Zoom)) \ 2 Player(1).YVel = Player(1).YVel + Gravity Player(2).YVel = Player(2).YVel + Gravity Blink = Blink + 1 Blink = Blink MOD 16 IF Player(1).Energy <= 0 OR Player(2).Energy <= 0 THEN EXIT DO LOOP UNTIL KeyCode = 1 foo = Multikey(-2) VIEW SCREEN (0, 0)-(319, 199) IF Player(1).Energy <= 0 OR Player(2).Energy <= 0 THEN WAVPlayDMA "boom.raw", 11025 FOR fade = 0 TO 63 FOR I& = 0 TO 255 PalGet INT(I&), r%, g%, b% IF r% < 63 THEN r% = r% + 1 IF g% < 63 THEN g% = g% + 1 IF b% < 63 THEN b% = b% + 1 PalSet INT(I&), r%, g%, b% NEXT DO: LOOP WHILE LEN(INKEY$) NEXT FadeOUT CLS LoadPalette "win.pal" ReadPal BlackPal IF Player(1).Energy <= 0 THEN DEF SEG = &HA000 BLOAD "win2.gfx" DEF SEG ELSE DEF SEG = &HA000 BLOAD "win1.gfx" DEF SEG END IF COLOR 60 LOCATE 22, 11 PRINT ShotsFired(1) LOCATE 24, 11 IF ShotsFired(1) > 0 THEN PRINT RTRIM$(STR$(INT(ShotsHit(1) / ShotsFired(1) * 100))); "%"; ELSE PRINT " 0%"; END IF LOCATE 22, 33 PRINT ShotsFired(2) LOCATE 24, 33 IF ShotsFired(2) > 0 THEN PRINT RTRIM$(STR$(INT(ShotsHit(2) / ShotsFired(2) * 100))); "%"; ELSE PRINT " 0%"; END IF FadeIN DO IF PlayingWAV& = True THEN SndSystem LOOP UNTIL INKEY$ <> "" END IF FadeOUT BlackPal CLS Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HFA00 Memcopy &HA000, 0, VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 DumpPage CLS END SUB FUNCTION GetAngle (x1, y1, x2, y2) IF x2 = x1 THEN x2 = x2 + 1 IF y2 = y1 THEN y2 = y2 + 1 IF y2 > y1 AND x2 > x1 THEN GetAngle = (ATN(ABS(y2 - y1) / ABS(x2 - x1)) * 57.2958) + 90 ELSEIF y1 > y2 AND x2 > x1 THEN GetAngle = 90 - (ATN(ABS(y2 - y1) / ABS(x2 - x1)) * 57.2958) ELSEIF y1 > y2 AND x1 > x2 THEN GetAngle = (ATN(ABS(y2 - y1) / ABS(x2 - x1)) * 57.2958) + 270 ELSE GetAngle = 90 - (ATN(ABS(y2 - y1) / ABS(x2 - x1)) * 57.2958) + 180 END IF END FUNCTION SUB GetBLASTER (DMA%, Baseport%, IRQ%) '---------------------------------------------------------------------------- ' This subroutine parses the BLASTER environment string and returns settings. '---------------------------------------------------------------------------- IF LEN(ENVIRON$("BLASTER")) = 0 THEN PRINT "þ BLASTER Enviroment variable not set - sound will not be played." EXIT SUB END IF FOR Length% = 1 TO LEN(ENVIRON$("BLASTER")) SELECT CASE MID$(ENVIRON$("BLASTER"), Length%, 1) CASE "A" Baseport% = VAL("&H" + MID$(ENVIRON$("BLASTER"), Length% + 1, 3)) CASE "I" IRQ% = VAL(MID$(ENVIRON$("BLASTER"), Length% + 1, 1)) CASE "D" DMA% = VAL(MID$(ENVIRON$("BLASTER"), Length% + 1, 1)) END SELECT NEXT END SUB FUNCTION GetByte (VOffset&) 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Returns 1 byte from EMS at virtual byte position VOffset& 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ChangePage VOffset& \ 16384 DEF SEG = Segment& GetByte = PEEK(VOffset& MOD 16384) DEF SEG END FUNCTION DEFSNG A-Z FUNCTION GetPageFrameAddress (Segment&) DIM InRegs AS RegType, OutRegs AS RegType InRegs.ax = GetPageFrame CALL INTERRUPT(EMMInt, InRegs, OutRegs) IF (OutRegs.ax \ 256) = 0 THEN Segment& = OutRegs.bx END IF GetPageFrameAddress = ((OutRegs.ax \ 256) = 0) END FUNCTION DEFINT A-Z SUB Help LoadPalette "help1.pal" ReadPal BlackPal DEF SEG = &HA000 BLOAD "help1.gfx" DEF SEG FadeIN DO IF PlayingWAV& = True THEN SndSystem LOOP UNTIL INKEY$ <> "" FadeOUT CLS LoadPalette "help2.pal" ReadPal BlackPal DEF SEG = &HA000 BLOAD "help2.gfx" DEF SEG FadeIN DO IF PlayingWAV& = True THEN SndSystem LOOP UNTIL INKEY$ <> "" FadeOUT CLS LoadPalette "help3.pal" ReadPal BlackPal DEF SEG = &HA000 BLOAD "help3.gfx" DEF SEG FadeIN DO IF PlayingWAV& = True THEN SndSystem LOOP UNTIL INKEY$ <> "" FadeOUT CLS END SUB SUB InitEMS (MemoryNeeded&) 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Initializes MemoryNeeded& bytes of EMS memory. 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Pages = (MemoryNeeded& \ 16384) + 1 IF NOT EMMInstalled THEN PRINT "EMM not installed!" SYSTEM END IF IF NOT EnoughEMSAvail(Pages) THEN PRINT "Not enough EMM available!" SYSTEM END IF IF NOT AllocateEMSPages(Pages, Handle%) THEN PRINT "Unable to allocate EMS Pages!" SYSTEM END IF IF NOT MapEMSPages(Handle%, 0, 0) THEN PRINT "Unable to map EMS Pages!" IF NOT DeallocateEMSPages(Handle%) THEN PRINT "Unable to deallocate EMS Pages!" END IF SYSTEM END IF IF NOT GetPageFrameAddress(Segment&) THEN PRINT "Unable to get the Page Frame address!" IF NOT DeallocateEMSPages(Handle%) THEN PRINT "Unable to deallocate EMS Pages!" END IF SYSTEM END IF CurrentPage% = 0 MapEMS Handle%, 0, 0 EmsBytes& = (INT(Pages) * 16384&) - 1 END SUB SUB InitLens (Lens() AS LensType, LensZoom, Radius) LensSize = UBOUND(Lens, 1) FOR y& = 0 TO LensSize FOR x& = 0 TO LensSize Xd! = (x& - (LensSize \ 2)) ^ 2 Yd! = (y& - (LensSize \ 2)) ^ 2 Dist! = SQR(Xd! + Yd!) IF Dist! >= Radius - 1 THEN Lens(x&, y&).Mask = 1 NEXT NEXT r = LensSize \ 2 FOR y = 0 TO LensSize FOR x = 0 TO LensSize OrgX = x - LensSize \ 2 OrgY = y - LensSize \ 2 z = SQR(ABS((Radius * Radius) - (OrgX * OrgX) - (OrgY * OrgY))) IF z = 0 THEN z = 1 Nx = INT(OrgX * LensZoom / z) Ny = INT(OrgY * LensZoom / z) Nx = Nx + LensSize \ 2 Ny = Ny + LensSize \ 2 IF Nx < 0 THEN Nx = 0 IF Ny < 0 THEN Ny = 0 IF Nx > 319 THEN Nx = 319 IF Ny > 199 THEN Ny = 199 Lens(x, y).XOfs = Nx Lens(x, y).YOfs = Ny NEXT NEXT END SUB SUB LoadPalette (file$) DIM Bt AS STRING * 1 TempFile = FREEFILE OPEN file$ FOR BINARY AS TempFile FOR I = 0 TO 255 OUT &H3C8, I GET #TempFile, , Bt OUT &H3C9, ASC(Bt) GET #TempFile, , Bt OUT &H3C9, ASC(Bt) GET #TempFile, , Bt OUT &H3C9, ASC(Bt) NEXT CLOSE TempFile END SUB SUB LoadSprite (file$, XLen, YLen, Num) OPEN file$ FOR BINARY AS #1 OPEN "rotate.tmp" FOR BINARY AS #2 FOR y = 0 TO YLen - 1 FOR x = 0 TO XLen - 1 UChar$ = " " GET #1, , UChar$ PUT #2, , UChar$ NEXT NEXT CLOSE #1 Sprite = 0 VOffset& = 16384 * (CLNG(Num) * 2) FOR I = 0 TO 359 STEP 359 \ 30 Rotate 0, 0, XLen - 1, YLen - 1, I + 1, 1 'VOffset& = CLNG(Sprite) * (XLen * YLen) + Num * 65504 'VOffset& = 16384 * ((Sprite + Num) * 2) FOR y = 0 TO YLen - 1 FOR x = 0 TO XLen - 1 PutByte VOffset&, POINT(x, y) VOffset& = VOffset& + 1 NEXT NEXT 'VOffset& = VOffset& + 1024 Sprite = Sprite + 1 NEXT CLOSE #1, #2 END SUB SUB MakePalette FOR I = 0 TO 63 OUT &H3C8, I OUT &H3C9, I OUT &H3C9, I OUT &H3C9, 0 NEXT FOR I = 64 TO 128 OUT &H3C8, I OUT &H3C9, I OUT &H3C9, 0 OUT &H3C9, 0 NEXT FOR I = 129 TO 192 OUT &H3C8, I OUT &H3C9, 0 OUT &H3C9, I OUT &H3C9, 0 NEXT FOR I = 193 TO 255 OUT &H3C8, I OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, I NEXT END SUB DEFSNG A-Z SUB MapEMS (EMMhandle%, PhysicalPage%, LogicalPage%) IF NOT MapEMSPages(EMMhandle%, PhysicalPage%, LogicalPage%) THEN PRINT "Unable to map EMS Pages!" IF NOT DeallocateEMSPages(EMMhandle%) THEN PRINT "Unable to deallocate EMS Pages!" END IF SYSTEM END IF END SUB FUNCTION MapEMSPages (EMMhandle%, PhysicalPage%, LogicalPage%) DIM InRegs AS RegType, OutRegs AS RegType InRegs.ax = MapPages + (PhysicalPage% MOD 256) InRegs.bx = LogicalPage% InRegs.dx = EMMhandle% CALL INTERRUPT(EMMInt, InRegs, OutRegs) MapEMSPages = ((OutRegs.ax \ 256) = 0) END FUNCTION DEFINT A-Z SUB MasterVolume (right%, Left%, Getvol%) '---------------------------------------------------------------------------- ' Sets the master volume on the Sound Blaster card '---------------------------------------------------------------------------- ' ' Right% - Right volume ' Left% - Left volume ' Getvol% - If False, then volume will be read, not set ' '---------------------------------------------------------------------------- OUT Baseport% + 4, &H22 'PRINT BasePort% IF Getvol% THEN Left% = INP(Baseport% + 5) \ 16 right% = INP(Baseport% + 5) AND &HF EXIT SUB ELSE OUT Baseport% + 5, (right% + Left% * 16) AND &HFF END IF END SUB DEFSNG A-Z SUB Memcopy (fromseg%, FromOffset%, toseg%, ToOffset%, Bytes%) DEF SEG = VARSEG(ASMMemCopy$) CALL ABSOLUTE(BYVAL fromseg%, BYVAL FromOffset%, BYVAL toseg%, BYVAL ToOffset%, BYVAL Bytes%, SADD(ASMMemCopy$)) DEF SEG END SUB DEFINT A-Z SUB Menu LoadPalette "menu.pal" ReadPal BlackPal DEF SEG = &HA000 BLOAD "menu.gfx" DEF SEG Selected = 1 LensX = 61 LensDir = 1 Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HFA00 DumpPage MenuStars = 400 DIM St(0 TO MenuStars) AS StarType2 FOR I = 0 TO MenuStars St(I).x = INT(RND * 40) - 20 St(I).y = INT(RND * 40) - 20 St(I).z = INT(RND * 150) + 1 St(I).Col = RND * 20 NEXT FOR I = 0 TO MenuStars x = 160 + (St(I).x / St(I).z) * 512 y = 100 + (St(I).y / St(I).z) * 512 IF x > 0 AND y > 0 AND x < 320 AND y < 200 THEN IF Buffer(x, y) = CHR$(0) THEN Buffer(x, y) = CHR$(St(I).Col) END IF St(I).z = St(I).z - 1 IF St(I).z < 2 THEN St(I).x = INT(RND * 40) - 20 St(I).y = INT(RND * 40) - 20 St(I).z = INT(RND * 150) + 1 St(I).Col = RND * 20 END IF NEXT Memcopy VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HA000, 0, &HFA00 Memcopy VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 FadeIN DO IF PlayingWAV& = True THEN SndSystem DrawLens Lens(), LensX, 80 + ((Selected - 1) * 30) - 20 FOR I = 0 TO MenuStars x = 160 + (St(I).x / St(I).z) * 512 y = 100 + (St(I).y / St(I).z) * 512 IF x > 0 AND y > 0 AND x < 320 AND y < 200 THEN IF Buffer(x, y) = CHR$(0) THEN Buffer(x, y) = CHR$(St(I).Col) END IF St(I).z = St(I).z - 1 IF St(I).z < 2 THEN St(I).x = INT(RND * 40) - 20 St(I).y = INT(RND * 40) - 20 St(I).z = INT(RND * 150) + 1 St(I).Col = RND * 20 END IF NEXT WAIT &H3DA, 8 Memcopy VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HA000, 0, &HFA00 Memcopy VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 IF LensX >= 260 THEN LensDir = -LensDir IF LensX <= 60 THEN LensDir = -LensDir LensX = 160 - (Cosine(LensDir) / 1024) * 80 LensDir = LensDir + 3 LensDir = LensDir MOD 360 KeyCode$ = INKEY$ IF KeyCode$ = CHR$(0) + CHR$(72) THEN WAVPlayDMA "select.raw", 22050 Selected = Selected - 1 IF Selected < 1 THEN Selected = 4 END IF IF KeyCode$ = CHR$(0) + CHR$(80) THEN WAVPlayDMA "select.raw", 22050 Selected = Selected + 1 IF Selected > 4 THEN Selected = 1 END IF IF KeyCode$ = "8" THEN WAVPlayDMA "select.raw", 22050 Selected = Selected - 1 IF Selected < 1 THEN Selected = 4 END IF IF KeyCode$ = "2" THEN WAVPlayDMA "select.raw", 22050 Selected = Selected + 1 IF Selected > 4 THEN Selected = 1 END IF IF KeyCode$ = CHR$(13) THEN EXIT DO LOOP WAVPlayDMA "confirm.raw", 22050 FadeOUT BlackPal CLS Memcopy &HA000, 0, VARSEG(BGround(0, 0)), VARPTR(BGround(0, 0)), &HFA00 Memcopy &HA000, 0, VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HFA00 DumpPage CLS IF Selected = 1 THEN Player(1).Computer = 0 Player(2).Computer = 1 ChooseCraft END IF IF Selected = 2 THEN Player(1).Computer = 0 Player(2).Computer = 0 ChooseCraft END IF IF Selected = 3 THEN Help END IF IF Selected = 4 THEN CloseEMS SCREEN 0: CLS WIDTH 80, 25 DEF SEG = &HB800 BLOAD "ansi.gfx", 0 LOCATE 12, 1 COLOR 7 PRINT " þ Code, GFX, SFX", , COLOR 15 PRINT "Sami Ky”stil„" COLOR 7 PRINT " þ Keyboard Handler", , COLOR 15 PRINT "Joe Huber, jr." PRINT COLOR 7 PRINT " If you have any comments about this game, feel free to send them to:" COLOR 9 PRINT " hiteck@freenet.hut.fi" PRINT COLOR 14 PRINT " Thanks for playing!" PRINT SYSTEM END IF END SUB SUB MoveShip (XPos&, YPos&, Angle, XVel&, YVel&, KeyArray(), Player) SELECT CASE Player CASE 1 IF Player(1).Computer = 0 THEN IF Multikey(&H50) AND Player(1).OverHeat = 0 THEN '2 XVel& = XVel& + Sine(Angle) * Player(1).ShipSpeed YVel& = YVel& + Cosine(Angle) * Player(1).ShipSpeed END IF IF Multikey(&H48) AND Player(1).OverHeat = 0 THEN '8 XVel& = XVel& - Sine(Angle) * Player(1).ShipSpeed YVel& = YVel& - Cosine(Angle) * Player(1).ShipSpeed END IF IF Multikey(&H4B) THEN '4 Angle = Angle - Player(1).ShipTurnRate END IF IF Multikey(&H4D) THEN '6 Angle = Angle + Player(1).ShipTurnRate END IF IF Multikey(29) AND Player(1).OverHeat = 0 THEN SpawnShot 1 END IF IF Angle < 0 THEN Angle = 360 + Angle Angle = Angle MOD 361 XPos& = XPos& - ((XVel& \ 1024)) YPos& = YPos& + ((YVel& \ 1024)) ELSE EnemyAngle = (GetAngle(INT(XPos&), INT(YPos&), INT(Player(2).XPos), INT(Player(2).YPos))) MOD 360 IF Angle < EnemyAngle THEN Angle = Angle + Player(1).ShipTurnRate END IF IF Angle > EnemyAngle THEN Angle = Angle - Player(1).ShipTurnRate END IF IF Angle >= EnemyAngle - 5 AND Angle <= EnemyAngle + 5 AND Player(1).CompOverHeat = 0 THEN SpawnShot 1 END IF IF Angle < 0 THEN Angle = 360 + Angle Angle = Angle MOD 361 IF Player(1).HeatLevel > 95 THEN Player(1).CompOverHeat = 1 IF Player(1).HeatLevel < 75 THEN Player(1).CompOverHeat = 0 IF Player(1).CompOverHeat = 0 THEN Flame(1, FlamePointer1).x = FlameX1 Flame(1, FlamePointer1).y = FlameY1 Flame(1, FlamePointer1).Col = 158 FlamePointer1 = FlamePointer1 + 1 FlamePointer1 = FlamePointer1 MOD 15 Player(1).HeatLevel = Player(1).HeatLevel + .7 XVel& = XVel& - Sine(Angle) * Player(1).ShipSpeed YVel& = YVel& - Cosine(Angle) * Player(1).ShipSpeed END IF XPos& = XPos& - ((XVel& \ 1024)) YPos& = YPos& + ((YVel& \ 1024)) END IF IF XPos& < -640 THEN XPos& = -640: XVel& = 0 IF YPos& < -400 THEN YPos& = -400: YVel& = 0 IF XPos& > 640 THEN XPos& = 640: XVel& = 0 IF YPos& > 400 THEN YPos& = 400: YVel& = 0 CASE 2 IF Player(2).Computer = 0 THEN IF Multikey(31) AND Player(2).OverHeat = 0 THEN XVel& = XVel& + Sine(Angle) * Player(2).ShipSpeed YVel& = YVel& + Cosine(Angle) * Player(2).ShipSpeed END IF IF Multikey(17) AND Player(2).OverHeat = 0 THEN XVel& = XVel& - Sine(Angle) * Player(2).ShipSpeed YVel& = YVel& - Cosine(Angle) * Player(2).ShipSpeed END IF IF Multikey(30) THEN Angle = Angle - Player(2).ShipTurnRate END IF IF Multikey(32) THEN Angle = Angle + Player(2).ShipTurnRate END IF IF Multikey(15) AND Player(2).OverHeat = 0 THEN SpawnShot 2 END IF IF Angle < 0 THEN Angle = 360 + Angle Angle = Angle MOD 361 XPos& = XPos& - ((XVel& \ 1024)) YPos& = YPos& + ((YVel& \ 1024)) ELSE EnemyAngle = (GetAngle(INT(XPos&), INT(YPos&), INT(Player(1).XPos), INT(Player(1).YPos))) MOD 360 IF Angle < EnemyAngle THEN Angle = Angle + Player(2).ShipTurnRate END IF IF Angle > EnemyAngle THEN Angle = Angle - Player(2).ShipTurnRate END IF IF Angle >= EnemyAngle - 5 AND Angle <= EnemyAngle + 5 AND Player(2).CompOverHeat = 0 THEN SpawnShot 2 END IF IF Angle < 0 THEN Angle = 360 + Angle Angle = Angle MOD 361 IF Player(2).HeatLevel > 95 THEN Player(2).CompOverHeat = 1 IF Player(2).HeatLevel < 75 THEN Player(2).CompOverHeat = 0 IF Player(2).CompOverHeat = 0 THEN Flame(2, FlamePointer2).x = FlameX2 Flame(2, FlamePointer2).y = FlameY2 Flame(2, FlamePointer2).Col = 158 FlamePointer2 = FlamePointer2 + 1 FlamePointer2 = FlamePointer2 MOD 15 Player(2).HeatLevel = Player(2).HeatLevel + .7 XVel& = XVel& - Sine(Angle) * Player(2).ShipSpeed YVel& = YVel& - Cosine(Angle) * Player(2).ShipSpeed END IF XPos& = XPos& - ((XVel& \ 1024)) YPos& = YPos& + ((YVel& \ 1024)) END IF IF XPos& < -640 THEN XPos& = -640: XVel& = 0 IF YPos& < -400 THEN YPos& = -400: YVel& = 0 IF XPos& > 640 THEN XPos& = 640: XVel& = 0 IF YPos& > 400 THEN YPos& = 400: YVel& = 0 END SELECT END SUB FUNCTION Multikey (T) STATIC kbcontrol%(), kbmatrix%(), Firsttime, StatusFlag IF Firsttime = 0 THEN 'Initalize DIM kbcontrol%(128) DIM kbmatrix%(128) code$ = "" code$ = code$ + "E91D00E93C00000000000000000000000000000000000000000000000000" code$ = code$ + "00001E31C08ED8BE24000E07BF1400FCA5A58CC38EC0BF2400B85600FAAB" code$ = code$ + "89D8ABFB1FCB1E31C08EC0BF2400BE14000E1FFCFAA5A5FB1FCBFB9C5053" code$ = code$ + "51521E560657E460B401A8807404B400247FD0E088C3B700B0002E031E12" code$ = code$ + "002E8E1E100086E08907E4610C82E661247FE661B020E6205F075E1F5A59" code$ = code$ + "5B589DCF" DEF SEG = VARSEG(kbcontrol%(0)) FOR I% = 0 TO 155 ' Load ASM d% = VAL("&h" + MID$(code$, I% * 2 + 1, 2)) POKE VARPTR(kbcontrol%(0)) + I%, d% NEXT I% I& = 16 ' I think this stuff connects the interrupt with kbmatrix%() N& = VARSEG(kbmatrix%(0)): l& = N& AND 255: h& = ((N& AND &HFF00) \ 256): POKE I&, l&: POKE I& + 1, h&: I& = I& + 2 N& = VARPTR(kbmatrix%(0)): l& = N& AND 255: h& = ((N& AND &HFF00) \ 256): POKE I&, l&: POKE I& + 1, h&: I& = I& + 2 DEF SEG Firsttime = 1 END IF SELECT CASE T CASE -1 IF StatusFlag = 0 THEN DEF SEG = VARSEG(kbcontrol%(0)) CALL ABSOLUTE(0) ' Run interrupt DEF SEG StatusFlag = 1 END IF CASE -2 IF StatusFlag = 1 THEN DEF SEG = VARSEG(kbcontrol%(0)) ' Turn off interrupt CALL ABSOLUTE(3) DEF SEG StatusFlag = 0 END IF CASE 1 TO 128 Multikey = kbmatrix%(T) ' Return status CASE ELSE Multikey = 0 END SELECT END FUNCTION SUB PalGet (Index, r, g, b) OUT &H3C7, Index r = INP(&H3C9) g = INP(&H3C9) b = INP(&H3C9) END SUB SUB PalSet (Index, r, g, b) OUT &H3C8, Index OUT &H3C9, r OUT &H3C9, g OUT &H3C9, b END SUB DEFSNG A-Z SUB PutByte (VOffset&, Value) 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Writes Value to EMS virtual byte offset VOffset& 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ChangePage VOffset& \ 16384 DEF SEG = Segment& POKE VOffset& MOD 16384, Value DEF SEG END SUB DEFINT A-Z SUB PutSprite (x, y, x2, y2, XLen, YLen, SpriteNum, Angle, ColorShift) Num = (((Angle) MOD 350) \ 11) IF x2 = x OR y2 = y THEN EXIT SUB OrgX = x OrgY = y OrgX2 = x2 OrgY2 = y2 XDelta& = XLen / (x2 - x) * 1024 YDelta& = YLen / (y2 - y) * 1024 Tx& = 0 Ty& = 0 IF x < 0 THEN Tx& = Tx& + (-x * XDelta&) x = 0 END IF IF y < 0 THEN Ty& = Ty& + (-y * YDelta&) y = 0 END IF IF x2 > 319 THEN x2 = 319 END IF IF y2 > 199 THEN y2 = 199 END IF StartTx& = Tx& DIM TempTxt(0 TO XLen, 0 TO YLen) AS LONG VOffset& = (CLNG(Num) * (XLen * YLen)) + (16384 * (CLNG(SpriteNum) * 2)) ChangePage VOffset& \ 16384 DEF SEG = Segment& FOR yy& = 0 TO YLen - 1 FOR xx& = 0 TO XLen - 1 TempTxt(xx&, yy&) = PEEK(VOffset& MOD 16384) VOffset& = VOffset& + 1 NEXT NEXT DEF SEG IF ColorShift = 0 THEN FOR yy& = y TO y2 FOR xx& = x TO x2 IF TempTxt((Tx& \ 1024), (Ty& \ 1024)) <> 0 THEN Buffer(xx&, yy&) = CHR$(TempTxt((Tx& \ 1024), (Ty& \ 1024))) Tx& = Tx& + XDelta& NEXT Tx& = StartTx& Ty& = Ty& + YDelta& NEXT ELSE FOR yy& = y TO y2 FOR xx& = x TO x2 IF TempTxt((Tx& \ 1024), (Ty& \ 1024)) <> 0 THEN Buffer(xx&, yy&) = CHR$(TempTxt((Tx& \ 1024), (Ty& \ 1024)) + ColorShift) Tx& = Tx& + XDelta& NEXT Tx& = StartTx& Ty& = Ty& + YDelta& NEXT END IF x = OrgX y = OrgY x2 = OrgX2 y2 = OrgY2 END SUB DEFSNG A-Z SUB PutString (VOffset&, St$) 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ' Writes string St$ to EMS virtual byte offset VOffset& 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FOR I& = 0 TO LEN(St$) - 1 DEF SEG = VARSEG(St$) PutByte VOffset& + I&, PEEK(SADD(St$) + (I&)) DEF SEG NEXT END SUB DEFINT A-Z SUB ReadPal FOR I& = 0 TO 255 PalGet INT(I&), r%, g%, b% MID$(Pal, I& * 3 + 1, 1) = CHR$(r%) MID$(Pal, I& * 3 + 2, 1) = CHR$(g%) MID$(Pal, I& * 3 + 3, 1) = CHR$(b%) NEXT END SUB SUB Rotate (x, y, x2, y2, Angle2, Scale AS SINGLE) Angle = -Angle2 + 90 Angle = Angle MOD 360 IF Angle < 0 THEN Angle = 360 + Angle OPEN "rotate.tmp" FOR BINARY AS #1 XStep! = Sine(Angle) / 1024 * Scale YStep! = Cosine(Angle) / 1024 * Scale YStep2! = Cosine((Angle + 90) MOD 360) / 1024 * Scale XStep2! = Sine((Angle + 90) MOD 360) / 1024 * Scale xxx! = (x + (x2 - x) \ 2) - XStep! * ((x2 - x) \ 2) + YStep! * ((y2 - y) \ 2) yyy! = (y + (y2 - y) \ 2) - XStep2! * ((x2 - x) \ 2) + YStep2! * ((y2 - y) \ 2) FOR yy& = y TO y2 OrgY! = yyy! OrgX! = xxx! FOR xx& = x TO x2 Bt$ = " " GET #1, , Bt$ IF Scale = 1 THEN PSET (xxx!, yyy!), ASC(Bt$) PSET (xxx! + 1, yyy!), ASC(Bt$) PSET (xxx! + 1, yyy! + 1), ASC(Bt$) PSET (xxx!, yyy! + 1), ASC(Bt$) ELSE LINE (xxx!, yyy!)-(xxx! + (Scale + Scale \ 2) - 1, yyy! + (Scale + Scale / 2) - 1), ASC(Bt$), BF END IF xxx! = xxx! + XStep! yyy! = yyy! + YStep! NEXT yyy! = OrgY! - YStep2! xxx! = OrgX! - XStep2! NEXT CLOSE #1 END SUB SUB SaveSprite (file$, Num) VOffset& = CLNG(Num * 2) * 16384 'OPEN File$ FOR BINARY AS #1 'FOR i& = 0 TO 30720 ' Bt$ = CHR$(GetByte(i& + VOffset&)) ' PUT #1, , Bt$ 'NEXT 'CLOSE #1 OPEN file$ FOR BINARY AS #1 TempBuffer$ = SPACE$(16384) FOR I& = 0 TO 16383 MID$(TempBuffer$, I& + 1, 1) = CHR$(GetByte(I& + VOffset&)) NEXT PUT #1, , TempBuffer$ PRINT "þ"; VOffset& = VOffset& + 16384 TempBuffer$ = SPACE$(16384) FOR I& = 0 TO 16375 MID$(TempBuffer$, I& + 1, 1) = CHR$(GetByte(I& + VOffset&)) NEXT PUT #1, , TempBuffer$ PRINT "þ"; CLOSE #1 END SUB SUB SndSystem 'Checks if another buffer block needs to be transferred to the SB 'Call this whenever PlayingWAV& = True. IF PlayingWAV& = True AND DMADone% = -1 THEN WavOffset& = WavOffset& + BufferLen IF WavLength& - WavOffset& < BufferLen THEN PlayLength& = WavLength& - WavOffset& ELSE PlayLength& = BufferLen IF PlayLength& <= 0 THEN CLOSE #WavFileHandle& PlayingWAV& = False WavLength& = 0 WavOffset& = 0 WavFreq& = 0 ELSE GET #WavFileHandle&, , WavBuffer(0) DMAPlay VARSEG(WavBuffer(0)), VARPTR(WavBuffer(0)), PlayLength& - 1, WavFreq& END IF END IF END SUB SUB SpawnExplosion (XPos&, YPos&) Boom(ExplosionPointer).x = XPos& + RND * 30 - 15 Boom(ExplosionPointer).y = YPos& + RND * 30 - 15 Boom(ExplosionPointer).Radius = 1 Boom(ExplosionPointer).Col = 158 Boom(ExplosionPointer).Angle = 0 Boom(ExplosionPointer).Spin = RND * 8 + 1 ExplosionPointer = ExplosionPointer + 1 ExplosionPointer = ExplosionPointer MOD 11 END SUB SUB SpawnShot (Player) SELECT CASE Player CASE 1 Shot(1, ShotPointer1).x = (Player(1).XPos - Player(1).XVel \ 1024) + Sine(Player(1).Angle) / 1024 * 20 Shot(1, ShotPointer1).y = (Player(1).YPos + Player(1).YVel \ 1024) - Cosine(Player(1).Angle) / 1024 * 20 Shot(1, ShotPointer1).Angle = Player(1).Angle Shot(1, ShotPointer1).Col = 76& * 1024 Shot(1, ShotPointer1).Speed = 10 Player(1).HeatLevel = Player(1).HeatLevel + 1.2 ShotPointer1 = ShotPointer1 + 1 ShotPointer1 = ShotPointer1 MOD 101 ShotsFired(1) = ShotsFired(1) + 1 WAVPlayDMA "hit1.raw", 11025 CASE 2 Shot(2, ShotPointer2).x = (Player(2).XPos - Player(2).XVel \ 1024) + Sine(Player(2).Angle) / 1024 * 20 Shot(2, ShotPointer2).y = (Player(2).YPos + Player(2).YVel \ 1024) - Cosine(Player(2).Angle) / 1024 * 20 Shot(2, ShotPointer2).Angle = Player(2).Angle Shot(2, ShotPointer2).Speed = 10 Shot(2, ShotPointer2).Col = 60& * 1024 Player(2).HeatLevel = Player(2).HeatLevel + 1.2 ShotPointer2 = ShotPointer2 + 1 ShotPointer2 = ShotPointer2 MOD 101 ShotsFired(2) = ShotsFired(2) + 1 WAVPlayDMA "hit1.raw", 11025 END SELECT END SUB SUB UpdateEnergy (Player) VIEW SCREEN (0, 0)-(319, 199) SELECT CASE Player CASE 1 IF NOT Player(1).Energy <= 2 THEN Col& = 32& * 1024& XPos = (Player(1).Energy / 100) * 59 - 1 ColStep& = (16 / XPos) * 1024 FOR I& = 219 TO 219 + XPos LINE (I&, 185)-(I&, 194), Col& \ 1024 Col& = Col& + ColStep& NEXT LINE (219 + XPos + 1, 185)-(277, 194), 0, BF LINE (219 + XPos, 185)-(219 + XPos, 194), 15 END IF CASE 2 IF NOT Player(2).Energy <= 2 THEN Col& = 32& * 1024& XPos = (Player(2).Energy / 100) * 59 - 1 ColStep& = (16 / XPos) * 1024 FOR I& = 41 TO 41 + XPos LINE (I&, 185)-(I&, 194), Col& \ 1024 Col& = Col& + ColStep& NEXT LINE (41 + XPos + 1, 185)-(99, 194), 0, BF LINE (41 + XPos, 185)-(41 + XPos, 194), 15 END IF END SELECT VIEW SCREEN (0, 0)-(319, 179) END SUB SUB UpdateHeat (Player) VIEW SCREEN (0, 0)-(319, 199) SELECT CASE Player CASE 1 IF NOT Player(1).HeatLevel <= 2 THEN IF Player(1).OverHeat = 0 THEN IF Player(1).HeatLevel > 100 THEN Player(1).HeatLevel = 100 Col& = 208& * 1024& XPos = (Player(1).HeatLevel / 100) * 39 - 1 IF XPos > 0 THEN ColStep& = (16 / XPos) * 1024 FOR I& = 171 TO 171 + XPos LINE (I&, 191)-(I&, 194), Col& \ 1024 Col& = Col& + ColStep& NEXT LINE (171 + XPos + 1, 191)-(210, 194), 0, BF LINE (171 + XPos, 191)-(171 + XPos, 194), 15 END IF ELSE LINE (171, 191)-(210, 194), 64 + Blink, BF END IF END IF CASE 2 IF NOT Player(2).HeatLevel <= 2 THEN IF Player(2).OverHeat = 0 THEN IF Player(2).HeatLevel > 100 THEN Player(2).HeatLevel = 100 Col& = 208& * 1024& XPos = (Player(2).HeatLevel / 100) * 39 - 1 IF XPos > 0 THEN ColStep& = (16 / XPos) * 1024 FOR I& = 109 TO 109 + XPos LINE (I&, 191)-(I&, 194), Col& \ 1024 Col& = Col& + ColStep& NEXT LINE (109 + XPos + 1, 191)-(148, 194), 0, BF LINE (109 + XPos, 191)-(109 + XPos, 194), 15 END IF ELSE LINE (109, 191)-(148, 194), 64 + Blink, BF END IF END IF END SELECT VIEW SCREEN (0, 0)-(319, 179) END SUB SUB WAVPlayDMA (file$, Freq&) '---------------------------------------------------------------------------- ' Plays a WAV, VOC, SND sound file in the backround '---------------------------------------------------------------------------- ' ' File$ - File to be played ' Freq& - Playback frequency ' '---------------------------------------------------------------------------- ' Set volume levels with *Volume subs '---------------------------------------------------------------------------- IF PlayingWAV& = True THEN DmaState False CLOSE WavFileHandle& PlayingWAV& = False END IF WavFile = FREEFILE IF Exist(file$) = False THEN EXIT SUB OPEN file$ FOR BINARY AS #WavFile IF RIGHT$(UCASE$(file$), 3) = "WAV" THEN GET #WavFile, 44, WavBuffer(0) Length& = LOF(1) - 44 ELSE GET #WavFile, , WavBuffer(0) Length& = LOF(1) END IF DmaState True IF Length& > BufferLen THEN WavLength& = Length& WavFileHandle& = WavFile WavOffset& = 0 WavFreq& = Freq& Length& = BufferLen PlayingWAV& = True DMAPlay VARSEG(WavBuffer(0)), VARPTR(WavBuffer(0)), Length&, Freq& ELSE DMAPlay VARSEG(WavBuffer(0)), VARPTR(WavBuffer(0)), Length&, Freq& CLOSE #WavFile END IF END SUB SUB writedsp (Byte%) ' Writes a byte to the DSP DO LOOP WHILE INP(Baseport% + 12) AND &H80 OUT Baseport% + 12, Byte% END SUB