* * Stroids * * Step 1: create an asteroid field * * SLJ 4/99 * ORG $1000 ObjCX = 0 ObjCY = 2 ObjCZ = 4 ObjData = 6 ObjID = 8 ObjUser = 9 ObCenPos = 10 ObjCXRem = 11 ObjCYRem = 12 ObjCZRem = 13 ObjMat = 14 ObjSize = 32 ;32 bytes total ;Jump table Init3D = $5000 ;Initialize lib3d AddObj = Init3D+3 ;Add object to object list DelObj = AddObj+3 ;Delete object from list SetCurOb = DelObj+3 ;Set current object GetCurOb = SetCurOb+3 ;Get current object GetNextOb = GetCurOb+3 ;Get next object in list GetObj = GetNextOb+3 ;Get pointer to object SetMat = GetObj+3 ;Calculate and set object matrix Pitch = SetMat+3 ;Pitch - rotate object around x-axis Yaw = Pitch+3 ;Yaw - rotate around y-axis Roll = Yaw+3 ;Roll - rotate around z-axis MoveSide = Roll+3 ;Move object MoveUp = MoveSide+3 MoveForwards = MoveUp+3 GetSideVec = MoveForwards+3 ;Orientation vectors GetUpVec = GetSideVec+3 ;(length=64) GetFrontVec = GetUpVec+3 SetParms = GetFrontVec+3 ;Set rendering parameters SetVisParms = SetParms+3 ;Set visibility parameters CalcView = SetVisParms+3 ;Set viewpoint = object SortVis = CalcView+3 ;Compute and sort visible objects DrawAllVis = SortVis+3 ;Draw all visible objects DrawNextVis = DrawAllVis+3 ;Draw next objesible object list RotDraw = DrawNextVis+3 ;Rotate and draw object DrawFace = RotDraw+3;Draw single face (polygon) * obj3d tables OBCEN = $5781 ;Center object # ;Note: will bug if 128 vis objs CX = $5800 ;Rotated/relativecenters HCX = $5880 CY = $5900 HCY = $5980 CZ = $5A00 HCZ = $5A80 PLISTX EQU $5B00 ;Point lists (projected) PLISTY EQU $5C00 PLISTZ EQU $5D00 * lib3d stuff CALCMAT EQU $8800 ACCROTX EQU $8803 ACCROTY EQU $8806 ACCROTZ EQU $8809 GLOBROT EQU $880C ROTPROJ EQU $880F POLYFILL EQU $8812 PLOT EQU $8815 DRAWLINE EQU $8818 VERSION EQU $881B PQ EQU $0200 ;Point queue FILLPAT = $BB ;Pattern table pointer VIEWMAT = $4A XOFFSET = $53 ;Center of screen YOFFSET = $54 * Tables MULTLO EQU $C100 ;table of x^2 MULTHI EQU $C400 *=============================== BLAH = $02 temp = $58 point = $5a ;two bytes X1 = $60 ;Line x-coord Y1 = $62 X2 = $64 Y2 = $66 * * Handle the asteroid field. * * The field is characterized by a "density", which determines the total mass * of this part of the field. The entire field is not kept track of; rather, * the field only exists in a small area surrounding the player. * * Algorithm has three parts: * 1) If below density then create new asteroids. * 2) Drift asteroids * 3) Check for collisions * * OBS = $0800 ;Object records TAB1 = $0700 ;temporary table GETIN = $FFE4 Stroids JSR Init LDA #00 STA CURD :loop JSR CheckDensity JSR DriftStroids JSR SetRadar LDX VOB ;Calculate view JSR CalcView JSR SortVis ;Sort objects JSR DrawAllVis ;Draw objects JSR DrawRadar JSR CheckFire JSR SwapBuf LDX ROB ;Set rotation object JSR SetCurOb LDA VELOCITY JSR MoveForwards :wait LDA IRQFLAG BEQ :wait LDA #00 STA IRQFLAG JSR GETIN CMP #'a' BEQ :pitchdn CMP #'z' BEQ :pitchup CMP #'q' BEQ :rolll CMP #'w' BEQ :rollr CMP #'s' BEQ :yawl CMP #'d' BEQ :yawr CMP #'@' BEQ :incvel CMP #'/' BEQ :decvel CMP #'+' BEQ :incdens CMP #'-' BEQ :decdens CMP #'=' BEQ :wire CMP #' ' BEQ :swap CMP #'r' BEQ :rad LDX JOY BNE :joystick BEQ :loop :swap LDX VOB ;Swap viewpoint JSR SetCurOb JSR GetNextOb STX VOB JMP :loop :wire LDA SOLIDPOL EOR #$80 STA SOLIDPOL JMP :loop :yawr CLC DFB $24 :yawl SEC JSR Yaw JMP :loop :pitchup CLC DFB $24 :pitchdn SEC JSR Pitch JMP :loop :rolll CLC DFB $24 :rollr SEC JSR Roll JMP :loop :incdens INC DENSITY JMP :loop :decdens DEC DENSITY JMP :loop :incvel INC VELOCITY JMP :loop :decvel DEC VELOCITY JMP :loop :rad LDA RADFLAG EOR #$80 STA RADFLAG JMP :loop :joystick TXA AND #$01 BNE :pitchdn TXA AND #$02 BNE :pitchup TXA AND #$04 BNE :yawl TXA AND #$08 BNE :yawr JMP :loop VELOCITY DFB 00 * * DrawRadar -- Compute and draw radar * display, by creating a new object whose points are simply the * (scaled) object centers. * RADOFF = 24 ;Size of radar RADFLAG DFB #$00 ;Radar toggle IDENTITY DFB 64,0,0 ;Identity matrix DFB 0,64,0 DFB 0,0,64 * Set radar center to view center SetRadar LDX VOB JSR SetCurOb STA TEMP STY TEMP+1 LDX #00 JSR SetCurOb STA POINT STY POINT+1 LDY #5 :l LDA (TEMP),Y STA (POINT),Y DEY BPL :l rts2 RTS DrawRadar LDA RADFLAG BMI rts2 LDX #00 JSR GetObj STA POINT STY POINT+1 LDY #ObCenPos LDA (POINT),Y TAX LDA #200 ;First, cheat the center STA CZ,X ;by putting it at (0,0,200); note radar is object 0 LDA #03 ;(so projection will work out correctly -- don't want STA HCZ,X ;negative points!) LDX #8 :l1 LDA IDENTITY,X STA VIEWMAT,X ;Don't add any extra viewpoint rotation DEX BPL :l1 LDX NUMOBJS DEX STX RADOBJ+1 ;Number of points TXA CLC ADC #RADDAT ADC #00 STA TEMP+1 TXA ADC TEMP STA POINT ;z-coords LDA TEMP+1 ADC #00 STA POINT+1 LDY #00 ;Order doesn't matter :loop LDA CX,X STA X1 LDA HCX,X JSR DIV8X1 STA RADDAT,Y LDA CY,X STA X1 LDA HCY,X JSR DIV8X1 STA (TEMP),Y LDA CZ,X STA X1 LDA HCZ,X STA TAB1,Y ;Remember sign JSR DIV8X1 STA (POINT),Y INY :skip DEX BNE :loop ;0 is radar object STY RADOBJ+1 ;Number of points LDA XOFFSET ;Change coordinate offsets PHA LDA YOFFSET PHA LDA #RADOFF STA XOFFSET ;Upper-left cornerof screen STA YOFFSET LDX #00 JSR RotDraw PLA STA YOFFSET PLA STA XOFFSET :loop2 LDY RADOBJ+1 ;Now plot each point DEY LDA PLISTX,Y STA X1 LDA PLISTX+$80,Y STA X1+1 LDA PLISTY,Y STA Y1 LDA PLISTY+$80,Y STA Y1+1 LDA #RADOFF ;Line from center to point STA X2 STA Y2 LDA #00 STA X2+1 STA Y2+1 LDA #COLOR2 STA FILLPAT+1 LDA TAB1,Y ;Use different colors BMI :draw ;for front/back LDA #COLOR1 STA FILLPAT+1 :draw JSR DrawLine * JSR PLOT ;And plot! DEC RADOBJ+1 BNE :loop2 :rts RTS ;Whew! * * Divide X1,.A by 8 and normalize * DIV8X1 CMP #$80 ROR ROR X1 CMP #$80 ROR ROR X1 CMP #$80 ROR ROR X1 AND #$FF ;BMI, BEQ on exit BPL :pos ;Check between -95..94 CMP #$FF BNE :neg95 LDA X1 CMP #0-96 BCS :rts :neg95 LDA #0-96 ;fudge a bit :rts RTS :pos BNE :pos95 LDA X1 CMP #96 BCC :rts :pos95 LDA #95 RTS * * Handle fire special * CheckFire LDA JOY AND #$10 BNE Lase STA LCOUNT rts1 RTS LCOUNT DFB 00 Lase INC LCOUNT LDA LCOUNT AND #$03 BEQ rts1 LDA #00 STA Y1+1 STA Y2+1 STA X2+1 STA X1+1 ;Assume line from left STA X1 LDA #199 STA Y1 LDA #99 STA Y2 LDA SCRCEN STA X2 LDA #PATS STA FILLPAT+1 LDA LCOUNT AND #$04 BEQ :draw LDA X2 ;Draw from right ASL ;center*2 STA X1 ROL X1+1 :draw JMP DrawLine * * The My routines -- basically * just keep track of number of * objects (yep, should have included an * obj3d function to do this. * NUMOBJS DFB 00 MyAddObj INC NUMOBJS JMP AddObj MyDelObj DEC NUMOBJS JMP DelObj * * Density -- Check if we are at the right density. * If not, then create new asteroids. * DENSITY DFB 15 CURD DFB 00 ;Current density CheckDensity LDA $DC04 ;Semi-random AND #$07 BEQ rts1 TAX ;Wieght CLC ADC CURD CMP DENSITY BCS rts1 ;Don't always create one STA CURD LDA #SMALLOBJ CPX #1 BEQ :create LDA #MEDOBJ CPX #4 BCC :create LDA #BIGASS :create JSR MyAddObj ;Weight is ID STA POINT STY POINT+1 JSR NewCoord LDY #00 STA (POINT),Y INY TXA STA (POINT),Y JSR NewCoord INY STA (POINT),Y INY TXA STA (POINT),Y JSR NewCoord INY STA (POINT),Y INY TXA STA (POINT),Y LDA $DC04 BPL :and ORA #$F8 DFB $2C :and AND #$07 ORA #01 LDY #ObjUser ;Velocity STA (POINT),Y JSR Randy PHA JSR Randy PHA JSR Randy TAX PLA TAY PLA JSR SetMat ;Random orientation JMP CheckDensity * * Generate a coordinate offset in .AX * NewCoord JSR Randy LDX #$01 LSR BCC :rol LDX #$FE :rol ROL RTS * * Randy -- Generate a random number using middle-squares * ARLEN DFB 00 ;Max sequence length RAND DFB 00 Randy STY TEMP+1 DEC ARLEN BPL :grand LDA $DC04 ;Re-seed ORA #$10 ;Make sure nonzero STA RAND LDA #30 STA ARLEN :grand LDY RAND LDA MULTHI,Y STA TEMP LDA MULTLO,Y ;.A,TEMP = x^2/4 LSR TEMP ROR LSR TEMP ROR ;Now = middle 8 bits CMP RAND BNE :sta EOR #%10101010 :sta STA RAND LDY TEMP+1 RTS * * DriftStroids * * Goes through all asteroids, moving * each forwards. Asteroids which drift * out of the play area are removed. * DriftStroids LDX #00 ;Always present JSR SetCurOb :loop JSR GetNextOb STA POINT STY POINT+1 TXA BEQ :rts LDY #ObjID LDA (POINT),Y BMI :loop ;Find first stroid LDY #ObjUser LDA (POINT),Y ;Velocity JSR MoveForwards LDY #01 ;Check if left play area LDA (POINT),Y BPL :c1 EOR #$FF CLC ADC #01 :c1 CMP #06 ;Around 3000 units wide total BCS :del LDY #03 LDA (POINT),Y BPL :c2 EOR #$FF CLC ADC #01 :c2 CMP #06 BCS :del LDY #05 LDA (POINT),Y BPL :c3 EOR #$FF CLC ADC #01 :c3 CMP #06 BCC :loop :del LDY #ObjID ;Return mass LDA CURD SBC (POINT),Y STA CURD JSR GetCurOb ;Set .X JSR MyDelObj JMP :loop :rts RTS * * IRQ routine * IRQFLAG DFB 00 JOY DFB 00 FIRE DFB 00 HIT DFB 00 EXPLODE DFB 00 THRUST DFB 00 IRQ INC IRQFLAG LDA $DC00 EOR #$FF AND #$1F STA JOY LDA FIRE BEQ :c1 JSR SoundFire :c1 LDA HIT BEQ :c2 JSR SoundHit :c2 LDA EXPLODE BEQ :c3 JSR SoundExplode :c3 LDA THRUST BEQ :bye JSR SoundThrust :bye JMP $EA7B SoundFire SoundHit SoundExplode SoundThrust RTS * * Init code * SCRCEN DFB 00 SOLIDPOL DFB $80 Init SEI LDA #IRQ STA $0315 CLI LDA #$76 STA $01 LDA $D011 ORA #$20 ;Bitmap mode STA $D011 LDA #$08 ;Bitmap -> $6000 STA $D018 LDA $DD00 AND #$F8 ORA #$02 ;Bank 1 STA $DD00 LDA #$80 STA $028A ;All keys repeat LDA #00 STA NUMOBJS STA VELOCITY JSR VERSION ;If multicolor... BPL :hires LDA $D016 ORA #$10 STA $D016 LDA #79 DFB $2C :hires LDA #159 STA SCRCEN JSR ClrColMap LDA #OBS JSR Init3D LDA #RADOBJ LDX #$FF JSR MyAddObj ;Radar object = object 0 LDA #TETDAT LDX #$80 ;ID JSR MyAddObj STX VOB ;View object LDA #STARDAT LDX #$81 JSR MyAddObj STX ROB ;Rotate object STA POINT ;Object pointer STY POINT+1 LDY #5 ;Set center :l1 LDA OCEN,Y STA (POINT),Y DEY BPL :l1 * Set up bitmap, pointers etc. SwapBuf ;Swap buffers and clear LDA $DD00 EOR #$03 STA $DD00 LDX #$60 ;Bitmap at $6000 or $A000 LSR BCS :setp LDX #$A0 :setp LDA SOLIDPOL ;Solid polygons CMP #$80 LDA #PATS JSR SetParms ClrBitmap CPX #$A0 BEQ :cleara LDY #00 TYA :loop STA $6000,Y STA $6100,Y STA $6200,Y STA $6300,Y STA $6400,Y STA $6500,Y STA $6600,Y STA $6700,Y STA $6800,Y STA $6900,Y STA $6A00,Y STA $6B00,Y STA $6C00,Y STA $6D00,Y STA $6E00,Y STA $6F00,Y STA $7000,Y STA $7100,Y STA $7200,Y STA $7300,Y STA $7400,Y STA $7500,Y STA $7600,Y STA $7700,Y STA $7800,Y STA $7900,Y STA $7A00,Y STA $7B00,Y STA $7C00,Y STA $7D00,Y STA $7E00,Y STA $7F00,Y INY BNE :loop RTS :cleara LDY #00 TYA :loop2 STA $A000,Y STA $A100,Y STA $A200,Y STA $A300,Y STA $A400,Y STA $A500,Y STA $A600,Y STA $A700,Y STA $A800,Y STA $A900,Y STA $AA00,Y STA $AB00,Y STA $AC00,Y STA $AD00,Y STA $AE00,Y STA $AF00,Y STA $B000,Y STA $B100,Y STA $B200,Y STA $B300,Y STA $B400,Y STA $B500,Y STA $B600,Y STA $B700,Y STA $B800,Y STA $B900,Y STA $BA00,Y STA $BB00,Y STA $BC00,Y STA $BD00,Y STA $BE00,Y STA $BF00,Y INY BNE :loop2 RTS ClrColMap ;Only need to call once LDX #00 LDA #$12 :loop STA $4000,X STA $4100,X STA $4200,X STA $4300,X STA $8000,X STA $8100,X STA $8200,X STA $8300,X INX BNE :loop JSR VERSION BPL :rts LDA #00 ;Multicolor mode STA $D020 STA $D021 LDA #14 :l2 STA $D800,X STA $D900,X STA $DA00,X STA $DB00,X INX BNE :l2 :rts RTS VOB DFB 00 ;View object ROB DFB 00 ;2nd object OCEN DA 00 ;X-coord DA 00 ;Y-coord DA $0100 ;Z-coord PATS ;Pattern table SOLID = 0 HEX FFFFFFFFFFFFFFFF DITHER1 = 1 HEX 55AA55AA55AA55AA DITHER2 = 2 HEX AA55AA55AA55AA55 ZIGS = 3 HEX EEDDBB77EEDDBB77 ZAGS = 4 HEX 77BBDDEE77BBDDEE ZIGZAG = 5 HEX BB55EEFFBB55EEFF CROSSSM = 6 HEX 55EE55BB55EE55BB BRICK = 7 HEX 00EEEEEE00BBBBBB SQUARES = 8 HEX FFAAFFAAFFAAFFAA INVSQ = 9 HEX 0055005500550055 HOLES = 10 HEX BD7EE7DBDBE77EBD HSTRIPES = 11 HEX FF00FF00FF00FF00 VSTRIPES = 12 HEX AAAAAAAAAAAAAAAA COLOR1 HEX 5555555555555555 COLOR2 HEX AAAAAAAAAAAAAAAA * * Test object 1: simple tetrahedron * BIGASS TETDAT DFB 0 ;Normal object DFB 4 ;Number of points DFB 4 ;Number of faces * Point list TETX DFB 52,52,0-52,0-52 TETY DFB 52,0-52,52,0-52 TETZ DFB 52,0-52,0-52,52 * Face list FACE1 DFB 3 ;Number of vertices DFB SOLID ;Fill pattern DFB 0,1,2,0 ;Vertices FACE2 DFB 3 DFB ZIGS DFB 3,2,1,3 FACE3 DFB 3 DFB CROSSSM DFB 3,0,2,3 FACE4 DFB 3 DFB HOLES DFB 3,1,0,3 * * Test object 2: medium object * MEDOBJ DFB 0 ;Normal object DFB 4 ;Number of points DFB 4 ;Number of faces * Point list DFB 30,30,0-30,0-30 DFB 30,0-30,30,0-30 DFB 30,0-30,0-30,30 * Face list DFB 3 ;Number of vertices DFB DITHER1 ;Fill pattern DFB 0,1,2,0 ;Vertices DFB 3 DFB DITHER2 DFB 3,2,1,3 DFB 3 DFB BRICK DFB 3,0,2,3 DFB 3 DFB SOLID DFB 3,1,0,3 * * Object 3: small object * SMALLOBJ DFB 0 ;Normal object DFB 4 ;Number of points DFB 4 ;Number of faces * Point list DFB 10,10,0-10,0-10 DFB 10,0-10,10,0-10 DFB 10,0-10,0-10,10 * Face list DFB 3 ;Number of vertices DFB ZIGS ;Fill pattern DFB 0,1,2,0 ;Vertices DFB 3 DFB ZAGS DFB 3,2,1,3 DFB 3 DFB HSTRIPES DFB 3,0,2,3 DFB 3 DFB VSTRIPES DFB 3,1,0,3 * * Test object 2: a compound object, * spaceship-kind of thing (essentially * cool world stars) * STARDAT DFB $80 ;Compound object DFB 14 ;Number of points DFB 6 ;Number of oblets * Point list DFB 50,0-50,0,0,0,0,15,15,15,15,0-15,0-15,0-15,0-15 DFB 0,0,16,0-26,0,0,10,10,0-10,0-10,10,10,0-10,0-10 DFB 0,0,0,0,94,0-22,15,0-15,0-15,15,15,0-15,0-15,15 * Oblet list: reference points DFB 0 ;First 6 points DFB 1 DFB 2 DFB 3 DFB 4 DFB 5 * Oblet 1 DFB 26 ;26 bytes DFB 4 ;4 faces * faces DFB 3 ;4 points DFB SOLID ;pattern DFB 0,8,7,0 ;Star 2, Tine 0, face 1 DFB 3 DFB ZIGS DFB 0,7,6,0 DFB 3 DFB ZAGS DFB 0,6,9,0 DFB 3 DFB DITHER1 DFB 0,9,8,0 * Oblet 2 DFB 26 ;26 bytes DFB 4 ;4 faces DFB 3 ;4 points DFB ZIGS DFB 1,11,12,1 DFB 3 DFB BRICK DFB 1,12,13,1 DFB 3 DFB DITHER2 DFB 1,13,10,1 DFB 3 DFB ZAGS DFB 1,10,11,1 * Oblet 3 DFB 26 ;26 bytes DFB 4 ;4 faces DFB 3 DFB SQUARES DFB 2,7,11,2 DFB 3 DFB INVSQ DFB 2,6,7,2 DFB 3 DFB DITHER1 DFB 2,10,6,2 DFB 3 DFB DITHER2 DFB 2,11,10,2 * Oblet 4 DFB 26 DFB 4 DFB 3 DFB CROSSSM DFB 3,12,8,3 DFB 3 DFB HOLES DFB 3,8,9,3 DFB 3 DFB VSTRIPES DFB 3,9,13,3 DFB 3 DFB SOLID DFB 3,13,12,3 * Oblet 5 DFB 26 ;26 bytes DFB 4 ;4 faces DFB 3 DFB DITHER1 DFB 4,9,6,4 DFB 3 DFB SOLID DFB 4,6,10,4 DFB 3 DFB DITHER2 DFB 4,10,13,4 DFB 3 DFB HSTRIPES DFB 4,13,9,4 * Oblet 6 DFB 26 ;26 bytes DFB 4 ;4 faces DFB 3 DFB ZIGZAG DFB 5,8,12,5 DFB 3 DFB HSTRIPES DFB 5,12,11,5 DFB 3 DFB VSTRIPES DFB 5,11,7,5 DFB 3 DFB DITHER2 DFB 5,7,8,5 * * Radar object. To do the radar, an object is used whose points are simply * the translated and rotated object centers. This object is then projected * using the obj3d routines, and the points plotted. * RADOBJ DFB 0 ;Normal object DFB 0 ;Number of points DFB 0 ;Number of faces * Point list RADDAT