cruisin-usa/COLLA.ASM

4176 lines
78 KiB
NASM
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

.FILE "COLLA.ASM"
*----------------------------------------------------------------------------
*COLLISION SYSTEM
*
*COPYRIGHT (C) 1994 BY TV GAMES, INC.
*ALL RIGHTS RESERVED
*
.include C30.EQU
.include MACS.EQU
.include MPROC.EQU
.include OBJ.EQU
.include VUNIT.EQU
.include CMOS.EQU
.include SYSID.EQU
.include SYS.EQU
.include GLOBALS.EQU
.include SNDTAB.EQU
.include PALL.EQU
.include OBJECTS.EQU
.include TEXT.EQU
.include DIRQ.EQU
.include DELTA.EQU
.include COMM.EQU
.text
.GLOBL WRECKST,WRECKFLG,CHEAT
.globl CAMVIEW,PACTIVEI,COLSCC
.globl DRONESND,DRONESND1
.globl DRONINBZ
.globl ROADIR,GETFLYMAT
.globl CKAHEAD
VLI .word VL
.bss VL,4
TNORMI .word TNORM
.bss TNORM,3
TVECT1I .word TVECT1
.bss TVECT1,3
TVECT2I .word TVECT2
.bss TVECT2,3
TMATRIXI
.word TMATRIX
.bss TMATRIX,9
.bss COLVEL,1 ;RELATIVE COLLISION VELOCITY
.bss PMULT,1 ;PLAYER SLOW COLLISION VELOCITY MULTIPLIER
.bss SPINTEMP,1
*----------------------------------------------------------------------------
*CAMERA SCAN FOR ROAD HEIGHT
*
*PARAMETERS
* AR4 POINTS TO VECTOR CAMERA X,Y,Z
*RETURNS
* R0 = CAMERA HEIGHT ABOVE THE ROAD
* CS = COLLISION FOUND WITH ROAD
* CC = NO COLLISION FOUND
*
CAMSCAN:
LDPI @DRIVE_LIST,R0
CALL CAMSCANS
RETSC
LDPI @GROUND_LIST,R0
*FALL THRU TO CAMSCANS
*
*SCAN LIST FOR POINT-OBJECT INTERSECTION
CAMSCANS
BZ CMSX ;NULL LIST DUDES
LDI R0,AR2
LDI OPOSZ,IR1
LDF *+AR4(2),R2 ;GET POINT X
LDF *AR4,R3 ;GET POINT Z
CMS0
SUBF *+AR2(OPOSX),R3,R0
SUBF *+AR2(IR1),R2,R1
MPYF R1,R1
CMS1
MPYF R0,R0
ADDF R1,R0
FLOAT *+AR2(ORAD),R1 ;GET ROAD RADIUS
MPYF R1,R1
CMPF R1,R0 ;DISTANCE < RADIUS ?
BLT CMS2 ;YES, CHECK IT OUT
LDI *+AR2(OLINK3),AR2
LDI AR2,R1
BNZD CMS1
SUBF *+AR2(OPOSX),R3,R0
SUBF *+AR2(IR1),R2,R1
MPYF R1,R1
;----> BNZ CMS1
B CMSX ;WE FAILED
*CHECK OUT POINT COLLISION
CMS2
CALL _coll_road ;XZ POINT COLLISION WITH ROAD OBJECT?
BNC CMS1L
RETS ;RETURN COLLISION VALUE
CMS1L
LDI *+AR2(OLINK3),AR2
LDI AR2,R1
BNZD CMS0
LDI OPOSZ,IR1
LDF *+AR4(2),R2 ;GET POINT X
LDF *AR4,R3 ;GET POINT Z
;----> BNZ CMS0
CMSX
FLOAT 0,R0 ;DEFAULT HT.
CLRC
RETS
*----------------------------------------------------------------------------
*SCAN OBJECT CENTER POINT VERSUS ROAD
*
*PARAMETERS
* AR4 OBJECT
*RETURNS
* CARRY SET IF ROAD FOUND BELOW OBJECT
OBJSCAN:
PUSH AR4
ADDI OPOSX,AR4
CALL CAMSCAN ;AR4=XYZ, RET R0=HT, CS=ROAD,CC=NO ROAD
POP AR4
RETS
*----------------------------------------------------------------------------
*SCAN COLLSION BOX VS. ROAD
*
*AR4=OBJECT
*RET=R0=HT ABOVE ROAD (MIN)
*CS=FOUND A HIT, CC= NOTHING BELOW
.DEF BOXSCAN
FBSS BOXSCRAM,50
BOXSCRAMI .WORD BOXSCRAM
*
*CHECK ROAD OBJECTS ON ROAD LIST IN RANGE
*
BOXSCAN:
PUSH AR5
LDPI @BOXSCRAMI,AR2
LDI AR4,AR0 ;GET OBJ IN AR0 FOR GETBOX
LDF 0.7,R0 ;XMINUS MULT FACTOR
LDF 0.7,R1 ;YMINUS MULT FACTOR
LDF 0.7,R2 ;ZMINUS MULT FACTOR
LDF 0.7,R3 ;XPLUS MULT FACTOR
LDF 1.0,R4 ;YPLUS MULT FACTOR
LDF 0.7,R5 ;ZPLUS MULT FACTOR
CALL GETBOX0 ;GET BOX POINTS FOR OBJECT 1
FLOAT *+AR4(ORAD),R5 ;GET ROAD RADIUS
FLOAT 20000,R7 ;DEFAULT CAR HT. ABOVE GROUND
LDPI @DRIVE_LIST,R0
CALL BOXSCSUB
LDPI @GROUND_LIST,R0
CALL BOXSCSUB
POP AR5
LDF R7,R0
FLOAT 20000,R7
CMPF R7,R0
BLT BS3X
CLRC ;NOTHING FOUND
RETS
BS3X
SETC
RETS
*
*SCAN BOX FOR GROUND INTERSECTION
*R0=LIST
*AR4=OBJECT
*R5=QUICK REJECT LIMIT
*R7=LOWEST HEIGHT SO FAR
*
BOXSCSUB
BZ BSCX ;NULL LIST DUDES
LDI R0,AR2
LDI OPOSZ,IR1
BS0
FLOAT *+AR4(ORAD),R0 ;GET BOX RADIUS
LDF *+AR4(OPOSZ),R4 ;GET OBJECT Z
LDF *+AR4(OPOSX),R3 ;GET OBJECT X
SUBF *+AR2(OPOSX),R3,R2
SUBF *+AR2(IR1),R4,R1
MPYF R1,R1
BS1
MPYF R2,R2
ADDF R1,R2
FLOAT *+AR2(ORAD),R1 ;GET ROAD RADIUS
ADDF R0,R1 ;ADD AND SQUARE
MPYF R1,R1
CMPF R1,R2 ;TEST TRUE RADIUS
BLT BS2 ;NO GO...
LDI *+AR2(OLINK3),AR2
LDI AR2,R1
BNZD BS1
SUBF *+AR2(OPOSX),R3,R2
SUBF *+AR2(IR1),R4,R1
MPYF R1,R1
;----> BNZ BS1
RETS
*CHECK OUT POINT COLLISION
BS2
PUSH AR4
LDPI @BOXSCRAMI,AR4
ADDI 18H,AR4
LDI 7,AR5 ;LOOP 8 BOX POINTS
BSRDLP
CALL _coll_road ;XZ POINT COLLISION WITH ROAD OBJECT?
BNC BS10 ;NOPE...
CMPF R0,R7
LDFGT R0,R7 ;SAVE LOWEST POINT
BS10
NOP *AR4++(3) ;CHECK NEXT POINT
DB AR5,BSRDLP
LDI *+AR2(OLINK3),R0
BNZD BS0
LDI R0,AR2
POP AR4
LDI OPOSZ,IR1
;----> BNZ BS0
BSCX
RETS
*----------------------------------------------------------------------------
*CHECK VEHICLE COLLISION WITH ROAD
*
*PARAMETERS
* AR4 OBJECT
* R3 POINTER TO CARVCT RAM AREA
* RAM AREA= 3*(X,Y,Z,ROAD Y,Y VEL,COLLISION OBJECT)
* ONROAD,AIRFRONT,AIRBORNE (1=TRUE)
*RETURNS
* CARVCT AREA MODIFIED,FLAGS SET, OBJECT MATRIX ALIGNED TO ROAD
* NEED TO ADD Y RADIANS AFTERWARD
*
CAR_ROAD_COLL:
PUSH R4
PUSH R5
PUSH AR3
PUSH AR4
PUSH AR5
PUSH AR6
CALL ROADSCAN ;GET POINT HEIGHTS
****************************************************
*WE HAVE FOUND HEIGHT FOR ALL SUSPENSION POINTS
*GET NEW PLAYER MATRIX
PC1XX
LDI *+AR6(CT_PCOL),R0 ;NO ROAD COLLISION CENTER POINT
BZ PC1X0
LDI R0,AR0
LDI *+AR0(OID),R0
AND CLASS_M+TYPE_M,R0
STI R0,*+AR6(CAR_ONROAD) ;XXX OID->ONROAD FLAG
PC1X0
LDI AR6,AR0 ;GET CARVCT SUSPENSION POINTS
FLOATP @NFRAMES,R2
MPYF 4,R2 ;FRAME ADJUSTED GRAVITY
; MPYF 8,R2 ;FRAME ADJUSTED GRAVITY
LDI CARVNUM-1,RC ;LOOP FOR ALL GROUND TOUCHERS
RPTB PC2
LDF *+AR0(CARPRDYD),R0 ;LOAD DELTA HEIGHT
CMPF -9,R0
BGT PC1A ;WE ARE ABOVE ROAD
*BELOW ROAD CASE
ADDF -9,R0
ADDF *+AR0(CARPY),R0 ;WE ARE BELOW ROAD
BD PC2
STF R0,*+AR0(CARPY) ;SET TO ROAD HEIGHT
LDF 0,R0
STF R0,*+AR0(CARPYV) ;STORE NEW VELOCITY
;-------->B PC2
*ABOVE ROAD CASE
PC1A
LDF *+AR0(CARPYV),R1 ;GRAVITY ACCELERATES Y VEL
ADDF R2,R1
LDI *+AR0(CARPCOL),R4 ;CHECK GRAVITY TYPE
BZ PC1B
LDI R4,AR3
LDI *+AR3(OID),R4
AND CLASS_M+TYPE_M,R4
CMPI ROAD_C+LOGRAV_T,R4
; BNE PC1AA
; NOP
;PC1AA
BEQ PC1B ;LOGRAVITY SECTION?
LDF R2,R4
MPYF 4,R4 ;NO, GRAV X 4
ADDF R4,R1
PC1B
CMPF R1,R0 ;VEL GT HEIGHT?
BGT PC2A ;NO
LDF R0,R1 ;YES LIMIT VELOCITY
PC2A
STF R1,*+AR0(CARPYV) ;ADD VELOCITY TO HEIGHT
PC2B
ADDF *+AR0(CARPY),R1
STF R1,*+AR0(CARPY)
PC2 NOP *AR0++(CARVSIZ)
*SET AIRBORNE FLAGS
LDI AR6,AR0 ;GET CARVCT SUSPENSION POINTS
LDI 1,R0 ;ASSUME AIRBORNE
LDI 1,R1
LDF *+AR0(3),R2 ;LOAD DELTA HEIGHT
CMPF 72,R2 ;1 FOOT OFF GROUND?
LDILT 0,R0 ;NO
LDF *+AR0(9),R2
CMPF 72,R2 ;1 FOOT OFF GROUND?
LDILT 0,R1 ;NO
LDF *+AR0(15),R2
CMPF 72,R2 ;1 FOOT OFF GROUND?
LDILT 0,R1 ;NO
STI R0,*+AR6(CAR_AIRB)
STI R1,*+AR6(CAR_AIRF)
LDI AR6,R0 ;get suspension points in ram
LDPI @VLI,AR0 ;rotate for universe etc.
STI R0,*AR0++
ADDI CARVSIZ,R0
STI R0,*AR0++
ADDI CARVSIZ,R0
STI R0,*AR0++
CALL GETNMAT ;GET NEW MATRIX
PCOLLX
POP AR6
POP AR5
POP AR4
POP AR3
POP R5
POP R4
RETS
*----------------------------------------------------------------------------
*ROADSCAN - FIND COLLISION HEIGHTS FOR ALL WHEELS
*
*PARAMETERS
* AR4 CAR OBJECT
* R3 CAR BLOCK
*
ROADSCAN:
LDI R3,AR6 ;SAVE CARVCT RAM POINTER
*PROJECT CAR SUSPENSION POINTS
LDI AR4,R2
ADDI OMATRIX,R2 ;POINT TO CAR MATRIX
LDI AR6,AR2
ADDI CARWHLTAB,AR2
LDF *+AR4(OPOSX),R1 ;GET Y OBJECT OFFSET
LDF *+AR4(OPOSY),R4 ;GET Y OBJECT OFFSET
LDF *+AR4(OPOSZ),R5 ;GET Z OBJECT OFFSET
LDI 2,IR0
LDI CARVNUM-1,RC ;LOOP FOR ALL POINTS
RPTB LOOP
LDI R3,AR3
CALL MATRIX_MUL
*ADD IN X,Z OFFSETS
ADDF R1,*AR3,R0
ADDF R4,*+AR3(1),R0
|| STF R0,*AR3
STF R0,*+AR3(1)
; NEGF R0 ;DEFAULT COLLISION DELTA = - HEIGHT
LDF 0,R0 ;CLEAR DEFAULT HEIGHT
STF R0,*+AR3(3)
LDI 0,R0
STI R0,*+AR3(5) ;CLEAR COLLISION OBJECT
ADDF R5,*+AR3(IR0),R0
STF R0,*+AR3(2)
ADDI 3,AR2
LOOP ADDI 6,R3
CLRI R0
STI R0,*+AR6(CAR_ONROAD)
*CHECK ROAD OBJECTS ON ROAD LIST IN RANGE
LDPI @DRIVE_LIST,R0
CALL RDSCNSUB
*WE HAVE SCANNED ROADLIST
*IF INCOMPLETE SCAN DO GROUND LIST
LDI *+AR6(CT_PCOL),R0 ;CHECK COLLISION...
OR *+AR6(LF_PCOL),R0 ;CHECK COLLISION...
OR *+AR6(RF_PCOL),R0 ;CHECK COLLISION...
OR *+AR6(RR_PCOL),R0 ;CHECK COLLISION...
OR *+AR6(LR_PCOL),R0 ;CHECK COLLISION...
LDINZ 1,R0
STI R0,*+AR6(CAR_ONROAD) ;ANY WHEEL ON IS ONROAD
LDI 0,R1
LDI *+AR6(CT_PCOL),R0 ;CHECK COLLISION...
LDIZ 1,R1 ;SET FLAG IF NONE
; BZ PC3A
LDI *+AR6(LF_PCOL),R0 ;CHECK COLLISION...
LDIZ 2,R1
; BZ PC3A
LDI *+AR6(RF_PCOL),R0 ;CHECK COLLISION...
LDIZ 3,R1
; BZ PC3A
LDI *+AR6(RR_PCOL),R0 ;CHECK COLLISION...
LDIZ 4,R1
; BZ PC3A
LDI *+AR6(LR_PCOL),R0 ;CHECK COLLISION...
LDIZ 5,R1
; BZ PC3A
LDI R1,R1 ;ALL WHEELS ON ROAD?
BZ PC3X ;YES...WERE DONE
*OFF ROAD- CHECK OUT GROUND LIST
PC3A
LDPI @GROUND_LIST,R0
CALL RDSCNSUB
; LDI 0,R1
; LDI *+AR6(CT_PCOL),R0 ;CHECK COLLISION...
; LDIZ 1,R1 ;SET FLAG IF NONE
; LDI *+AR6(LF_PCOL),R0 ;CHECK COLLISION...
; LDIZ 2,R1
; LDI *+AR6(RF_PCOL),R0 ;CHECK COLLISION...
; LDIZ 3,R1
; LDI *+AR6(RR_PCOL),R0 ;CHECK COLLISION...
; LDIZ 4,R1
; LDI *+AR6(LR_PCOL),R0 ;CHECK COLLISION...
; LDIZ 5,R1
; LDI R1,R1 ;ALL WHEELS ON ROAD?
; BZ PC3X ;YES...WERE DONE
; NOP ;TRAP HERE
PC3X
RETS
*----------------------------------------------------------------------------
*ROAD SCAN SUBROUTINE
*
*PARAMETERS
* R0 LIST TO SCAN
* AR4 CAR OBJECT
*
RDSCNSUB:
BZD RDSCNX ;NULL LIST
LDI R0,AR2
LDI OPOSZ,IR1
FLOAT *+AR4(ORAD),R0 ;GET BOX RADIUS
;------>BZD RDSCNX ;NULL LIST
LDF *+AR4(OPOSZ),R4 ;GET OBJECT Z
RS0
LDF *+AR4(OPOSX),R3 ;GET OBJECT X
RS1
SUBF *+AR2(OPOSX),R3,R2
SUBF *+AR2(IR1),R4,R1
MPYF R1,R1
MPYF R2,R2
ADDF R1,R2
FLOAT *+AR2(ORAD),R1 ;GET ROAD RADIUS
ADDF R0,R1 ;ADD AND SQUARE
MPYF R1,R1
CMPF R1,R2 ;TEST TRUE RADIUS
BLT RS2 ;CHECK IT OUT !
RS1L
LDI *+AR2(OLINK3),AR2
LDI AR2,R1
BNZD RS1
SUBF *+AR2(OPOSX),R3,R2
SUBF *+AR2(IR1),R4,R1
MPYF R1,R1
;----> BNZ RS1
RETS
*CHECK OUT ROAD COLLISION
RS2
PUSH AR4
LDI AR6,AR4
LDI CARVNUM-1,AR5 ;LOOP ALL POINTS
RS3LP
LDI *+AR4(CARPCOL),R1 ;CHECK PRIOR COLLISION...
BZ RS300 ;NOPE, SCAN ON...
ABSF *+AR4(CARPRDYD),R1
FLOAT 2000,R2
CMPF R2,R1
BLT RS30 ;ALREADY CLOSE, NO RESCAN...
CALL _coll_road ;XZ POINT COLLISION WITH ROAD OBJECT?
BNC RS30 ;NOPE...
LDF *+AR4(CARPRDYD),R1
BNN RS297
LDF R0,R0
BNN RS301 ;OLD=NEG, NEW=POS, GO W/ POS
*BOTH NEGATIVE CASE
CMPF R0,R1
BGT RS30
B RS301
*OLD IS POSITIVE
RS297
LDF R0,R0
BNN RS299
*OLD IS POS, NEW IS NEG
FLOAT -1000,R2
CMPF R2,R0
BGT RS301
B RS30
*BOTH POSITIVE CASE
RS299
CMPF R0,R1 ;TAKE LEAST POSITIVE
BLT RS30
B RS301
RS300
CALL _coll_road ;XZ POINT COLLISION WITH ROAD OBJECT?
BNC RS30 ;NOPE...
RS301
STF R0,*+AR4(CARPRDYD) ;SAVE ROAD Y DELTA
STI AR2,*+AR4(CARPCOL) ;SAVE COLLISION OBJECT
RS30
NOP *AR4++(CARVSIZ)
DB AR5,RS3LP
POP AR4
RS3L
LDI *+AR2(OLINK3),AR2
LDI AR2,R0
BNZD RS0
LDI OPOSZ,IR1
FLOAT *+AR4(ORAD),R0 ;GET BOX RADIUS
LDF *+AR4(OPOSZ),R4 ;GET OBJECT Z
;----> BNZ RS0
RDSCNX
RETS
*----------------------------------------------------------------------------
*coll_road(OBJECTP _obj)
*PARMETERS
* AR2 colliding object
* AR4 POINT VECTOR X,Y,Z
*RETURNS
* R0 -HEIGHT ABOVE ROAD
* CARRY SET IF ROAD PIECE COLLISION
*
_coll_road:
LDI AR4,R2 ;GET POINT INTO R2
CALL _obj_coll
BNC CRX ;NO COLLISION BAIL OUT WITH CARRY CLEAR
*
*WE HAVE A COLLISION
*FIND Y HEIGHT RETURN IN R0
*
;generate a (unit) normal for the actual plane
PUSH R4
PUSH R5
PUSH AR2
PUSH R6
PUSHF R6
PUSH R7
PUSHF R7
LDPI @VLI,AR2 ;rotate for universe etc.
LDPI @TNORMI,AR0
CALL GEN_NORMAL ;gen_normal(&A,&B,&C,&N);
LDPI @VLI,AR1
LDI *AR1,AR1
MPYF *AR1++,*AR0++,R0
NEGF *AR0,R1 ;N.y
MPYF *AR1++,*AR0++,R2
ADDF R2,R0 ;D = - (N.x * bufferx[vert[0]] +
MPYF *AR1++,*AR0++,R2 ; N.y * buffery[vert[0]] +
ADDF R2,R0 ; N.z * bufferz[vert[0]]);
NEGF R0 ;D = ((D/(-N.y)));
CALL DIV_F30 ;(R0/R1)->R0 clobbers r0,r1,ar0,ar1
POPF R7
POP R7
POPF R6
POP R6
POP AR2
POP R5
POP R4
SETC ;WE GOT ONE
CRX
RETS
*----------------------------------------------------------------------------
*GET MATRIX TO ALIGN WITH NORMAL, Z AND X AXES ROTATION ONLY
*
*VL1=POINTER TO 3 POINTS
*AR4=OBJECT
*AR6=CARVCT RAM AREA
*
GETNMAT:
;*GENERATE A (UNIT) NORMAL FOR THE PLANE
LDPI @VLI,AR2 ;rotate for universe etc.
LDPI @TNORMI,AR0
CALL GEN_NORMAL ;gen_normal(&A,&B,&C,&N);
LDI AR0,AR2
CALL NORMALIZE ;normalize(&N);
LDPI @TMATRIXI,AR3
*LOAD 2ND COLUMN OF ROTATION MATRIX (Y AXIS)
LDF *AR2,R0 ;2ND COLUMN ROT MATRIX IS NORMAL VECTOR
STF R0,*+AR3(3)
LDF *+AR2(1),R1
STF R1,*+AR3(4)
LDF *+AR2(2),R2
STF R2,*+AR3(5)
*LOAD 1ST COLUMN OF ROTATION MATRIX (X AXIS)
LDI AR3,AR2
STF R1,*AR2 ;X
NEGF R0 ;-N2
STF R0,*+AR2(1) ;Y
CLRF R1
STF R1,*+AR2(2) ;Z
CALL NORMALIZE ;normalize(&N);
*LOAD 3RD COLUMN OF ROTATION MATRIX (Z AXIS)
; LDI AR3,AR2
; ADDI 6,AR2 ;POINT AR2 TO THIRD COLUMN OF MATRIX
;
; LDF *+AR3(4),R1 ;GET N2
; STF R1,*+AR2(2) ;Z
;
;
; LDF *+AR3(5),R0 ;GET N3
; NEGF R0
; STF R0,*+AR2(1) ;Y
;
; CLRF R1
; STF R1,*+AR2(0) ;X
*COMPUTE CROSS PRODUCT
ADDI 3,AR2 ;POINT AR2 TO THIRD COLUMN OF MATRIX
LDI 2,IR0
MPYF *+AR3(1),*+AR2(IR0),R0 ;U2*V3
MPYF *+AR3(IR0),*+AR2(1),R1 ;U3*V2
SUBF R1,R0
STF R0,*+AR3(6)
MPYF *+AR3(IR0),*AR2,R0 ;U3*V1
MPYF *AR3,*+AR2(IR0),R1 ;U1*V3
SUBF R1,R0
STF R0,*+AR3(7)
MPYF *AR3,*+AR2(1),R0 ;U1*V2
MPYF *+AR3(1),*AR2,R1 ;U2*V1
SUBF R1,R0
STF R0,*+AR3(8)
ADDI 3,AR2
CALL NORMALIZE ;normalize(&N);
*INVERT MATRIX AND STORE IN OBJECT
LDI AR3,R2
LDI AR4,AR2
ADDI OMATRIX,AR2
CALL CPYIMAT ;invert matrix and stuff in object
***GET CAR HEIGHT AND LOAD IT INTO CAR
LDF *+AR6(1),R0 ;GET Y HEIGHT FIRST POINT
SUBF *+AR6(CARWHLTAB+1),R0
STF R0,*+AR4(OPOSY)
RETS
*----------------------------------------------------------------------------
*CHECK OBJECT COLLISION WITH VECTOR IN X/Z SPACE
*
*PARAMETERS
* AR2 OBJECT POINTER
* R2 VECTOR POINTER
*
*RETURNS
* CS=collision, CC= No collision
* VL contains 3 pointers which point to VECTORs which
* define the normal to this polygon where the 1st collision has
* been found.
*
*TRASHES
* R0,R1,R2,R3
*
_obj_coll:
PUSH R4
PUSH R5
PUSH AR1
PUSH AR3
PUSH AR4
PUSH AR5
PUSH AR6
PUSH AR7
LDI *+AR2(OROMDATA),AR4
ADDI 1,AR4 ;skip object diameter
LDI AR2,AR5
ADDI OMATRIX,AR5 ;rotational matrix
LDPI @BLOWLISTI,AR3 ;blowlist pointer = AR3
LDI @transvectorYI,AR6 ;transvector temp store
LDI @tmpmatY,AR7 ;TEMP VECTOR STORE
LDI 8,IR0
LDI R2,AR1 ;create translation (TRANS = OBJPOS - COLLPOS)
LDF *+AR2(OPOSX),R0
SUBF *AR1++,R0
STF R0,*-AR6(1) ;transvector.x
LDF *+AR2(OPOSY),R0
SUBF *AR1++,R0
STF R0,*AR6 ;transvector.y
LDF *+AR2(OPOSZ),R0
SUBF *AR1,R0
STF R0,*+AR6(1) ;transvector.z
LDI *AR4++,RC
LDI RC,BK
AND 0FFh,RC
RPTB EOTV
LDI *AR4++,R4
LDI R4,R3
ASH -16,R4
LS 16,R3
ASH -16,R3
FLOAT R3
FLOAT R4
STF R3,*-AR7(1)
FLOAT *AR4++,R2 ;get z element of source 1
|| STF R4,*AR7
*
*MULTIPLY BY ROTATION MATRIX
*AND ADD TRANSLATION (IN THAT ORDER)
*
MPYF3 *AR5++,R3,R0
|| STF R2,*+AR7(1) ;STORE OUT Z ELEMENT
MPYF3 *AR5++,R4,R1
MPYF3 *AR5++,*+AR7(1),R1
|| ADDF3 R0,R1,R2
MPYF3 *AR5++,*-AR7(1),R0
|| ADDF3 R1,R2,R2
ADDF *-AR6(1),R2 ;*blowlist++ += translation[X]
MPYF3 *AR5++,R4,R1
|| STF R2,*AR3++ ;STORE ROTATED X
MPYF3 *AR5++,*+AR7(1),R1
|| ADDF3 R0,R1,R2
MPYF3 *AR5++,*-AR7(1),R0
|| ADDF3 R1,R2,R3
ADDF *AR6,R3 ;*blowlist++ += translation[Y]
MPYF3 *AR5++,R4,R1
|| STF R3,*AR3++ ;STORE ROTATED Y
MPYF3 *AR5--(IR0),*+AR7(1),R1
|| ADDF3 R0,R1,R2
ADDF R1,R2 ;FORM ROTATED Z
ADDF *+AR6(1),R2 ;ADD IN TRANSLATION Z
EOTV STF R2,*AR3++ ;STORE Z
LDPI @BLOWLISTI,IR1 ;blowlist pointer = IR1
LDI IR1,IR0
ADDI 2,IR0
LDI 0FFh,R4
LDI -8,R5
; BD VLINST
INC AR4 ;skip control of 1st polygon
LDI BK,RC
RS 16,RC
;----->BD VLINST
*----------------------------------------------------------------------------
*CHECK OBJECT COLLISION WITH VECTOR IN X/Z SPACE
*
*THIS ROUTINE MUST BE FIRST BECAUSE OF .ALIGN BUG IN LINKER/ASSEMBLER
; .align
; NOP
; NOP
; NOP
VLINST
LDI *AR4++(5),R1
RPTB VLINLP
; LDI *AR4++(5),R1
AND R1,R4,AR1
MPYI 3,AR1 ;FIRST INDEX
RS 8,R1
AND R1,R4,AR3
MPYI 3,AR3 ;SECOND INDEX
RS 8,R1
AND R1,R4,AR5
MPYI 3,AR5 ;THIRD INDEX
LSH R5,R1,AR6
MPYI 3,AR6 ;FOURTH INDEX
CMPI AR5,AR6 ;CHECK FOR QUAD OR TRIANGLE
BZD VLTRI
*
*CHECK POLYGON PT COLLISION
*AR1,AR3,AR5,AR6= PTR TO VERTICES
*IMPLIED COLLISION POINT IS 0,0,0
*
VLQUAD
SUBF *+AR5(IR0),*+AR6(IR0),R0 ;-A
SUBF *+AR6(IR1),*+AR5(IR1),R1 ;-B
MPYF R0,*+AR5(IR1),R2 ;-AX1
;------>BZD VLTRI
MPYF R1,*+AR5(IR0),R3 ;-BY1
ADDF R3,R2 ;C
ABSF R1
CMPF R1,R2
BGTD VLINLP ;FAIL
VLTRI
SUBF *+AR6(IR0),*+AR1(IR0),R0 ;-A
SUBF *+AR1(IR1),*+AR6(IR1),R1 ;-B
MPYF R0,*+AR6(IR1),R2 ;-AX1
MPYF R1,*+AR6(IR0),R3 ;-BY1
ADDF R3,R2 ;C
ABSF R1
CMPF R1,R2
BGTD VLINLP ;FAIL
SUBF *+AR1(IR0),*+AR3(IR0),R0 ;-A
SUBF *+AR3(IR1),*+AR1(IR1),R1 ;-B
MPYF R0,*+AR1(IR1),R2 ;-AX1
MPYF R1,*+AR1(IR0),R3 ;-BY1
ADDF R3,R2 ;C
ABSF R1
CMPF R1,R2
BGTD VLINLP ;FAIL
SUBF *+AR3(IR0),*+AR5(IR0),R0 ;-A
SUBF *+AR5(IR1),*+AR3(IR1),R1 ;-B
MPYF R0,*+AR3(IR1),R2 ;-AX1
MPYF R1,*+AR3(IR0),R3 ;-BY1
ADDF R3,R2 ;C
ABSF R1
CMPF R1,R2
BLE VLCOLL ;GOT ONE...
VLINLP
LDI *AR4++(5),R1
CLRC
POP AR7
POP AR6
POP AR5
POP AR4
POP AR3
POP AR1
POP R5
POP R4
RETS
VLCOLL ;FOUND ONE!
ADDI IR1,AR1
ADDI IR1,AR3
ADDI IR1,AR5
STI AR1,@VL
STI AR3,@VL+1
STI AR5,@VL+2
SETC
POP AR7
POP AR6
POP AR5
POP AR4
POP AR3
POP AR1
POP R5
POP R4
RETS
*----------------------------------------------------------------------------
*MAKBOX GET XYZPLUS-MINUS VALUES FOR CAR
* MAKE WHEEL OFFSET TABLE
*PARAMETERS
* AR4 OBJECT WITH OCARBLK
*RETURNS
* GETS CARXYZPLUS/MINUS IN OCARBLK
* CARWHLTAB IN OCARBLK
*TRASHES
* R0-R2
_makbox:
PUSH R3
PUSH R4
PUSH R5
PUSH R6
PUSHF R6
PUSH AR0
LDI *+AR4(OROMDATA),AR0
ADDI 1,AR0 ;skip object diameter
LDI *AR0++,RC ;GET VERTEX COUNT
AND 0FFh,RC
SUBI 1,RC
LDI *AR0++,R3 ;GET Y:X
LDI R3,R4
LS 16,R3
ASH -16,R3 ;UNPACK X X1->R3 OXPLUS
ASH -16,R4 ;UNPACK Y Y1->R4 OYPLUS
FLOAT R3
FLOAT R4
FLOAT *AR0++,R5 ;Z1->R5 OZPLUS
LDF R3,R0 ;X1->R0 OXMINUS
LDF R4,R1 ;Y1->R1 OYMINUS
LDF R5,R2 ;Z1->R2 OZMINUS
RPTB MBVL
LDI *AR0,R6 ;GET Y:X
LS 16,R6
ASH -16,R6 ;UNPACK X
FLOAT R6
CMPF R3,R6 ;CHECK X(N) > XPLUS
LDFGT R6,R3
CMPF R0,R6 ;CHECK X(N) < XMINUS
LDFLT R6,R0
LDI *AR0++,R6 ;GET Y:X
ASH -16,R6 ;UNPACK Y
FLOAT R6
CMPF R4,R6 ;CHECK Y(N) > YPLUS
LDFGT R6,R4
CMPF R1,R6 ;CHECK Y(N) < YMINUS
LDFLT R6,R1
FLOAT *AR0++,R6 ;XN
CMPF R5,R6 ;CHECK Z(N) > ZPLUS
LDFGT R6,R5
CMPF R2,R6 ;CHECK Z(N) < ZMINUS
MBVL LDFLT R6,R2
LDI *+AR4(OCARBLK),AR0
*STORE WHEEL OFFSET TABLE
LDF 0,R6
STF R6,*+AR0(CARWHLTAB+0) ;CENTER POINT BOTTOM
STF R4,*+AR0(CARWHLTAB+1)
STF R6,*+AR0(CARWHLTAB+2)
STF R3,*+AR0(CARWHLTAB+3) ;RT FRONT BOTTOM
STF R4,*+AR0(CARWHLTAB+4)
STF R5,*+AR0(CARWHLTAB+5)
STF R0,*+AR0(CARWHLTAB+6) ;LFT FRONT BOTTOM
STF R4,*+AR0(CARWHLTAB+7)
STF R5,*+AR0(CARWHLTAB+8)
STF R0,*+AR0(CARWHLTAB+9) ;LFT REAR BOTTOM
STF R4,*+AR0(CARWHLTAB+10)
STF R2,*+AR0(CARWHLTAB+11)
STF R3,*+AR0(CARWHLTAB+12) ;RT REAR BOTTOM
STF R4,*+AR0(CARWHLTAB+13)
STF R2,*+AR0(CARWHLTAB+14)
*STORE XYZ PLUS/MINUS
ADDF 25.0,R0 ;MAKE IT A LITTLE SMALLER
STF R0,*+AR0(CARXMINUS)
STF R1,*+AR0(CARYMINUS)
; ADDF 15.0,R2 ;MAKE IT A LITTLE SMALLER
STF R2,*+AR0(CARZMINUS)
ADDF -25.0,R3 ;MAKE IT A LITTLE SMALLER
STF R3,*+AR0(CARXPLUS)
STF R4,*+AR0(CARYPLUS)
; ADDF -15.0,R5 ;MAKE IT A LITTLE SMALLER
STF R5,*+AR0(CARZPLUS)
POP AR0
POPF R6
POP R6
POP R5
POP R4
POP R3
RETS
*----------------------------------------------------------------------------
*COLLISION SCAN
*
COLSCC:
LDPI @_MODE,R0 ;MAKE SURE MODE IS IN GAME
AND MMODE,R0
CMPI MATTR,R0 ;cm
BEQ ATTR_COLLISION ;cm
CMPI MGAME,R0
BNE COLSCCX
LDI @PACTIVEI,AR7 ;ROOT PROCESS
*************TEST CODE
; CALL CKRAD
****************TEST CODE
CALL COLSCAN ;PLAYER VS. DRONES
CALL CLDSCAN ;DRONES VS. DRONES
CALL PLYRSIGN ;PLAYER VS. SIGNS, POLES, TREES
CALL PLYRDEBRIS ;PLAYER VS. ROAD DEBRIS
CALL DRONSIGN ;DRONES VS. SIGNS, POLES, TREES
CALL DRONDEBRIS ;DRONES VS. ROAD DEBRIS
CALL PLYRROADKILL ;PLAYER VS. ROADKILL
CALL DEBSCAN ;CLEAR OUT DEAD DEBRIS
COLSCCX
RETS
*----------------------------------------------------------------------------
ATTR_COLLISION
; LDI @_ATTR_MODE,R0
; CMPI -3,R0 ;BUG IN FUTURE
LDI @_MODE,R0 ;This check makes sure the code is not active
TSTB MHS,R0 ;during the high score display. Thus allowing
BNZ NO_ATTR_COL ;use to set MATTR mode during high score
;display while in the attract mode
LDI @PACTIVEI,AR7 ;ROOT PROCESS
CALL CLDSCAN ;DRONES VS. DRONES
CALL DRONSIGN ;DRONES VS. SIGNS, POLES, TREES
CALL DRONDEBRIS ;DRONES VS. ROAD DEBRIS
CALL DEBSCAN ;CLEAR OUT DEAD DEBRIS
NO_ATTR_COL
RETS
*----------------------------------------------------------------------------
*PLAYER COLLIDE WITH DEBRIS
*
PLYR_VS_DEBRIS:
PLYRDEBRIS
LDPI @_plyr1+PLY_CAR,AR0 ;GET PLAYER CAR
LDPI @ROAD_DEBRISI,AR1
B COLPOINT
*
*PLAYER COLLIDE WITH SIGNS
*
PLYR_VS_SIGN:
PLYRSIGN
LDPI @_plyr1+PLY_CAR,AR0 ;GET PLAYER CAR
LDPI @SIGN_LISTI,AR1
B COLPOINT
*
*DRONE COLLIDE WITH DEBRIS
*
DRONE_VS_DEBRIS:
DRONDEBRIS
LDPI @ROAD_DEBRISI,AR1
B DRONEPT
*
*DRONE COLLIDE WITH SIGNS
*
DRONE_VS_SIGN:
DRONSIGN
LDPI @SIGN_LISTI,AR1
DRONEPT:
LDPI @CAR_LIST,R0 ;GET LIST AND CHECK NULL
LDI R0,AR0
RETSZ
DRONEPTL:
LDI *+AR0(OID),R0
CMPI DRONE_C|HELICOPTER,R0
BEQ DRONEPT1
LDI *+AR0(ODIST),R1 ;IF DUDE OFFSCREEN, IGNORE
BN DRONEPT1
LDI 25000,R2 ;CHECK IF FAR DISTANT
MPYI 2,R2
CMPI R2,R1
BGT DRONEPT1 ;IF FAR IN DISTANCE, IGNORE
PUSH AR1
PUSH AR0
CALL COLPOINT ;CHECK CAR/POINT COLLISION
POP AR0
POP AR1
DRONEPT1
LDI *+AR0(OLINK3),R0
LDI R0,AR0
BNZ DRONEPTL
RETS
*----------------------------------------------------------------------------
*SIGN/TREE COLLISION SCAN WITH CAR
*
*CHECK PLAYER CAR AGAINST LIST
*PARAMETERS
* AR0 CAR OBJECT
* AR1 ADDRESS OF LIST HEADER
*
*DO NOT MODIFY THE BEHAVIOR THAT HAS BEEN DEFINED HERE:
*  only the TYPE is used to determine behavior
*  object is NOT pulled from any list (SIGN or OTHERWISE)
*
*
COLPOINT:
BD CARSCL0 ;GET FIRST GUY
LDF *+AR0(OPOSX),R2 ;GET X COORD
LDF *+AR0(OPOSZ),R3 ;GET Z COORD
SUBI OLINK3,AR1 ;SETUP INDEXING
;------->BU CARSCL0
CARSCLP0
MPYF R4,R4
ADDF R0,R4
CMPF R5,R4 ;ARE WE WITHIN RADIUS?
BGT CARSCL ;NO, KEEP GOING
LDI *+AR1(OFLAGS),R0
TSTB O_NOCOLL,R0 ;check non-collide flag
BNZ CARSCL
CALL COLSGCK
LDF *+AR0(OPOSX),R2 ;GET X COORD
LDF *+AR0(OPOSZ),R3 ;GET Z COORD
CARSCL0
FLOAT *+AR0(ORAD),R5 ;GET CAR RADIUS
LDI OPOSZ,IR0
MPYF R5,R5
CARSCL
LDI *+AR1(OLINK3),AR1
LDI AR1,R0
BNZD CARSCLP0
SUBF *+AR1(OPOSX),R2,R0
MPYF R0,R0
SUBF *+AR1(IR0),R3,R4
********BNZD CARSCLP0
RETS
*----------------------------------------------------------------------------
*CHECK POINT VERSUS XZ BOX
*
*PARAMETERS
* AR0 POINTS TO CAR OBJECT
* AR1 POINTS TO SIGN/POLE OBJECT
*
COLSGCK:
PUSH AR0
PUSH AR1
LDPI @BLOWLISTI,AR2
CALL GETBOX ;GET BOX POINTS FOR OBJECT 1
*
*CHECK 4 LINE EQUATIONS FOR BOTTOM OF CAR
*PT 2-6-7-3
LDPI @LEQTABI,AR2
LDI 3,RC ;DO 4 EQUATIONS
RPTB CSGLNEQ
LDI *AR2++,AR3 ;GET 2 POINTS
LDI *AR2,AR4
SUBF *+AR3(1),*+AR4(1),R0 ;A
SUBF *-AR4(1),*-AR3(1),R1 ;B
MPYF R0,*-AR3(1),R2
MPYF R1,*+AR3(1),R3
ADDF R3,R2
NEGF R2 ;C
*EVALUATE THE POINT
MPYF *+AR1(OPOSX),R0 ;AX
MPYF *+AR1(OPOSZ),R1 ;BZ
ADDF R0,R1
ADDF R1,R2
BLE COLSGCX
CSGLNEQ NOP
*
*GOT A COLLISION
*CHECK TYPE
*
LDI *+AR0(OCARBLK),AR5 ;GET VELOCITY DIRECTION
LDI *+AR1(OID),R0
AND TYPE_M,R0
CMPI TSC_IGNORE,R0
BEQ SIGN_IGNORE
;herein lies the start of our bugs...
;
;
;
LDI *+AR1(OID),R0
AND CLASS_M|TYPE_M,R0
CMPI RDDEBRIS_C|TSC_ROADKILL,R0
BEQ ROADKILL
LDI *+AR1(OID),R0
AND TYPE_M,R0
CMPI TSC_FLYING,R0
BEQ FLYCOLL
CMPI TSC_RUNOVER,R0
BEQ RUNOVER
*
*IMMOBILE SIGN
*
*PARAMETERS
* AR0 POINTS TO CAR OBJECT
* AR1 POINTS TO SIGN/POLE OBJECT
* AR5 CARBLOCK
HARDCOL:
LDI *+AR1(OID),R0
AND CLASS_M|TYPE_M|SUBTYPE_M,R0
CMPI TSIGN_C|TSC_IMMOBILE|TSC_V_PALM,R0
BNE NOTCOCONUT
PUSH R0
PUSH R2
PUSH AR0
PUSH AR2
PUSH AR3
PUSH AR5
LDI AR0,AR5 ;parent object
RANDN 3
LDI R0,AR3
LL88
.globl DROP_COCONUTS
CREATE DROP_COCONUTS,TSIGN_C|TSC_IMMOBILE|TSC_V_PALM
DBU AR3,LL88
POP AR5
POP AR3
POP AR2
POP AR0
POP R2
POP R0
BU DOREPEL
NOTCOCONUT
AND TYPE_M,R0 ;REDWOODS MUST NOT GET KNOCKED OVER
CMPI TSC_HARD,R0
BNE RUNOVER
*REPELL THE SUCKERS
DOREPEL
CALL REPELL
MPYF *AR2,R0,R1 ;X REPELL
MPYF *+AR2(2),R0 ;Z REPELL
ADDF *+AR0(OPOSX),R1 ;REPELL THE SUCKER (AR0)
ADDF *+AR0(OPOSZ),R0
STF R1,*+AR0(OPOSX)
STF R0,*+AR0(OPOSZ)
LDF *+AR5(CARSPEED),R2 ;GOING FAST???
MPYF 0.6,R2
CMPF 37,R2 ;MINIMUM SPEED VALUE
LDFLT 37,R2
STF R2,*+AR5(CARSPEED) ;REVERSE SPEED
BLT HARDCOL00 ;YES,SPINOUT
LDI 500,AR2 ;STRAIGHT OR SPINNER?
CALL RANDPER
BC HARDCOL1 ;SPINNER...
*STRAIGHT KICKBACK
HARDCOL00
LDI 60,R0 ;SPIN COUNT
STI R0,*+AR5(CAR_SPIN)
LDI AR0,AR4
.GLOBL GETNXTRDIR
CALL GETNXTRDIR
LDI AR4,AR0
LDF R0,R2
SUBF *+AR5(CARYROT),R2
CALL NORMITS
LDF R2,R2
LDFGT 0.02,R0
LDFLE -0.02,R0
B HARDCOL2 ;STORE DROT, SET VROT
*SPIN THE DUDE
HARDCOL1
LDI 1,R0 ;SPIN THE DUDE
STI R0,*+AR5(CAR_SPIN)
LDF 3.14,R1 ;SET 180 MIN SPIN
STF R1,*+AR5(CARSPRAD)
LDF 0.1,R0 ;GET ROTATION AMOUNT
HARDCOL2
STF R0,*+AR5(CARDROT)
LDPI @VECTORAI,AR2 ;COMPUTE REPULSION VECTOR
LDF *AR2,R2
LDF *+AR2(2),R3
CALL ARCTANF
SUBF 1.57,R0
SUBF *+AR5(CARVROT),R0
LDF R0,R2
CALL NORMITS
ABSF R2
CMPF 1.57,R2
BLT HARDCOL3
LDF *+AR5(CARVROT),R2 ;REVERSE VELOCITY
LDF R2,R3
ADDF 3.14,R2
CALL NORMITS
STF R2,*+AR5(CARVROT)
*SHAKE THE TREE
LDI *+AR1(OID),R0
AND TYPE_M,R0
CMPI TSC_HARD,R0
BEQ HARDCOL3
LDF R3,R2
LDI AR1,AR2 ;FORM OMATRIX POINTER
ADDI OMATRIX,AR2 ;STUFF
CALL FIND_YMATRIX ;NEW MATRIX
LDI AR1,AR4 ;GET SIGN OBJECT POINTER
LDI *+AR4(OFLAGS),R0 ;MAKE IT SELF ROTATING
ANDN O_POSTER,R0
LDI 1,R1 ;SET 3D ROTATION BIT
LS O_3DROT_B,R1
OR R1,R0
STI R0,*+AR4(OFLAGS)
LDF *+AR5(CARSPEED),R7 ;HIT CAR SPEED
MPYF 0.04,R7 ;FALL RATE BASED UPON VELOCITY
CMPF 0.13,R7
LDFLT 0.13,R7
CMPF 1.0,R7
LDFGT 1.0,R7
LDPI @TREESHAKI,AR2 ;GET SIGN FALL PROCESS
LDI DRONE_C|FLYER_T,R2
CALL PRC_CREATE_CHILD ;CREATE A CHILD PROCESS
HARDCOL3
SONDFX POLESND ;MAKE SOUND
B COLSGCX
*
*ROADKILL OBJECT
* AR0 POINTS TO CAR OBJECT
* AR1 POINTS TO ROADKILL OBJECT HIT
*
ROADKILL:
LDI 1,R0
STI R0,*+AR1(OCARBLK)
CALL ROADKILL_HIT ;MAKE A SOUND
CALL ROADKILL_FLYERP
BC FLYCOLL
B COLSGCX
*
*FLYING OBJECT
* AR0 POINTS TO CAR OBJECT
* AR1 POINTS TO OBJECT HIT
FLYCOLL:
LDF *+AR0(OPOSY),R0 ;MAKE SURE HEIGHT IS CLOSE
SUBF *+AR1(OPOSY),R0
ABSF R0
FLOAT 250,R1
CMPF R1,R0
BGT COLSGCX
LDF 0.10,R0 ;ADD RANDOM ROTATION
CALL SFRAND
LDF R0,R2
ADDF *+AR5(CARVROT),R2
LDF 0.65,R0 ;RANDOM SPEED MULTIPLIER
CALL FRAND
LDF R0,R1
ADDF 0.8,R1
MPYF 1.5,R1 ;SPEEDFUDGE FACTOR
CALL _SINE
NEGF R0,R3
CALL _COSI
MPYF *+AR5(CARSPEED),R1 ;GET CURRENT SPEED
MPYF R1,R3
MPYF R1,R0
STF R3,*+AR1(OVELX) ;SETUP VELOCITIES
STF R0,*+AR1(OVELZ)
LDF -0.3,R0
CALL FRAND
ADDF -0.2,R0
MPYF 1.5,R0 ;SPEEDFUDGE FACTOR
MPYF *+AR5(CARSPEED),R0 ;GET CURRENT SPEED
CMPF -65,R0
LDFLT -65,R0 ;MAX VERTICAL VELOCITY
STF R0,*+AR1(OVELY) ;STUFF VERTICAL VELOCITY
LDI AR1,AR4 ;GET SIGN OBJECT POINTER
LDI AR0,AR3 ;SAVE CAR OBJECT
LDI 1,R0
LSH O_PROC_B,R0 ;PROCESS BIT MASK IN OBJECT STRUCT
TSTB *+AR4(OFLAGS),R0 ;PROCESS ALREADY ACTIVE ?
LDINZ *+AR4(OPLINK),AR2 ;YES, KILL HIM OFF...
BZ CLLL1
CALL PRC_KILL ;DONT FUCK WITH THIS PRIBYL!!!!
CLLL1
LDPI @FLYCOLLPI,AR2 ;GET SIGN FLY PROCESS
LDI DRONE_C|FLYER_T,R2
CALL PRC_CREATE_CHILD ;CREATE A CHILD PROCESS
BC COLSGCX ;NOTHING AVAILABLE, QUIT
STI AR0,*+AR4(OPLINK) ;SAVE PROCESS LINK
LDI 1,R0
LSH O_3DROT_B,R0 ;FLAG CAN AS NON-2D OPTIMIZABLE
LDI 1,R1
LSH O_PROC_B,R1 ;PROCESS BIT MASK IN OBJECT STRUCT
ADDI R1,R0
OR *+AR4(OFLAGS),R0 ;SET YOUR FLAGS...
STI R0,*+AR4(OFLAGS)
LDI 0,R0 ;KILL OFF GROUP REFERENCE
STI R0,*+AR4(OLINK2)
*GET SOUND FOR SAWHORSE/DRUM HIT
LDI *+AR4(OID),R2
LDI R2,R0
AND TYPE_M,R0
CMPI TSC_ROADKILL,R0
BNE KLFD
CALL ROADKILL_SETKILL
BU COLSGCX
KLFD
AND SUBTYPE_M,R2
CMPI @PLYCAR,AR3 ;PLAYERS CAR?
BNZ FLYCOLL1 ;NO...
CMPI RDD_55GAL,R2
LDIEQ DRUMSND,AR2
LDINE SIGNSND,AR2
CALL ONESNDFX
B COLSGCX
FLYCOLL1
CMPI RDD_55GAL,R2
LDIEQ DRMBNCE,AR2
LDINE DSIGNSND,AR2
B COLSGCX0
*----------------------------------------------------------------------------
*RUNOVER SIGN
*REMOVE SIGN FROM SIGN SUP LIST
*START SIGN PROCESS TO MAKE IT FALL
*
*PARAMETERS
* AR0 POINTS TO CAR OBJECT
* AR1 POINTS TO SIGN/POLE OBJECT
* AR5 CARBLOCK
RUNOVER:
LDF *+AR5(CARVROT),R2
LDI AR1,AR2 ;FORM OMATRIX POINTER
ADDI OMATRIX,AR2 ;STUFF
CALL FIND_YMATRIX ;NEW MATRIX
LDI AR1,AR4 ;GET SIGN OBJECT POINTER
LDI AR0,AR3 ;SAVE CAR OBJECT
LDI *+AR4(OFLAGS),R0 ;MAKE IT SELF ROTATING
ANDN O_POSTER,R0
STI R0,*+AR4(OFLAGS)
LDF *+AR5(CARSPEED),R7 ;HIT CAR SPEED
LDF R7,R6
MPYF 0.2,R6
CMPF 10,R6
LDFLT 10,R6
CMPF R6,R7
LDFLT R7,R6
LDF R7,R5
SUBF R6,R5
STF R5,*+AR5(CARSPEED)
MPYF 0.03,R7 ;FALL RATE BASED UPON VELOCITY
CMPF 0.1,R7
LDFLT 0.1,R7
CMPF 0.7,R7
LDFGT 0.7,R7
CALL FREESIGN ;GET SIGN OFF LIST
LDPI @SIGNFALLI,AR2 ;GET SIGN FALL PROCESS
LDI DRONE_C|FLYER_T,R2
CALL PRC_CREATE_CHILD ;CREATE A CHILD PROCESS
LDI *+AR4(OID),R0
AND SUBTYPE_M,R0
LDI SIGNSND,AR2 ;DEFAULT SOUND
CMPI TSC_R_SAGE,R0
BNZ RUNOV0
LDI 5,AR2
CALL RANDU0
ADDI @SAGETABI,R0
LDI R0,AR2
LDI *AR2,AR2
B RUNOV00
RUNOV0
CMPI TSC_R_POLE,R0
LDIZ DONGSND,AR2
CMPI TSC_R_LAMPPOST,R0
LDIZ LAMPSND,AR2
RUNOV00
CMPI @PLYCAR,AR3 ;PLAYERS CAR?
BNZ COLSGCX0 ;NO...
CALL ONESNDFX
B COLSGCX
COLSGCX0
CALL DRONESND1
SIGN_IGNORE
COLSGCX
POP AR1
POP AR0
RETS
SAGETABI .WORD SAGETAB
SAGETAB .WORD SAGESND,SAGESND1,SAGESND2,SAGESND3,SAGESND
*----------------------------------------------------------------------------
*FLYING SIGN COLLISION PROCESS
*
*AR4= SIGN OBJECT
*
FLYCOLLPI .WORD FLYCOLLP
FLYCOLLP:
LDF 0.2,R0
CALL SFRAND
LDF R0,R2
LDI AR7,AR2
ADDI PDATA+2,AR2 ;STORE MATRIX PDATA+2
CALL FIND_XMATRIX
LDPI @MATRIXAI,AR2
LDF 0.1,R0
CALL SFRAND
LDF R0,R2
CALL FIND_YMATRIX
LDI AR7,R2 ;ROTATE THE SUCKER
ADDI PDATA+2,R2
LDI R2,R3
CALL CONCATMAT
FLYCOLP0
; LDI *+AR4(OFLAGS),R0 ;CHECK IF OBJECT ACTIVE, EXISTS
; AND O_LIST_M,R0
; CMPI O_LIST0,R0
; BZ FLYSTOP ;ERROR DOES NOT EXIST
; CMPI O_LIST2,R0 ;OBJECT NOT ACTIVE, SPLIT
; BZ FLYSTOP
LDPI @NFRAMES,AR6 ;ADJUST MATRIX FOR FRAME COUNT
SUBI 1,AR6
FLYCOLPL
LDI AR7,R2 ;ROTATE THE SUCKER
ADDI PDATA+2,R2
LDI AR4,AR2
ADDI OMATRIX,AR2
LDI AR2,R3
CALL CONCATMAT
DBU AR6,FLYCOLPL
CALL OVELNADD ;UPDATE VELOCITIES
LDI 0,R0
STI R0,*+AR4(OUSR1) ;INDICATE IN MOTION, RE-SORT
FLOATP @NFRAMES,R2
MPYF 2,R2 ;FRAME ADJUSTED GRAVITY
ADDF *+AR4(OVELY),R2
STF R2,*+AR4(OVELY)
CMPF 100,R2
BGT FLYSTOP
CALL OBJSCAN
BNC FLYCSLP ;OFF THE MAP
*WERE OVER THE ROAD
FLYROAD
FLOAT 155,R1 ;HT OF DRUM/SAWHORSE
LDI *+AR4(OID),R2 ;ROADKILL DOESN'T BOUNCE
CMPI RDDEBRIS_C|TSC_ROADKILL,R2
LDFEQ 35,R1
CMPF R1,R0
BGT FLYCSLP ;WERE ABOVE GROUND
*WE HIT THE GROUND DUDES
LDF *+AR4(OVELY),R2 ;GET VERTICAL VELOCITY
BN FLYCSLP ;WERE GOING UP IGNORE IT
SUBRF R1,R0 ;SET HIM ON THE GROUND
ADDF *+AR4(OPOSY),R0
CMPF 20,R2 ;CHECK FOR MINIMUM
BLT FLYSTOP ;TIME TO STOP
MPYF -0.5,R2
STF R2,*+AR4(OVELY)
LDF *+AR4(OVELX),R0 ;CUT DOWN VELOCITIES
MPYF 0.5,R0
STF R0,*+AR4(OVELX)
LDF *+AR4(OVELZ),R1 ;CUT DOWN VELOCITIES
MPYF 0.5,R1
STF R1,*+AR4(OVELZ)
*MAKE BOUNCE SOUND
FLOAT *+AR4(ODIST),R0
BN FLYCSLP ;BEHIND PLAYER NO SOUND
CALL INV_F30
FLOAT 5000,R1
MPYF R1,R0
ABSF *+AR4(OVELY),R2 ;SOUND PROPORTIONAL TO VERT VELOCITY
CMPF 30,R2
LDFGT 30,R2
MPYF 5.0,R2
MPYF R2,R0
FIX R0
CMPI 140,R0
LDIGT 140,R0
LDI *+AR4(OID),R1
AND SUBTYPE_M,R1
CMPI RDD_55GAL,R1
LDIEQ DRMBNCE,AR2
LDINE SAWBNCE,AR2
CALL VOLSNDFX
FLYCSLP
SLEEP 1
B FLYCOLP0
FLYSTOP
LDI 1,R0
LSH O_PROC_B,R0 ;CLEAR PROCESS BIT
NOT R0
AND *+AR4(OFLAGS),R0
STI R0,*+AR4(OFLAGS)
LDI *+AR4(OID),R0
CMPI RDDEBRIS_C|TSC_ROADKILL,R0
BNE NOT_ROADKILL
LDI AR4,AR2
CALL OBJ_DELETE
NOT_ROADKILL
BR SUICIDE
*----------------------------------------------------------------------------
*
*KILL OFFSCREEN ROAD DEBRIS
*
DEBSCAN
LDI @ROAD_DEBRIS,R0
B DEBSCL1
DEBSCL0
LDI *+AR2(OLINK2),R0 ;IN BACKGROUND GROUP?
BNZ DEBSCL ;YES, SKIP IT...
LDI *+AR2(OFLAGS),R0
AND O_LIST_M,R0
CMPI O_LIST2,R0 ;OBJECT ACTIVE?
BNZ DEBSCL ;YES, FAGIT ABOUDIT
LDI *+AR2(OLINK3),R0
CALL OBJ_DELETE ;OBJECT INACTIVE, CAN IT + PROCESS
B DEBSCL1
DEBSCL
LDI *+AR2(OLINK3),R0
DEBSCL1
LDI R0,AR2
BNZ DEBSCL0
RETS
*----------------------------------------------------------------------------
*FALLING SIGN PROCESS
*
*PARAMETERS
* AR4 SIGN OBJECT
* R7 ROTATION DELTA
*
SIGNFALLI .WORD SIGNFALL
SIGNFALL
LDF 0,R6
SIGNFALP
ADDF R7,R6 ;ACCUMULATE RADIANS
CMPF 1.5,R6 ;CHECK DONE
BLT SIGNFALP0 ;NOPE...
SUBF 1.5,R6 ;SUBTRACT OUT EXCESS
SUBF R6,R7
LDF 1.6,R6 ;SIGNAL WERE DONE
SIGNFALP0
LDF R7,R2
LDPI @MATRIXAI,AR2 ;GET TEMP STORE
CALL FIND_XMATRIX ;NEW MATRIX
LDI AR4,R2
ADDI OMATRIX,R2
LDI R2,R3
CALL CONCATMAT
SLEEP 1
CMPF 1.5,R6
BLT SIGNFALP ;LOOP TIL DONE
BR SUICIDE
*----------------------------------------------------------------------------
*TREE SHAKE PROCESS
*
*PARAMETERS
* AR4 SIGN OBJECT
* R7 ROTATION DELTA
*
TREESHAKI .WORD TREESHAK
TREESHAK
*SHAKE IT FORWARD
LDF R7,R2
LDPI @MATRIXAI,AR2 ;GET TEMP STORE
CALL FIND_XMATRIX ;NEW MATRIX
LDI AR4,R2
ADDI OMATRIX,R2
LDI R2,R3
CALL CONCATMAT
SLEEP 1
*SHAKE IT BACK
LDI 3,AR6 ;# FRAMES/SHAKE
MPYF -0.40,R7 ;DAMP IT
TREESHKL
LDF R7,R2
; LDP @MATRIXAI
LDPI @MATRIXAI,AR2 ;GET TEMP STORE
CALL FIND_XMATRIX ;NEW MATRIX
LDI AR4,R2
ADDI OMATRIX,R2
LDI R2,R3
CALL CONCATMAT
SLEEP 1
DBU AR6,TREESHKL
TREESHKL1
LDI 3,AR6 ;# FRAMES/SHAKE
MPYF -0.6,R7 ;REVERSE IT
ABSF R7,R0
CMPF 0.01,R0
BGT TREESHKL
LDI *+AR4(OFLAGS),R0 ;MAKE IT A POSTER AGAIN
OR O_POSTER,R0
LDI 1,R1 ;CLR 3D ROTATION BIT
LS O_3DROT_B,R1
ANDN R1,R0
STI R0,*+AR4(OFLAGS)
BR SUICIDE
*----------------------------------------------------------------------------
*FREESIGN
*unlink SIGN from SIGN supplementary list
*PARAMETERS
* AR4 OBJECT SIGN POINTER
* R0 IS TRASHED
FREESIGN:
PUSH AR1
; LDP @SIGN_LISTI
LDPI @SIGN_LISTI,R0
SUBI OLINK3,R0 ;(we are offset pointing)
SFREELP LDI R0,AR1
LDI *+AR1(OLINK3),R0
.if DEBUG
BZ $ ;lockup on end of list found
.else
RETSZ
.endif
CMPI R0,AR4
BNE SFREELP
LDI *+AR4(OLINK3),R0
STI R0,*+AR1(OLINK3) ;LINK AROUND
LDI 1,R1
LS O_SIGN_SUPP_B,R1
LDI *+AR4(OFLAGS),R0
ANDN R1,R0 ;TURN OFF SUPP LIST FLAGS
LDI 1,R1
LS O_3DROT_B,R1
OR R1,R0
STI R0,*+AR4(OFLAGS)
POP AR1
RETS
*----------------------------------------------------------------------------
*ADDSIGN
*LINK SIGN TO SIGN sup list
*PARAMETERS
* AR4 OBJECT SIGN POINTER
* R0 IS TRASHED
ADDSIGN:
LDPI @SIGN_LIST,R0
STI AR4,@SIGN_LIST
STI R0,*+AR4(OLINK3)
LDI 1,R1
LS O_SIGN_SUPP_B,R1
OR *+AR4(OFLAGS),R0
STI R0,*+AR4(OFLAGS)
RETS
*----------------------------------------------------------------------------
*
*FLYING CAR WRECK
*
* AR0 POINTS TO PLAYER CAR
* AR1 POINTS TO CAR TO SEND FLYING
* AR4 POINTS TO PLAYER CAR BLOCK
* AR5 POINTS TO DRONE CAR BLOCK
*
SBUSI .word sbus
CBUSI .word cbus
FLYCAR:
PUSH AR0
PUSH AR1
PUSH AR3
PUSH AR4
PUSH AR5
LDI *+AR0(OCARBLK),AR3 ;GET PLAYER'S CAR
LDI AR1,AR4 ;GET DRONE CAR OBJECT POINTER
LDI *+AR4(OCARBLK),AR5 ;GET DRONE CAR BLOCK
LDI @HEAD2HEAD_ON,R0
BZ NOTLINKED
LDI *+AR5(CAR_OM),R0 ;OTHER MACHINES CAR?
BNE L78G ;YES SKIP FLYING STUFF
NOTLINKED
LDI 1,R0
LSH O_PROC_B,R0 ;PROCESS BIT MASK IN OBJECT STRUCT
TSTB *+AR1(OFLAGS),R0 ;PROCESS ALREADY ACTIVE ?
BZ FLYCAR0 ;NO
LDI *+AR1(OPLINK),R0 ;YES, KILL OFF DRONE PROCESS
BZ FLYCAR0
LDI R0,AR2
CALL PRC_KILL
LDI 0,R0
STI R0,*+AR1(OPLINK)
FLYCAR0
LDI *+AR1(OFLAGS),R0
TSTB O_DYNAMIC,R0
BZ FLYCAR1
LDI *+AR1(ORADZ),R0 ;KILL WHEEL SPINNER, LEANER PROCESS
BZ FLYCAR1
LDI R0,AR2
CALL PRC_KILL
LDI 0,R0
STI R0,*+AR1(ORADZ)
FLYCAR1
LDI 0,R0
STI R0,*+AR5(CARSHAD) ;TURN OFF SHADOW
LDF 0.10,R0 ;ADD RANDOM ROTATION
CALL SFRAND
ADDF *+AR3(CARVROT),R0
STF R0,*+AR5(CARVROT)
LDF 0.45,R0 ;RANDOM SPEED MULTIPLIER
CALL FRAND
ADDF 0.8,R0
MPYF 0.75,R0
LDF *+AR5(CARMASS),R1 ;DECREASE THROW BY MASS
CALL DIV_F
MPYF *+AR3(CARSPEED),R0 ;COMPUTE DRONE SPEED FROM PLAYER SPD
STF R0,*+AR5(CARSPEED) ;STORE NEW DRONE SPEED
LDF -0.3,R0
CALL FRAND
ADDF -0.2,R0
MPYF 1.5,R0 ;SPEEDFUDGE FACTOR
MPYF *+AR3(CARSPEED),R0 ;GET CURRENT SPEED
CMPF -65,R0
LDFLT -65,R0 ;MAX VERTICAL VELOCITY
STF R0,*+AR1(OVELY) ;STUFF VERTICAL VELOCITY
LDPI @FLYCARPI,AR2 ;GET SIGN FLY PROCESS
LDI DRONE_C|FLYER_T,R2
CALL PRC_CREATE_CHILD ;CREATE A CHILD PROCESS
BC L78G
STI AR0,*+AR4(OPLINK) ;SAVE LINK
LDI 1,R0
LSH O_PROC_B,R0 ;PROCESS BIT MASK IN OBJECT STRUCT
OR *+AR4(OFLAGS),R0 ;SET ATTACHED PROCESS FLAG
STI R0,*+AR4(OFLAGS)
L78G LDF *+AR3(CARSPEED),R0 ;CUT SPEED OF PLAYER
MPYF 0.5,R0
MPYF @CHEAT,R0 ;BOOST SPEED ON CHEAT
MPYF @CHEAT,R0 ;BOOST SPEED ON CHEAT
STF R0,*+AR3(CARSPEED)
MPYF 1.25,R0
LDF *+AR5(CARSPEED),R1 ;KEEP FLYING CAR OUT FRONT
CMPF R0,R1
LDFLT R0,R1
STF R1,*+AR5(CARSPEED)
*GET PLAYER CAR VELOCITY, SPIN
LDI @WRECKFLG,R0 ;WRECK ON?
BNE FLY0 ;YES, DONT START A NEW ONE
LDI 400,AR2 ;TOTAL WRECK PLAYER
CALL RANDPER ;NO
BNC FLY0
CALL WRECKST ;START YOUR WRECK
LDI @DETHTAB2I,AR2
LDI 4,R0
B FLYCARXX
FLY0
LDPI @CAMVIEW,R0
BZ FLY1
LDI 750,AR2
CALL RANDPER
BC FLY3 ;SPIN SOMETIMES IN 3RD PERSON
*FIRST PERSON
FLY1
LDF *+AR3(CARVROT),R0 ;REVERSE VELOCITY
ADDF 3.14,R0
STF R0,*+AR3(CARVROT)
LDF 0,R1
LDI 15,R0 ;REVERSE FOR 15 COUNT
B FLYCARX
FLY3
LDF 3.14,R0 ;SPIN HIM AROUND
STF R0,*+AR3(CARSPRAD)
LDF 0.04,R0
CALL SFRAND
LDF R0,R0
LDFGT 0.08,R1
LDFLE -0.08,R1
ADDF R0,R1
LDI 1,R0
FLYCARX
STF R1,*+AR3(CARDROT)
STI R0,*+AR3(CAR_SPIN)
LDI @DETHTAB1I,AR2
LDI 8,R0
FLYCARXX
LDI *+AR1(OROMDATA),R1 ;CHECK FOR A BUS...
CMPI @SBUSI,R1
BNZ FC00
LDI KIDSCREAM2,AR2
B FC01
FC00
CMPI @CBUSI,R1
BNZ FC02
LDI ROAR,AR2
FC01
CALL ONESNDFX
B FC03
FC02
CALL RANDSND
FC03
POP AR5
POP AR4
POP AR3
POP AR1
POP AR0
RETS
DETHTAB1I .WORD DETHTAB1
DETHTAB2I .WORD DETHTAB2
DETHTAB1 .WORD MDETHSCREAM2,MDETHSCREAM4,EXP1,EXP3
.WORD NDETHSCREAM1,NDETHSCREAM3,NDETHSCREAM4,NDETHSCREAM7
DETHTAB2 .WORD MFDETHSCREAM1,MFDETHSCREAM2,BCHEER,EXP2
FLYCARPI .WORD FLYCARP
*
*FLYING CAR PROCESS
*AR4=DRONE PROCESS
*AR5=DRONE CAR BLOCK
*PDATA= X RAD
*PDATA+1= Y RAD
*PDATA+2= Z RAD
*PDATA+3= X RAD TOTAL
*PDATA+4= Y RAD TOTAL
*PDATA+5= Z RAD TOTAL
*PDATA+6=MATRIX
*
FLYCARP:
*GET YOUR RADIANS
LDF 0.2,R0
CALL SFRAND
STF R0,*+AR7(PDATA) ;X RADIANS
LDF 0.1,R0
CALL SFRAND
STF R0,*+AR7(PDATA+1) ;Y RADIANS
LDF 0,R0
STF R0,*+AR7(PDATA+2) ;Z RADIANS
LDF 0,R0
STF R0,*+AR7(PDATA+3) ;X RADIAN TOTAL
STF R0,*+AR7(PDATA+5) ;Z RADIAN TOTAL
LDF *+AR5(CARYROT),R0 ;GET CAR Y ROT
STF R0,*+AR7(PDATA+4)
FLYCARP0
LDI @SUSPEND_MODE,R0 ;WAIT IN SUSPEND MODE
CMPI SM_HALT,R0
BZ FLYCARSLP
LDI 0,R4
LDI *+AR4(ODIST),R0 ;OUT OF RANGE ??
CMPI -6000,R0
BLT FLYCARPXX ;END THIS FARCE
LDI *+AR4(OCARBLK),R3 ;GET CAR DATA AREA
CALL ROADSCAN
LDI *+AR4(OCARBLK),AR5 ;GET CAR DATA AREA
FLOATP @NFRAMES,R1 ;ADJUST MATRIX FOR FRAME COUNT
LDF *+AR7(PDATA),R0 ;ACCUMULATE X RADIANS
MPYF R1,R0
ADDF *+AR7(PDATA+3),R0
STF R0,*+AR7(PDATA+3)
LDF *+AR7(PDATA+1),R0 ;ACCUMULATE Y RADIANS
MPYF R1,R0
ADDF *+AR7(PDATA+4),R0
STF R0,*+AR7(PDATA+4)
; LDF *+AR7(PDATA+2),R0 ;ACCUMULATE Z RADIANS
; MPYF R1,R0
; ADDF *+AR7(PDATA+5),R0
; STF R0,*+AR7(PDATA+5)
CALL GETFLYMAT ;COMPUTE MATRICES
*CONVERT CARVROT,CARSPEED TO OVELX, OVELZ
LDF *+AR5(CARVROT),R2
ADDF 1.57,R2 ;CORRECT FOR 90 DEGREE ERROR
CALL _SINE
LDF *+AR5(CARSPEED),R3
MPYF R3,R0
STF R0,*+AR4(OVELZ) ;CONVERT TO CARVROT, CARSPEED TO XZVEL
CALL _COSI
MPYF R3,R0
STF R0,*+AR4(OVELX)
CALL OVELNADD ;UPDATE VELOCITIES
FLOATP @NFRAMES,R2
MPYF 2,R2 ;FRAME ADJUSTED GRAVITY
ADDF *+AR4(OVELY),R2
STF R2,*+AR4(OVELY)
FLOAT 300,R1 ;GOING DOWN TOO MUCH?
CMPF R1,R2
BGT FLYCARPXXX ;ABORT THE DUDE...
CALL GETTRAK
LDPI @_MODE,R0
TSTB MBRIDGE,R0 ;ON BRIDGE?
CALLZ DRONINBZ ;CHECK BOUNDS IF NO BRIDGE
LDF *+AR4(OVELY),R2 ;GET VERTICAL VELOCITY
BN FLYCARSLP ;WERE GOING UP IGNORE IT
CALL BOXSCAN ;KEEP FALLING!!!
BNC FLYCARSLP
*WERE OVER THE ROAD
FLYCROAD
LDF R0,R0
BGT FLYCARSLP ;WERE ABOVE GROUND
*WE HIT THE GROUND DUDES
LDF R0,R2 ;Save for offseting sparks
ADDF 30,R2 ;IMPACT_SPARKS uses this
CALL ROAD_IMPACT_SPARK
ADDF *+AR4(OPOSY),R0 ;SET HIM ON THE GROUND
STF R0,*+AR4(OPOSY)
LDF *+AR4(OVELY),R2 ;GET VERTICAL VELOCITY
; CMPF 20,R2 ;CHECK FOR MINIMUM
CMPF 35,R2 ;CHECK FOR MINIMUM
BLT FLYCARSTOP0 ;TIME TO STOP
FLYCROAD1
MPYF -0.5,R2
STF R2,*+AR4(OVELY)
LDF *+AR5(CARSPEED),R0 ;CUT SPEED IN HALF
MPYF 0.5,R0
STF R0,*+AR5(CARSPEED)
; LDF *+AR4(OVELX),R0 ;CUT DOWN VELOCITIES
; MPYF 0.5,R0
; STF R0,*+AR4(OVELX)
; LDF *+AR4(OVELZ),R1 ;CUT DOWN VELOCITIES
; MPYF 0.5,R1
; STF R1,*+AR4(OVELZ)
LDF *+AR7(PDATA),R0 ;CUT DOWN SPIN
MPYF 0.5,R0
STF R0,*+AR7(PDATA)
LDF *+AR7(PDATA+1),R0
MPYF 0.5,R0
STF R0,*+AR7(PDATA+1)
; LDF *+AR7(PDATA+2),R0
; MPYF 0.5,R0
; STF R0,*+AR7(PDATA+2)
*MAKE BOUNCE SOUND
LDPI @SCOLLTABI,AR2 ;RANDOM COLLISION CRUNCH
LDI 3,R0
CALL DRONESND
FLYCARSLP
LDI @HEAD2HEAD_ON,R0 ;HEAD 2 HEAD RACE???
CALLNZ SEND_FLY_POS ;SEND YOUR POSITION TO LINKED GAME
SLEEP 1
B FLYCARP0
*ROTATE TO QUIESCENT STATE
FLYCARSTOP0
; CALL GETCARVSPD ;CONVERT XVEL,ZVEL TO CARSPEED, CARVROT
FLYCARSTOP
LDI @SUSPEND_MODE,R0 ;WAIT IN SUSPEND MODE
CMPI SM_HALT,R0
BZ FLYSTOPSLP
LDI 1,R4
LDI *+AR4(ODIST),R0 ;OUT OF RANGE ??
CMPI -6000,R0
BLT FLYCARPXX ;END THIS FARCE
FLOAT 500,R0
STF R0,*+AR4(OVELY) ;FORCE ONTO GROUND
LDF *+AR5(CARVROT),R2
ADDF 1.57,R2 ;CORRECT FOR 90 DEGREE ERROR
CALL _SINE
LDF *+AR5(CARSPEED),R3
MPYF R3,R0
STF R0,*+AR4(OVELZ) ;CONVERT TO CARVROT, CARSPEED TO XZVEL
CALL _COSI
MPYF R3,R0
STF R0,*+AR4(OVELX)
LDF *+AR5(CARDROT),R0
STF R0,*+AR7(PDATA+1) ;GET Y SPIN
LDI *+AR4(OCARBLK),R3 ;GET CAR DATA AREA
CALL ROADSCAN
LDI *+AR4(OCARBLK),AR5 ;GET CAR DATA AREA
LDPI @NFRAMES,RC ;ADJUST MATRIX FOR FRAME COUNT
SUBI 1,RC
RPTB FLYCSTL
LDF *+AR4(OVELX),R0
MPYF 0.98,R0 ;DECAY VELOCITY
STF R0,*+AR4(OVELX)
ADDF *+AR4(OPOSX),R0
STF R0,*+AR4(OPOSX)
LDF *+AR4(OVELY),R0
ADDF *+AR4(OPOSY),R0
STF R0,*+AR4(OPOSY)
LDF *+AR4(OVELZ),R0
MPYF 0.98,R0 ;DECAY VELOCITY
STF R0,*+AR4(OVELZ)
ADDF *+AR4(OPOSZ),R0
STF R0,*+AR4(OPOSZ)
LDF *+AR7(PDATA),R0 ;ACCUMULATE X RADIANS
; MPYF 0.97,R0 ;DAMP IT
MPYF 0.96,R0 ;DAMP IT
STF R0,*+AR7(PDATA) ;CUT DOWN ROCK
ADDF *+AR7(PDATA+3),R0
STF R0,*+AR7(PDATA+3)
LDF *+AR7(PDATA+1),R0 ;ACCUMULATE Y RADIANS
; MPYF 0.985,R0 ;DAMP IT
MPYF 0.98,R0 ;DAMP IT
STF R0,*+AR7(PDATA+1) ;CUT DOWN ROCK
STF R0,*+AR5(CARDROT) ;STORE IN CAR STRUCTURE
ADDF *+AR7(PDATA+4),R0
STF R0,*+AR7(PDATA+4)
; LDF *+AR7(PDATA+2),R0 ;ACCUMULATE Z RADIANS
; ADDF *+AR7(PDATA+5),R0
; STF R0,*+AR7(PDATA+5)
LDF *+AR7(PDATA+3),R2 ;CHECK TOTAL X RADIANS
CALL NORMITS
ABSF R2,R3
LDF *+AR5(CARSPEED),R0 ;DECAY SPEED
MPYF 0.98,R0
STF R0,*+AR5(CARSPEED)
*CHECK FOR DONE...
CMPF 10,R0 ;SPEED DECAYED?
BGT FLYCSTP0 ;NO, KEEP GOING...
ABSF *+AR5(CARDROT),R0 ;GET ROTATE
ABSF *+AR7(PDATA),R1 ;ADD IN ROCK
ADDF R0,R1
MPYF 10,R1 ;GET IN RANGE
CMPF 0.02,R1 ;PETERED OUT?
BGT FLYCSTP0 ;NO, KEEP GOING
CMPF 0.2,R3 ;RIGHT SIDE UP?
BGT FLYCSTP00 ;NOPE...
LDF 0,R3 ;STRAIGHTEN HIM UP!!!
STF R3,*+AR7(PDATA+3)
LDI 2,R0
B FLYCCC ;YES, TIME TO STOP
FLYCSTP00
CMPF 2.95,R3 ;UPSIDE DOWN?
BLT FLYCSTP0 ;NOPE
FLYCSTP
LDI 1,R0 ;WERE DONE DUDES...
B FLYCCC
*ACCELERATE X ROTATION
FLYCSTP0
LDF R2,R2
BN FLYCSTP1
CMPF 1.57,R2
B FLYCSTP2
FLYCSTP1
CMPF -1.57,R2
FLYCSTP2
LDFLT -0.01,R0
LDFGE 0.01,R0
MPYF 0.4,R0
ADDF *+AR7(PDATA),R0
LDF *+AR7(PDATA),R1
XOR R0,R1,R2 ;CHECK FOR SIGN CHANGE- MAKE SOUND
BNN FLYCSTL ;NO SOUND
ABSF *+AR7(PDATA+3),R2 ;CHECK IF AMPLITUDE BIG ENOUGH
CALL NORMITS
ABSF R2
CMPF 0.08,R2
BLT FLYCSTL ;TOO SMALL OF A ROCK
CMPF 3.06,R2
BGT FLYCSTL ;TOO SMALL OF A UPSIDE DOWN ROCK
LDI BOTTOMOUT,AR2 ;MAKE BOTTOMOUT SOUND
PUSHF R0
CALL DRONESND1
POPF R0
FLYCSTL STF R0,*+AR7(PDATA) ;ACCELERATE ROTATION
LDI 0,R0 ;DONE FLAG
FLYCCC
PUSH R0
CALL GETTRAK
CALL DRONINBZ ;CHECK BOUNDS
CALL GETFLYMAT
CALL BOXSCAN ;KEEP FALLING!!!
POP R1 ;CLEAN STACK
BNC FLYCARSTP
ADDF *+AR4(OPOSY),R0 ;SET HIM ON THE GROUND
STF R0,*+AR4(OPOSY)
CALL SKID_SPARK
LDI R1,R1 ;DONE
BNE FLYCARSTP ;YESSAH
FLYSTOPSLP
LDI @HEAD2HEAD_ON,R0 ;HEAD 2 HEAD RACE???
CALLNZ SEND_FLY_POS ;SEND YOUR POSITION TO LINKED GAME
SLEEP 1
B FLYCARSTOP
FLYCARSTP
CMPI 2,R1
BZ DEADCAR ;RIGHT SIDE UP CARCASS
; LDPI @SCOLLTABI,AR2 ;RANDOM COLLISION CRUNCH
; LDI 3,R0
; CALL DRONESND
*
*CAR IS UPSIDE DOWN
*
LDI *+AR4(OID),R0
ANDN TYPE_M,R0
OR DEAD_VEH_T,R0
LDF 0,R0 ;CLEAR OUT THE SPEED
STF R0,*+AR5(CARSPEED)
*WAIT FOR OFFSCREEN
FLYCARWT
LDI @HEAD2HEAD_ON,R0 ;HEAD 2 HEAD RACE???
CALLNZ SEND_FLY_POS ;SEND YOUR POSITION TO LINKED GAME
SLEEP 1
LDI 1,R4 ;STATE #
LDI *+AR4(ODIST),R0 ;OUT OF RANGE?
CMPI -6000,R0
BLT FLYCARPXX ;YES CLEAN IT UP...
LDF *+AR5(CARSPEED),R0 ;ARE WE HIT???
BZ FLYCARWT ;NO, JUST WAIT
*
*UPSIDE DOWN CAR IS HIT
*
; LDF *+AR5(CARVROT),R2
; ADDF 1.57,R2 ;CORRECT FOR 90 DEGREE ERROR
; CALL _SINE
; LDF *+AR5(CARSPEED),R3
; MPYF R3,R0
; STF R0,*+AR4(OVELX) ;CONVERT TO CARVROT, CARSPEED TO XZVEL
; CALL _COSI
; MPYF R3,R0
; STF R0,*+AR4(OVELZ)
LDF 0.1,R0 ;ROCK HIM A LITTLE
CALL SFRAND
STF R0,*+AR7(PDATA) ;X RADIANS RATE
B FLYCARSTOP ;GO ROCK AND ROLL
*CLEAN UP THE MESS...
FLYCARPXX
LDI @HEAD2HEAD_ON,R0 ;HEAD 2 HEAD RACE???
BZ FLYCARPXXXX ;NOPE...
CALL COMPTRAK ;OTHER GUY BEHIND?
BLE FLYCARPXXX ;NO KILL THE DUDE...
CALL SEND_FLY_XSFER
BR OM_DRONE ;CONTROL SWAPS TO OTHER MACHINE
FLYCARPXXX
LDI @HEAD2HEAD_ON,R0 ;HEAD 2 HEAD RACE???
CALLNZ SEND_FLY_KILL ;SEND YOUR POSITION TO LINKED GAME
FLYCARPXXXX
CALL FREE_DRONE
LDI AR5,AR2
CALL DELCAR
LDI 1,R0
LSH O_PROC_B,R0 ;PROCESS BIT MASK IN OBJECT STRUCT
XOR *+AR4(OFLAGS),R0 ;WIPE OUT PROCESS BIT
STI R0,*+AR4(OFLAGS)
LDI AR4,AR2
CALL OBJ_DELETE
DIE
*
*CAR IS RIGHT SIDE UP
*
DEADCAR
LDI 1,R0
STI R0,*+AR5(CARSHAD) ;TURN BACK ON THE SHADOW
LDI *+AR4(OID),R0
ANDN TYPE_M,R0
OR DEAD_VEH_T,R0
STI R0,*+AR4(OID)
STI R0,*+AR5(CAR_ID)
STI R0,*+AR7(PID)
CLRF R0
STF R0,*+AR5(CARTHROTTLE)
STF R0,*+AR5(CARDROT)
STF R0,*+AR5(CARSPEED)
LDF *+AR7(PDATA+4),R0 ;GET Y ROTATION ORIENTATION
STF R0,*+AR5(CARVROT)
STF R0,*+AR5(CARYROT)
LDI 0,R0
STI R0,*+AR5(CAR_SPIN) ;CLEAR SPIN
DEADLP
LDI 2,R4
LDI *+AR4(ODIST),R0 ;DIE OFF WHEN OFFSCREEN
CMPI -6000,R0
BLT FLYCARPXX
LDF 0,R2 ;NO STEERING
CALL DRONEGO
CALL GETTRAK
DEADSLP
LDI @HEAD2HEAD_ON,R0 ;HEAD 2 HEAD RACE???
CALLNZ SEND_FLY_POS ;SEND YOUR POSITION TO LINKED GAME
SLEEP 1
B DEADLP
*
*KILL OFF FLY MESSAGE
*AR4= OBJECT
*AR5= CAR BLOCK
*
SEND_FLY_KILL
LDI @COMMQ_TMP_BUFFI,AR2
LDI CB_FLY_KILL,R1
STI R1,*AR2
LDI *+AR5(CARNUM),R0
STI R0,*+AR2(1)
LDI 2-1,RC
CALL MESSAGE_ADD
RETS
*
*KILL OFF FLY
*
DECODE_FLY_KILL
CALL FIND_DRONE ;GET DRONE OBJ IN AR0
BNZ DRKX
LDI *+AR0(OPLINK),AR7
LDI @FLYCARPXXXXI,R2 ;KILL THE SOMBITCH
STI R2,*+AR7(PWAKE) ;CHANGE WAKE-UP ADDR
DRKX
RETS
FLYCARPXXXXI .WORD FLYCARPXXXX
FLYCARPXXXI .WORD FLYCARPXXX
*
*KILL OFF FLY MESSAGE
*AR4= OBJECT
*AR5= CAR BLOCK
*AR7= PROCESS
*R4= STATE PARAMETER
*
SEND_FLY_XSFER
LDI @COMMQ_TMP_BUFFI,AR2
LDI CB_FLY_XSFER,R1
STI R1,*AR2++ ;SEND HEADER
LDI *+AR5(CARNUM),R1 ;SEND ID
STI R1,*AR2++
STI R4,*AR2++ ;SEND STATE
LDI AR7,AR0
ADDI PDATA,AR0 ;GET PDATA 0-5
LDI 5,RC
RPTB SENDP
LDI *AR0++,R0
STI R0,*AR2++
LSH -8,R0
STI R0,*AR2++
LSH -8,R0
STI R0,*AR2++
LSH -8,R0
SENDP STI R0,*AR2++
LDI 27-1,RC
LDI @COMMQ_TMP_BUFFI,AR2
CALL MESSAGE_ADD
RETS
*
*GET A FLYER FROM OTHER GAME
*AR2=MESSAGE BUFFER
*
DECODE_FLY_XSFER
CALL FIND_DRONE ;GET DRONE OBJ IN AR0
BNZ DFXX
LSH R2,*AR2++,R4 ;GET STATE
LDI *+AR0(OPLINK),AR1
ADDI PDATA,AR1 ;GET PDATA 0-5
LDI 8,R5
LDI 5,RC
RPTB DECP
LSH R2,*AR2++,R0
LSH R3,*AR2++,R1
ADDI R1,R0
ADDI *AR2++,R0
LSH R5,*AR2++,R1
ADDI R1,R0
DECP STI R0,*AR1++
LDI *+AR0(OCARBLK),AR5
LDI *+AR0(OPLINK),AR7
LDI 0,R0 ;OUR CAR NOW....
STI R0,*+AR5(CAR_OM)
LDI *+AR5(CARTRACK_ID),R2 ;GET TRACK ID
LDI @FLYCARPXXXI,R5 ;KILL THE SOMBITCH
LDI @DYNALIST_END,AR0 ;GET FURTHEST ROAD ID
LDI *+AR0(OUSR1),R0
CMPI R0,R2
BGT DFX1 ;TOO FAR OUT, DIE
LDI @DYNALIST_TRUEBEGIN,AR0
LDI *+AR0(OUSR1),R0
CMPI R0,R2
BLT DFX1 ;BEHIND US KILL HIM
LDI @DEADLPI,R5 ;DEFAULT
CMPI 0,R4 ;FLYIN'
LDIZ @FLYCARP0I,R5
CMPI 1,R4 ;ROCKIN'
LDIZ @FLYCARSTOPI,R5
DFX1
STI R5,*+AR7(PWAKE) ;CHANGE WAKE-UP ADDR
RETS
DFXX
ADDI 25,AR2 ;SKIP REST OF MESSAGE
RETS
DEADLPI .WORD DEADLP
FLYCARP0I .WORD FLYCARP
FLYCARSTOPI .WORD FLYCARSTOP
.GLOBL SEND_FLY_KILL,DECODE_FLY_KILL,SEND_FLY_POS,DECODE_FLY_XSFER
.GLOBL FIND_DRONE,COMPTRAK,OM_DRONE
*----------------------------------------------------------------------------
*GET MATRIX FOR FLYING CAR
*
*PARAMETERS
* PDATA+3,4,5 = X,Y,ZRAD
* AR4 OBJECT
* AR7 PROCESS
*
*R2,R3,AR2 TRASHED
*
GETFLYMAT:
LDF *+AR7(PDATA+5),R2
LDI AR4,AR2
ADDI OMATRIX,AR2
CALL FIND_ZMATRIX
LDPI @MATRIXAI,AR2
LDF *+AR7(PDATA+3),R2
CALL FIND_XMATRIX
LDI AR4,R2
ADDI OMATRIX,R2
LDI R2,R3
CALL CONCATMAT ;FORMULATE COMBINED MATRIX
LDPI @MATRIXAI,AR2
LDF *+AR7(PDATA+4),R2
CALL FIND_YMATRIX
LDI AR4,R2
ADDI OMATRIX,R2
LDI R2,R3
B CONCATMAT ;FORMULATE COMBINED MATRIX
;*
;*CONVERT XVEL,ZVEL TO CARSPEED,CARVROT
;*AR4=OBJECT
;*AR5=CAR OBJECT
;*
;GETCARVSPD
;
; LDF *+AR4(OVELX),R2 ;UPDATE CARVROT, CARSPEED
; LDF *+AR4(OVELZ),R3
; CALL ARCTANF
; SUBF 1.57,R0
; STF R0,*+AR5(CARVROT)
;
; MPYF R2,R2
; MPYF R3,R3
; ADDF R3,R2
; CALL SQRT
; STF R0,*+AR5(CARSPEED)
;
; RETS
*----------------------------------------------------------------------------
*COLLISION SCAN
*
*CHECK OBJECT AGAINST LIST
*
*PARAMETERS
* AR0 OBJECT
* AR1 ADDRESS OF LIST HEADER
*
PLYR_VS_DRONES:
COLSCAN
BD COLSCL0
LDI @_plyr1+PLY_CAR,AR0 ;GET PLAYER CAR
LDI @CAR_LISTI,AR1
SUBI OLINK3,AR1 ;SETUP INDEXING
********B COLSCL0
COLSCLP0
BNZD COLSCL ;DONT COLLIDE DUDES...
SUBF *+AR1(OPOSX),R2,R0
MPYF R0,R0
SUBF *+AR1(IR0),R3,R4
********BNZD COLSCL
MPYF R4,R4
ADDF R0,R4
FLOAT *+AR1(ORAD),R1
ADDF R5,R1
MPYF R1,R1 ;SQUARE THE RADIUS LENGTH
CMPF R1,R4 ;ARE WE WITHIN RADIUS?
BGT COLSCL
CALL COLCHK ;CHECK OUT COLLISION FURTHER
BNC COLSCL0 ;NO COLLIDE
LDI *+AR0(OCARBLK),AR4 ;CHECK FOR LOW SPEED PLOW
LDF *+AR4(CARSPEED),R0
LDI *+AR1(OCARBLK),AR5 ;CHECK FOR LOW SPEED PLOW
ADDF *+AR5(CARSPEED),R0
CMPF 100,R0
LDFGT 100,R0
SUBRF 100,R0
MPYF 0.02,R0
ADDF 1.0,R0
STF R0,@PMULT ;SPEED MULTIPLIER
B COLDISP
COLSCL0
LDI OPOSZ,IR0
LDF *+AR0(OPOSX),R2 ;GET X COORD
LDF *+AR0(OPOSZ),R3 ;GET Z COORD
FLOAT *+AR0(ORAD),R5 ;GET SUCKERS RADIUS
COLSCL
LDI *+AR1(OLINK3),R0
BNZD COLSCLP0
LDI R0,AR1
LDI *+AR1(OFLAGS),R0
TSTB O_NOCOLL,R0 ;check non-collide flag
********BNZD COLSCLP0
RETS
*----------------------------------------------------------------------------
*DRONE COLLISION SCAN
*CHECK DRONES AGAINST DRONES
*CHECK OBJECT AGAINST LIST
*
*PARAMETERS
* AR0 OBJECT
* AR1 ADDRESS OF LIST HEADER
*
DRONES_VS_DRONES:
CLDSCAN
LDPI @CAR_LIST,R0 ;GET LIST AND CHECK NULL
BNZD CLDSCL0
LDI R0,AR0
LDI R0,AR1
NOP
;------->BNZD CLDSCL0
RETS
CLDSCLP0
BNZD CLDSCL ;NOCOL BIT SET
SUBF *+AR1(OPOSX),R2,R0
MPYF R0,R0
SUBF *+AR1(IR0),R3,R4
;----> BNZD CLDSCL ;NOCOL BIT SET
MPYF R4,R4
ADDF R0,R4
FLOAT *+AR1(ORAD),R1
ADDF R5,R1
MPYF R1,R1 ;SQUARE THE RADIUS LENGTH
CMPF R1,R4 ;ARE WE WITHIN RADIUS?
BGT CLDSCL
CALL COLCHK ;CHECK OUT COLLISION FURTHER
BC COLDISP
CLDSCL0
LDI *+AR0(OFLAGS),R0
TSTB O_NOCOLL,R0 ;check non-collide flag
BNZ CLDSCL1 ;NON COLLIDABLE STEALTH OBJECT
LDF *+AR0(OPOSX),R2 ;GET X COORD
LDF *+AR0(OPOSZ),R3 ;GET Z COORD
LDI OPOSZ,IR0
FLOAT *+AR0(ORAD),R5 ;GET SUCKERS RADIUS
CLDSCL
LDI *+AR1(OLINK3),R0
BNZD CLDSCLP0
LDI R0,AR1
LDI *+AR1(OFLAGS),R0
TSTB O_NOCOLL,R0 ;check non-collide flag
;------->BNZD CLDSCLP0
CLDSCL1
LDI *+AR0(OLINK3),R0 ;GET NEXT LIST
BNZD CLDSCL0
LDI R0,AR1
LDI R0,AR0
NOP
;------->BNZD CLDSCL0
RETS
*----------------------------------------------------------------------------
*REPELL COLLISION OBJECTS
*
*PARAMETERS
* AR0 OBJECT 0
* AR1 OBJECT 1
*RETURNS
* AR2 POINTS TO NORMALIZED REPULSION VECTOR
* R0 VELOCITY MAGNITUDE OF REPULSION
*
*FIND REPULSION AXIS
*
REPELL:
LDPI @VECTORAI,AR2 ;COMPUTE REPULSION VECTOR
LDF *+AR0(OPOSX),R0
SUBF *+AR1(OPOSX),R0
STF R0,*AR2
LDF 0,R0
STF R0,*+AR2(1)
LDF *+AR0(OPOSZ),R0
SUBF *+AR1(OPOSZ),R0
STF R0,*+AR2(2)
CALL NORMALIZE ;NORMALIZE IT
*FIND RELATIVE VELOCITY MAGNITUDE
LDF *+AR0(OVELX),R0
SUBF *+AR1(OVELX),R0
MPYF R0,R0
LDF *+AR0(OVELZ),R1
SUBF *+AR1(OVELZ),R1
MPYF R1,R1
ADDF R0,R1,R2
BR SQRT
*----------------------------------------------------------------------------
*COLLISION CHECK
*
*PARAMETERS
* AR0 OBJECT 0
* AR1 OBJECT 1
* *-AR3(1) COLLISION PT
*
COLDISP:
*SET COLLISION BITS
LDI *+AR0(OCARBLK),AR4
LDI *+AR1(OCARBLK),AR5
*check vs helicopter -> not a normal collision
LDI *+AR1(OID),R2
CMPI DRONE_C|HELICOPTER,R2
BNE NOTHELI
SUBF *+AR1(OPOSX),*+AR0(OPOSX),R0
MPYF R0,R0
LDF *+AR0(OPOSY),R2
SUBF *+AR1(OPOSY),R2
MPYF R2,R2
ADDF R0,R2
LDF *+AR0(OPOSZ),R0
SUBF *+AR1(OPOSZ),R0
MPYF R0,R0
ADDF R0,R2
CALL SQRT
LDF *+AR1(ORAD),R1
MPYF 0.5,R1
CMPF R1,R0
RETSGT
NOTHELI
LDI *+AR0(OID),R2
AND CLASS_M|TYPE_M,R2
CMPI DRONE_C|RAILROAD,R2
BNE NTRN
CMPI *+AR1(OID),R2
RETSEQ
NTRN
LDF *+AR0(OPOSY),R0 ;MAKE SURE HEIGHT IS CLOSE
SUBF *+AR1(OPOSY),R0
ABSF R0
FLOAT 750,R1
CMPF R1,R0
RETSGT ;IF HEIGHT TO FAR AWAY, FORGET IT...
CALL IMPACT_SPARK
*REPELL CARS
CALL REPELL ;R0=REPULSION MAGNITUDE
CALL COLSND ;MAKE YOUR SOUND...
MPYF 0.5,R0 ;ADJUST MAGNITUDE FOR 1/2 EACH OBJECT
LDF R0,R1
MPYF *AR2,R0 ;MULTIPLY BY X,Z DIRECTIONAL VECTOR
MPYF *+AR2(2),R1
LDF *+AR0(OPOSX),R2 ;REPELL THE SUCKER (AR0)
LDF *+AR0(OPOSZ),R3
ADDF R0,R2
ADDF R1,R3
STF R2,*+AR0(OPOSX)
STF R3,*+AR0(OPOSZ)
LDI *+AR1(OID),R2
AND CLASS_M|TYPE_M,R2
CMPI DRONE_C|RAILROAD,R2
BEQ FLYTRAIN
LDF *+AR1(OPOSX),R2 ;REPELL THE SUCKER (AR1)
LDF *+AR1(OPOSZ),R3
SUBF R0,R2
SUBF R1,R3
STF R2,*+AR1(OPOSX)
STF R3,*+AR1(OPOSZ)
*
*ELASTIC COLLSION IN X AND Z
*FIND X AND Z VELOCITIES OF OBJ AR0
* AR4 OCARBLK OBJECT AR0
*
* COMPUTE: R4=XV1
* R5=ZV1
* R6=XV2
* R7=ZV2
LDI *+AR0(OCARBLK),AR4
LDF *+AR4(CARVROT),R2
; STF R2,@CAR1VROTI
ADDF @HALFPII,R2 ;CORRECT FOR 90 DEGREE ERROR
CALL _SINE
LDF *+AR4(CARSPEED),R3
; STF R3,@CAR1SPEEDI
MPYF R3,R0,R5 ;V1Zi (INIT ZV OBJECT 1)
CALL _COSI
MPYF R3,R0,R4 ;V1Xi (INIT XV OBJECT 1)
*FIND X AND Z VELOCITIES OF OBJ AR1
*AR5=OCARBLK OBJECT AR1
LDI *+AR1(OCARBLK),AR5
LDF *+AR5(CARVROT),R2
; STF R2,@CAR2VROTI
ADDF @HALFPII,R2 ;CORRECT FOR 90 DEGREE ERROR
CALL _SINE
LDF *+AR5(CARSPEED),R3
; STF R3,@CAR2SPEEDI
MPYF R3,R0,R7 ;V2Zi (INIT ZV OBJECT 2)
CALL _COSI
MPYF R3,R0,R6 ;V2Xi (INIT XV OBJECT 2)
*CHECK FOR FLYING COLLISION
CMPI @PLYCAR,AR0 ;PLAYERS CAR?
BNZ COLDISP0 ;NO
***************
; LDF *+AR4(CARSPEED),R0 ;PLAYER SPEED HIGH ENOUGH
; CMPF 60,R0
; BGT FLYCAR ;FLY THE SUCKER...
; B COLDISP0
******************
SUBF R4,R6,R0
MPYF R0,R0
SUBF R5,R7,R1
MPYF R1,R1
ADDF R1,R0 ;FIND CLOSING SPEED SQUARED
FLOAT 20000,R1 ;BIG MAGNITUDE ?
MPYF 2,R1 ;2X30000=60000
CMPF R1,R0
BLT COLDISP0 ;NOT A FLYER
PUSH AR2 ;SAVE REPULSION VECTOR DUDES...
FLOAT 70,R1 ;GET PROBABILITY FUNCTION
CALL DIV_F
FIX R0,AR2
CALL RANDPER
POP AR2
BNC COLDISP0 ;NOT A FLYER
LDF *+AR4(CARSPEED),R0 ;PLAYER SPEED HIGH ENOUGH
FLOAT 160,R1
CMPF R1,R0
BGT FLYCAR ;FLY THE SUCKER...
COLDISP0
PUSH AR3 ;SAVE COLLISION POINT
LDPI @MATRIXAI,AR3 ;GET TEMP STORE
*COMPUTE INELASTIC VELOCITY
LDF *+AR4(CARMASS),R1 ;GET MASS1
CMPI @PLYCAR,AR0
BNE COLIN1
MPYF @CHEAT,R1 ;BOOST MASS ON CHEAT
MPYF @CHEAT,R1
MPYF @CHEAT,R1
COLIN1
PUSHF R1
MPYF R4,R1,R2 ;M1XV1
MPYF R5,R1,R3 ;M1ZV1
LDF *+AR5(CARMASS),R0 ;GET MASS2
MPYF R6,R0,R1 ;M2XV2
ADDF R1,R2
MPYF R7,R0,R1 ;M2ZV2
ADDF R1,R3
POPF R1
ADDF R1,R0 ;GET M1+M2
; ADDF *+AR4(CARMASS),R0 ;GET M1+M2
CALL INV_F30
MPYF R0,R2 ;INELASTIC XV
MPYF R0,R3 ;INELASTIC ZV
STF R2,*+AR3(4) ;SAVE INELASTIC XV
STF R3,*+AR3(5) ;SAVE INELASTIC ZV
*COMPUTE (M1-M2)/(M1+M2)
LDF *+AR4(CARMASS),R1
ADDF *+AR5(CARMASS),R1
STF R1,*+AR3(3) ;SAVE M1+M2
LDF *+AR4(CARMASS),R0
SUBF *+AR5(CARMASS),R0
CALL DIV_F
STF R0,*AR3
*COMPUTE 2*M2/(M1+M2)
LDF *+AR3(3),R1
LDF *+AR5(CARMASS),R0
MPYF 2,R0
CALL DIV_F
STF R0,*+AR3(1)
*COMPUTE 2*M1/(M1+M2)
LDF *+AR3(3),R1
LDF *+AR4(CARMASS),R0
MPYF 2,R0
CALL DIV_F
STF R0,*+AR3(2) ;SAVE 2*M1/(M1+M2)
*X VELOCITY CASE OBJECT 1
MPYF *AR3,R4,R0 ;V1Xf = V1Xi(M1-M2)/(M1+M2)
MPYF *+AR3(1),R6,R1 ; + V2Xi(2*M2)/(M1+M2)
ADDF R1,R0,R2 ;V1XF
*Z VELOCITY CASE OBJECT 1
MPYF *AR3,R5,R0 ;V1Zf = V1Zi(M1-M2)/(M1+M2)
MPYF *+AR3(1),R7,R1 ; + V2Zi(2*M2)/(M1+M2)
ADDF R1,R0,R3 ;V1ZF
*ADD INELASTIC VELOCITY OBJECT 1
LDF *+AR3(4),R0
LDF *+AR3(5),R1
MPYF 0.75,R0
MPYF 0.75,R1
MPYF 0.25,R2
MPYF 0.25,R3
ADDF R0,R2
ADDF R1,R3
*ADD REPULSION VELOCITY OBJECT 1
LDF 10.0,R0 ;VELOCITY REPULSION CONSTANT
; LDF *+AR4(CARMASS),R1 ;DIVIDE BY MASS
; CALL DIV_F
LDF *AR2,R1 ;X REPULSION VELOCITY
MPYF R0,R1
ADDF R1,R2
LDF *+AR2(2),R1 ;Z REPULSION VELOCITY
MPYF R0,R1
ADDF R1,R3
**********debugging stuff
; STF R4,@CAR1XVI ;SAVE YOUR VELOCITIES
; STF R5,@CAR1ZVI
; STF R6,@CAR2XVI
; STF R7,@CAR2ZVI
*************************end debug stuff
CALL ARCTANF
SUBPF @HALFPII,R0
*STORE VEL THETA, SPEED
PUSHF R0
; STF R0,*+AR4(CARVROT)
MPYF R2,R2
MPYF R3,R3
ADDF R3,R2
CALL SQRT
STF R0,*+AR4(CARSPEED)
; STF R0,@CAR1SPEEDF ;SAVE FOR DEBUG
*X VELOCITY CASE OBJECT 2
NEGF *AR3,R0 ;(M2-M1)/(M1+M2)
STF R0,*AR3
MPYF *AR3,R6,R0 ;V2Xf = V2Xi(M1-M2)/(M1+M2)
LDF *+AR3(2),R3
MPYF R3,R4,R1 ; + V1Xi(2*M1)/(M1+M2)
ADDF R1,R0,R2 ;V2XF
*Z VELOCITY CASE OBJECT 2
MPYF *AR3,R7,R0 ;V1Zf = V1Zi(M1-M2)/(M1+M2)
MPYF R3,R5,R1 ; + V2Zi(2*M2)/(M1+M2)
ADDF R1,R0,R3 ;V2ZF
*ADD INELASTIC VELOCITY OBJECT 2
LDF *+AR3(4),R0
LDF *+AR3(5),R1
MPYF 0.75,R0
MPYF 0.75,R1
MPYF 0.25,R2
MPYF 0.25,R3
ADDF R0,R2
ADDF R1,R3
CMPI @PLYCAR,AR0 ;HIT BY PLAYERS CAR?
BNE ZZZ1
MPYF @PMULT,R2 ;SLOW SPEED MULTIPLIER
MPYF @PMULT,R3
ZZZ1
*ADD REPULSION VELOCITY OBJECT 2
LDF -10.0,R0 ;VELOCITY REPULSION CONSTANT
; LDF *+AR5(CARMASS),R1 ;DIVIDE BY MASS
; CALL DIV_F
LDF *AR2,R1 ;X REPULSION VELOCITY
MPYF R0,R1
ADDF R1,R2 ;ADD TO XV
LDF *+AR2(2),R1 ;Z REPULSION VELOCITY
MPYF R0,R1
ADDF R1,R3 ;ADD TO ZV
CALL ARCTANF
LDP HALFPII
SUBF @HALFPII,R0
*STORE VEL THETA, SPEED
PUSHF R0 ;SAVE NEW CARVROT
MPYF R2,R2
MPYF R3,R3
ADDF R3,R2
CALL SQRT
STF R0,*+AR5(CARSPEED)
; STF R0,@CAR2SPEEDF ;SAVE FOR DEBUG
*NORMALIZE VELOCITY ROTATIONS OBJECT 2
POPF R2
LDF 0.333,R0 ;ADD A LITTLE RANDOM DIRECTION
CALL SFRAND
ADDF R0,R2
CALL NORMITS
STF R2,*+AR5(CARVROT)
; STF R2,@CAR2VROTF ;SAVE FOR DEBUG
*NORMALIZE VELOCITY ROTATIONS OBJECT 1
POPF R2
CALL NORMITS
STF R2,*+AR4(CARVROT)
; STF R2,@CAR1VROTF ;SAVE FOR DEBUG
POP AR3
*
*FIND ROTATIONAL FORCE AND DIRECTION IN XZ PLANE
*
*ORIGIN = OBJECT CENTER
*VECTOR 1= COLLISION POINT
*VECTOR 2= COLLISION POINT + RELATIVE VELOCITY
*AR0=OBJECT 0
*AR1=OBJECT 1
*R4= XV OBJ 1 (initial)
*R5= ZV OBJ 1 (initial)
*R6= XV OBJ 2 (initial)
*R7= ZV OBJ 2 (initial)
*AR3-1=COLLISION PT
*AR4 =CAR STRUCT AR0
*AR5 =CAR STRUCT AR1
*
*CHECK FOR SPIN
*
SUBF R6,R4,R0 ;GET RELATIVE XV
SUBF R7,R5,R1
CALL SPINROT
COLDSP30
PUSH AR1
PUSH AR0
PUSH AR1
LDI AR5,AR1 ;SWAP AR4,AR5
LDI AR4,AR5
LDI AR1,AR4
LDI AR0,AR1
POP AR0 ;SWAP AR0,AR1
SUBF R4,R6,R0 ;GET RELATIVE XV
SUBF R5,R7,R1 ;GET RELATIVE ZV
CALL SPINROT
POP AR0
POP AR1
COLDSPX
RETS ;FOR NOW DUDES
*----------------------------------------------------------------------------
*SPINROT CALCULATE SPIN ROTATION
*
*PARAMETERS
* AR0 OBJECT THAT HIT ME
* AR1 OBJECT
* AR3 COLLISION POINT VECTOR
* AR4 CAR BLOCK POINTER OBJECT THAT HIT ME
* AR5 CAR BLOCK POINTER
* R0 XV RELATIVE
* R1 ZV RELATIVE
*
*CALCS
* *+AR5(CARDROT) AMOUNT TO SPIN CAR
* *+AR5(CAR_BUMP) 0=SMALL COLLISION, 1=BIG COLLISION
* *+AR5(CAR_SPIN) SPIN TIME/ FLAG
* *+AR5(CARSPRAD) RADIANS TO SPIN
.BSS PLYRBEHIND,1
*
SPINROT:
LDI 0,R2
STI R2,@PLYRBEHIND ;PLAYER HIT FROM BEHIND FLAG
PUSHF R0
PUSHF R1
MPYF R0,R0 ;GET INTENSITY OF RELATIVE SPEED
MPYF R1,R1
ADDF R0,R1,R2
CALL SQRT
LDF R0,R3 ;SAVE INTENSITY
CMPF 20,R0 ;SET BUMP FLAG FOR BIGGIE
LDIGT 1,R2
LDILE 0,R2
STI R2,*+AR5(CAR_BUMP)
POPF R1
POPF R0
PUSHF R3 ;SAVE INTENSITY
LDPI @VECTORAI,AR2
LDF *+AR1(OPOSX),R2 ;GET OBJECT2 XZ CENTER ORIGIN
SUBF3 R2,*-AR3(1),R2 ;GET RELATIVE POSITION OF COLLISION PT.
STF R2,*AR2
LDF *+AR1(OPOSZ),R2
SUBF3 R2,*+AR3(1),R2
STF R2,*+AR2(1)
*GET RELATIVE VELOCITY OBJECT AR1 PERSPECTIVE
MPYF 0.5,R0 ;MAKE THIS SMALL
ADDF *AR2,R0
STF R0,*+AR2(2)
MPYF 0.5,R1 ;MAKE THIS SMALL
ADDF *+AR2(1),R1
STF R1,*+AR2(3)
*COMPUTE CROSS PRODUCT
MPYF *AR2,R1,R1
MPYF *+AR2(1),R0,R0
SUBF R0,R1 ;THIS CROSS PRODUCT SIGN
PUSHF R1 ;SAVE THE SIGN DUDES
*GET ROTATIONAL INTENSITY
*NORMALIZE VECTORS
*NORMALIZE RADIUS VECTOR
MPYF *AR2,*AR2,R3
MPYF *+AR2(1),*+AR2(1),R1
ADDF R1,R3,R2
CALL SQRT
PUSHF R0 ;SAVE THE RADIUS LENGTH
CALL INV_F30
MPYF *AR2,R0,R1
STF R1,*AR2
MPYF *+AR2(1),R0,R1
STF R1,*+AR2(1)
*NORMALIZE IMPACT VECTOR
LDF *+AR2(2),R1
MPYF R1,R1,R3
LDF *+AR2(3),R1
MPYF R1,R1
ADDF R1,R3,R2
CALL SQRT
CALL INV_F30
LDF R0,R1
MPYF *+AR2(2),R0
MPYF *+AR2(3),R1
*COMPUTE DOT PRODUCT TO GET ANGLE
*COSINE=DOT PRODUCT
MPYF *AR2,R0
MPYF *+AR2(1),R1
ADDF R0,R1 ;R3=DOT PRODUCT
ABSF R1
SUBRF 1.0,R1
POPF R0 ;GET RADIUS LENGTH
MPYF R0,R1
MPYF 2,R1 ;FUDGE FACTOR
POPF R0 ;GET SIGN
LDFN -15.0,R0 ;LOAD FUDGE FACTOR
LDFNN 15.0,R0
MPYF R1,R0 ;DO IT DUDE
LDF *+AR5(CARMASS),R1 ;ADJUST FOR MASS
CMPF 2.0,R1
LDFGE 10.0,R1 ;HEAVY MASS ADJUSTMENT
CALL DIV_F
STF R0,@SPINTEMP ;SPIN TIME TEMP
*
*GET THE SPIN TIME
*
*R0 ROTATION SPEED (FLOAT)
*AR1 OBJECT
*AR5 CAR BLOCK POINTER
*
POPF R3 ;GET INTENSITY OF COLLISION
STF R3,@COLVEL ;COLLISION RELATIVE VELOCITY
LDI *+AR5(CAR_SPIN),R1 ;CHECK IF ALREADY SPINNING
CMPI 1,R1
BZ SPINNIT ;YES...
CMPI @PLYCAR,AR1 ;PLAYERS CAR?
BNZ DRONESPIN
*PLAYER SPIN
*
*R0 ROTATION SPEED (FLOAT)
*R3 COLLSION RELATIVE SPEED
*AR1 OBJECT
*AR5 CAR BLOCK POINTER
*
PLYRSPIN
CALL BEHINDCK ;CHECK IF PLAYER HIT FROM BEHIND
CMPF 50,R3
BGT PLSPIN1 ;BIG BUMP...
CALL CKBOUNCE
BNC SPINBUMP
B SPINBOUNCE
PLSPIN1
CMPF 100,R3
BGT PLBIG ;SPIN, RELATIVE VELOCITY LARGE
LDI 500,AR2 ;SPIN PROBABILITY
CALL RANDPER
BC PLSPIN2 ;NORMAL SPIN
CALL CKBOUNCE
BC SPINBOUNCE ;DO A BOUNCE
PLSPIN2
LDI @CAMVIEW,R2
LDINZ 150,AR2
LDIZ 100,AR2 ;LESS SPIN 1ST PERSON
CALL RANDPER
BC PSPINNIT ;NORMAL SPIN
B SPINBUMP
PLBIG
LDI @CAMVIEW,R2
LDINZ 500,AR2
LDIZ 250,AR2 ;LESS SPIN 1ST PERSON
CALL RANDPER
BC PSPINNIT ;NORMAL SPIN
CALL CKBOUNCE
BC SPINBOUNCE ;DO A BOUNCE
B SPINBUMP
*
*CHECK IF PLAYER HIT FROM BEHIND
*
BEHINDCK
PUSHF R0
PUSHF R3
PUSH AR2
PUSH AR3
PUSH AR4
PUSH AR0
LDI AR0,AR2
LDI AR4,AR3
LDI AR1,AR4
CALL CKAHEAD ;IS PLAYER AHEAD?
LDIGE 0,R0 ;NO
LDILT 1,R0 ;YES
STI R0,@PLYRBEHIND
POP AR0
POP AR4
POP AR3
POP AR2
POPF R3
POPF R0
RETS
*
*CHECK PLAYER SPINNOUT
*
PSPINNIT
LDI @PLYRBEHIND,R2
BNE SPINBUMP ;YES, JUST BUMP THE DUDE
B SPINNIT ;NO, SPIN 'EM OUT
SPINBOUNCE
LDF *+AR5(CARSPEED),R4
CMPF 20,R4 ;MINIMUM SPEED VALUE
LDFLT 20,R4
STF R4,*+AR5(CARSPEED) ;REVERSE SPEED
MPYF 1.5,R4
FIX R4,R0 ;BOUNCE TIME
CMPI 60,R0
LDIGT 60,R0 ;MAX AT 40
STI R0,*+AR5(CAR_SPIN)
FLOAT R0,R1
LDF R2,R0 ;MOVE TO MIDDLE
CALL DIV_F
MPYF -6.0,R0
; LDF R2,R2 ;CORRECTION FACTOR
; LDFGT -0.04,R0
; LDFLE 0.04,R0
;; LDF 0,R0
STF R0,*+AR5(CARDROT)
LDF 0,R1 ;CARSPRAD
B SPINXX
*DRONE SPIN
*R0 ROTATION SPEED (FLOAT)
*R3 COLLSION RELATIVE SPEED
DRONESPIN
ABSF R0,R1 ;COMPUTE SPIN PROBABILITY
CMPF 0.1,R1
BLT SPINBUMP ;NO SPIN, TOO SMALL
CMPF 30,R3
BLT SPINBUMP ;NO SPIN, RELATIVE VELOCITY SMALL
CMPF 140,R3
BGT DSPIN ;SPIN, RELATIVE VELOCITY LARGE
FIX R3,AR2 ;GET SPIN PROBABILITY
SUBI 30,AR2
MPYI 6,AR2
ADDI 160,AR2
CALL RANDPER
BNC SPINBUMP
*
*DRONE TOTAL SPINOUT
*
DSPIN
ABSF @SPINTEMP,R2 ;GET SPIN MAGNITUDE
CMPF 10,R2
LDFGT 10,R2
MPYF 0.1,R2
MPYF 0.08,R2
LDF 0.06,R0 ;GET SOME RANDOMNESS IN SPIN RATE
CALL FRAND
ADDF 0.04,R0
ADDF R0,R2
LDF @SPINTEMP,R0 ;GET SIGN (SPIN DIRECTION)
BNN DSPIN1
NEGF R2
DSPIN1
LDF 6.28,R0 ;ONCE OR TWICE AROUND
CALL FRAND
LDF 3.14,R1 ;CARSPRAD
ADDF R0,R1
LDF *+AR5(CARMASS),R0 ;HEAVY MASS ?
CMPF 2.0,R0
BLT DSPIN0 ;NOPE
MPYF 0.5,R2 ;CUT DOWN SPIN SPEED
LDF 3.14,R1 ;CARSPRAD
DSPIN0
CALL ANGMOM
STF R2,*+AR5(CARDROT)
LDI 1,R0 ;SET RADIAN SPIN FLAG
B SPINX
*
* SPINNIT: TOTAL SPINOUT
*SET RANGE TO .08 -.12 DUDES
*
SPINNIT
ABSF @SPINTEMP,R2 ;GET SPIN MAGNITUDE
CMPF 10,R2
LDFGT 10,R2
MPYF 0.1,R2
MPYF 0.08,R2
ADDF 0.1,R2
LDF @SPINTEMP,R0 ;GET SIGN (SPIN DIRECTION)
BNN SPINTM0
NEGF R2
SPINTM0
CALL ANGMOM
CMPI @PLYCAR,AR1 ;PLAYERS CAR?
LDFZ 0.08,R1 ;PLAYER MIN
LDFNZ 0.02,R1 ;DRONE MIN
ABSF R2,R0 ;MINIMUM SPIN RATE FOR PLAYER
CMPF R1,R0
BGT SPINTM1
LDF R2,R2
LDFLT -1,R2
LDFGE 1,R2
MPYF R1,R2
SPINTM1
STF R2,*+AR5(CARDROT)
LDI *+AR5(CAR_SPIN),R1 ;CHECK IF ALREADY SPINNING
CMPI 1,R1
LDFZ *+AR5(CARSPRAD),R1 ;YES... SAVE CARSPRAD
LDFNZ 3.14,R1 ;NO NEW CARSPRAD
LDI 1,R0
B SPINX
*
*MOMENTARY BUMP SPIN
*R3=RELATIVE VELOCITY OF HIT
*
SPINBUMP
LDF @SPINTEMP,R2
CMPF 0.05,R2
LDFGT 0.05,R2
CMPF -0.05,R2
LDFLT -0.05,R2
CALL ANGMOM ;ADJUST ANGULAR MOMENTUM
CMPF 80,R3
LDFGT 80,R3
MPYF 0.0125,R3 ;ADJUST ROTATE FOR REL VEL
MPYF R3,R2
LDF @COLVEL,R0
MPYF 0.4,R0
CMPF 35,R0
LDFGT 35,R0
CALL FRAND
CMPI @PLYCAR,AR1 ;ARE WE PLAYERS CAR?
BNE SPINB0
MPYF 0.7,R0 ;LESS SPIN FOR PLAYER
SPINB0
CMPF 8,R0
LDFLT 8,R0
FIX R0
CMPI @PLYCAR,AR0 ;HIT BY PLAYERS CAR?
BNZ SPINBUMP1 ;NO
ADDI 5,R0 ;YES, BOOST SPIN TIME
SPINBUMP1
LDI @PLYRBEHIND,R1 ;REDUCE FOR PLAYER HIT BEHIND
BZ SPINBX
CMPI 14,R0 ;MAX TIME AT 14
LDIGT 14,R0
LSH -1,R0 ;DIVIDE TIME BY 1/2
SPINBX
STF R2,*+AR5(CARDROT)
LDF 0,R1 ;CARSPRAD
SPINX
STI R0,*+AR5(CAR_SPIN)
SPINXX
STF R1,*+AR5(CARSPRAD)
LDF *+AR1(OMAT11),R0 ;IF CAR FLIPPED, REVERSE CARDROT
BGE SPINXXX
NEGF *+AR5(CARDROT),R0
STF R0,*+AR5(CARDROT)
SPINXXX
RETS
*
*ANGULAR MOMENTUM
*R2=NEW ANGULAR MOMENTUM
*
ANGMOM:
LDI *+AR5(CAR_SPIN),R3 ;ADD IN EXISTING INERTIA
BZ ANGM1
LDF *+AR5(CARDROT),R3 ;GET OLD MOMENTUM
MPYF 0.5,R3 ;FUDGE FACTOR
ADDF R3,R2
MPYF 0.67,R2
ANGM1
RETS
*----------------------------------------------------------------------------
*
*CHECK FOR BOUNCE ALLOWED
*AR5 CAR BLOCK
*C=O.K., NC=FAIL
*R0=ROADIR
*R2=YROT-ROADIR
*
CKBOUNCE
CALL ROADIR ;GET DIRECTIONAL DIFFERENCE
LDF *+AR5(CARVROT),R1
SUBF R1,R0,R2
CALL NORMITS
ABSF R2,R3 ;VELOCITY BACKWARDS?
CMPF 1.75,R3
BLT CKBNCX ;NO...
LDF *+AR5(CARYROT),R2 ;JUST BOUNCE HIM WITH TIMED SPIN
SUBF R0,R2
CALL NORMITS
ABSF R2,R3
CMPF 1.4,R3
BGT CKBNCX ;DIRECTION OUT OF RANGE
SETC
RETS
CKBNCX
CLRC
RETS
*
*CAR TO CAR COLLISION SOUND
*AR0=VEHICLE #1
*AR1=VEHICLE #2
*R0=IMPACT SPEED
*
.globl SCOLLTABI,RANDSND,RANDVSND
COLSND
PUSHF R0
PUSH AR0
PUSH AR1
PUSH AR2
FLOAT @NFRAMES,R1
CALL DIV_F ;ADJUST IMPACT FOR FRAME RATE
LDF R0,R1
MPYF 0.01,R1
MPYF 0.7,R1
CMPF 1,R1
LDFGT 1,R1
MPYF 128,R1
ADDF 127,R1
FIX R1 ;VOLUME ADJUSTER
LDF *+AR1(OMAT11),R0 ;IS DRONE FLIPPED?
LDILT @SCUPDTABI,AR2 ;UPSIDE DOWN HIT SOUND
LDILT 4,R0 ;FOUR TABLE ENTRIES
BLT COLSND1
LDI @SCTABI,AR2
CMPI 220,R1
LDILT 5,R0
LDIGE 3,R0
COLSND1
CMPI @PLYCAR,AR0 ;PLAYERS CAR?
BNZ DRCOLSND ;NO, DO DRONE SOUND
CALL RANDVSND ;DO COLLISION SOUND+EXIT
B COLSNDX
* DRONE VS. DRONE
DRCOLSND
PUSH AR4
LDI AR0,AR4
CALL DRONESND
POP AR4
COLSNDX
POP AR2
POP AR1
POP AR0
POPF R0
RETS
SCUPDTABI .word SCUPDTAB
SCUPDTAB .word SCOLLF,SCOLLF,SCOLLG,SCOLLH
SCTABI .WORD SCTAB
SCTAB .WORD SCOLLA,SCOLLB,SCOLLC,SCOLLD,SCOLLE
*----------------------------------------------------------------------------
*DISPATCH COLLISION
*----------------------------------------------------------------------------
*CHECK COLLISION BETWEEN 2 OBJECTS
*
*PARAMETERS
* AR0 OBJECT 1
* AR1 OBJECT 2
*RETURNS
* CARRY SET FOR COLLISION
*
*BLOWLIST ALLOCATIONS
*BLOWLIST+00 : OBJ0 BOX PTS (ORIGINAL)
*BLOWLIST+24 : OBJ0 BOX PTS (ROTATED, TRANLSATED)
*BLOWLIST+48 : OBJ1 BOX PTS (ORIGINAL)
*BLOWLIST+72 : OBJ1 BOX PTS (ROTATED, TRANSLATED)
*BLOWLIST+96 : OBJ0 PLANE EQUATIONS
*BLOWLIST+120: OBJ1 PLANE EQUATIONS
COLCHK:
PUSH R2
PUSH R3
PUSH R5
PUSH IR0
PUSH AR0
PUSH AR1
LDPI @BLOWLISTI,AR2
CALL GETBOX ;GET BOX POINTS FOR OBJECT 1
LDI AR1,AR0
CALL GETBOX ;GET BOX POINTS FOR OBJECT 2
*GET 6 EQUATIONS FOR BOX
*GET PLANE EQUATION
*4 COEFFICIENTS PER EQUATION
*N1,N2,N3,P.N WHERE N=NORMAL VECTOR, P= 1ST POINT IN LIST
*
LDI AR2,AR0 ;STORE NORMAL VECTORS HERE
LDPI @EQTABI,AR2
LDI 11,RC ;DO 2 X 6 EQUATIONS
RPTB PLANEQ
PUSH AR2
CALL GEN_NORMAL ;GETS NORMAL VECTOR
POP AR2
LDI *AR2++(3),AR3 ;GET FIRST POINT
MPYF *AR0++,*AR3++,R0 ;COMPUTE DOT PRODUCT
MPYF *AR0++,*AR3++,R1
MPYF *AR0++,*AR3++,R0
|| ADDF R0,R1,R2
ADDF R0,R2
PLANEQ STF R2,*AR0++ ;SAVE DOT PRODUCT
*CHECK POINTS OBJ1 VS EQ OBJ0
SUBI 48,AR0 ;GET OBJ 0 EQUATION BASE ADDR
LDI AR0,AR3
SUBI 23,AR3 ;GET INDEX PROJ POINTS OBJ 1+1
LDI 7,AR4 ;DO 8 POINTS
PNTCKL0
LDI AR0,AR2
LDI 5,RC ;DO 6 EQUATIONS
RPTB EQCHK0
MPYF *AR2++,*-AR3(1),R0
MPYF *AR2++,*AR3,R1
MPYF *AR2++,*+AR3(1),R0
|| ADDF R0,R1,R2
ADDF R0,R2
CMPF *AR2++,R2
BLT PNTNXT0 ;THIS POINT FAILED, GET A NEW ONE
EQCHK0 NOP
BU GOTCOL ;GOT A COLLISION
PNTNXT0
NOP *AR3++(3)
DBU AR4,PNTCKL0
*CHECK POINTS OBJ0 VS EQ OBJ1
ADDI 24,AR0 ;GET OBJ1 EQUATION BASE
LDI AR0,AR3
SUBI 95,AR3 ;GET INDEX PROJ POINTS OBJ 1+1
LDI 7,AR4 ;DO 8 POINTS
PNTCKL1
LDI AR0,AR2
LDI 5,RC ;DO 6 EQUATIONS
RPTB EQCHK1
MPYF *AR2++,*-AR3(1),R0
MPYF *AR2++,*AR3,R1
MPYF *AR2++,*+AR3(1),R0
|| ADDF R0,R1,R2
ADDF R0,R2
CMPF *AR2++,R2
BLT PNTNXT1 ;THIS POINT FAILED, GET A NEW ONE
EQCHK1 NOP
BU GOTCOL ;GOT A COLLISION
PNTNXT1
NOP *AR3++(3)
DBU AR4,PNTCKL1
CLRC ;NO COLLISION
POP AR1
POP AR0
COLCHKX
POP IR0
POP R5
POP R3
POP R2
RETS
GOTCOL
POP AR1 ;GET COLLIDING OBJECTS
POP AR0
SETC
BU COLCHKX
*----------------------------------------------------------------------------
*
*PROJECT BOX POINTS FOR OBJECT AR0
*R0=SIZING PARAMETER (1.00=TRUE SIZE)
*AR0= OBJECT
*AR2= STORAGE AREA FOR POINTS AND PROJECTION (48 WORDS)
*RET AR2= END OF STROAGE AREA+1
*TRASHES R0-R5
*
GETBOX:
LDF 1.0,R0 ;XMINUS MULT FACTOR
LDF 1.0,R1 ;YMINUS MULT FACTOR
LDF 1.0,R2 ;ZMINUS MULT FACTOR
LDF 1.0,R3 ;XPLUS MULT FACTOR
LDF 1.0,R4 ;YPLUS MULT FACTOR
LDF 1.0,R5 ;ZPLUS MULT FACTOR
GETBOX0:
PUSH AR4
PUSH AR5
PUSH AR6
*GET 8 POINTS FOR OBJ 0
LDI *+AR0(OCARBLK),AR5
MPYF *+AR5(CARXMINUS),R0
MPYF *+AR5(CARYMINUS),R1
MPYF *+AR5(CARZMINUS),R2
MPYF *+AR5(CARXPLUS),R3
MPYF *+AR5(CARYPLUS),R4
MPYF *+AR5(CARZPLUS),R5
LDI 2,IR0
PUSH AR2
NOP *AR2++
STF R0,*-AR2(1) ;X1
|| STF R1,*AR2++(IR0) ;Y1
STF R2,*-AR2(1) ;Z1
|| STF R3,*AR2++(IR0) ;X2
STF R1,*-AR2(1) ;Y2
|| STF R2,*AR2++(IR0) ;Z2
STF R0,*-AR2(1) ;X3
|| STF R4,*AR2++(IR0) ;Y3
STF R2,*-AR2(1) ;Z3
|| STF R3,*AR2++(IR0) ;X4
STF R4,*-AR2(1) ;Y4
|| STF R2,*AR2++(IR0) ;Z4
STF R0,*-AR2(1) ;X5
|| STF R1,*AR2++(IR0) ;Y5
STF R5,*-AR2(1) ;Z5
|| STF R3,*AR2++(IR0) ;X6
STF R1,*-AR2(1) ;Y6
|| STF R5,*AR2++(IR0) ;Z6
STF R0,*-AR2(1) ;X7
|| STF R4,*AR2++(IR0) ;Y7
STF R5,*-AR2(1) ;Z7
|| STF R3,*AR2++(IR0) ;X8
STF R4,*-AR2(1) ;Y8
|| STF R5,*AR2++ ;Z8
*
*ROTATE POINTS FOR OBJ 0
*AR0=OBJ 0
*AR1=OBJ 1
*AR2=RAM1 STORAGE AREA
*AR3=
*AR4=INDEX TO POINTS
*AR5=ROTATIONAL MATRIX
*AR6=TRANSVECTOR
*
LDI AR0,AR5
ADDI OMATRIX,AR5 ;rotational matrix
POP AR4 ;GET POINTER TO POINT LIST
SUBI 2,AR4 ;SETUP AT -2
LDPI @transvectorYI,AR6 ;transvector temp store
LDI 8,IR0
LDF *+AR0(OPOSX),R0
LDF *+AR0(OPOSY),R1
STF R0,*-AR6(1) ;transvector.x
|| STF R1,*AR6 ;transvector.y
LDF *+AR0(OPOSZ),R0
STF R0,*+AR6(1) ;transvector.z
LDI 7,RC
RPTB EOCV
LDF *++AR4(3),R4
*
*MULTIPLY BY ROTATION MATRIX
*AND ADD TRANSLATION (IN THAT ORDER)
*
MPYF3 *AR5++,*-AR4(1),R0
MPYF3 *AR5++,R4,R1
MPYF3 *AR5++,*+AR4(1),R1
|| ADDF3 R0,R1,R2
MPYF3 *AR5++,*-AR4(1),R0
|| ADDF3 R1,R2,R2
ADDF *-AR6(1),R2 ;*blowlist++ += translation[X]
MPYF3 *AR5++,R4,R1
|| STF R2,*AR2++ ;STORE ROTATED X
MPYF3 *AR5++,*+AR4(1),R1
|| ADDF3 R0,R1,R2
MPYF3 *AR5++,*-AR4(1),R0
|| ADDF3 R1,R2,R3
ADDF *AR6,R3 ;*blowlist++ += translation[Y]
MPYF3 *AR5++,R4,R1
|| STF R3,*AR2++ ;STORE ROTATED Y
MPYF3 *AR5--(IR0),*+AR4(1),R1
|| ADDF3 R0,R1,R2
ADDF R1,R2 ;FORM ROTATED Z
ADDF *+AR6(1),R2 ;ADD IN TRANSLATION Z
EOCV STF R2,*AR2++ ;STORE Z
POP AR6
POP AR5
POP AR4
RETS
*----------------------------------------------------------------------------
*TABLE OF 6 BOX EQUATIONS
*CLOCKWISE ORDER
VCTO .SET BLOWLIST+24
VCTO1 .SET BLOWLIST+72
EQTABI .WORD EQTAB
EQTAB
* OBJECT 0
.WORD VCTO+(3*0),VCTO+(3*2),VCTO+(3*3) ;FRONT
.WORD VCTO+(3*0),VCTO+(3*4),VCTO+(3*6) ;LSIDE
.WORD VCTO+(3*0),VCTO+(3*1),VCTO+(3*5) ;BOTTOM
.WORD VCTO+(3*2),VCTO+(3*6),VCTO+(3*7) ;TOP
.WORD VCTO+(3*1),VCTO+(3*3),VCTO+(3*7) ;RSIDE
.WORD VCTO+(3*7),VCTO+(3*6),VCTO+(3*4) ;BACK
* OBJECT 1
.WORD VCTO1+(3*0),VCTO1+(3*2),VCTO1+(3*3) ;FRONT
.WORD VCTO1+(3*0),VCTO1+(3*4),VCTO1+(3*6) ;LSIDE
.WORD VCTO1+(3*0),VCTO1+(3*1),VCTO1+(3*5) ;BOTTOM
.WORD VCTO1+(3*2),VCTO1+(3*6),VCTO1+(3*7) ;TOP
.WORD VCTO1+(3*1),VCTO1+(3*3),VCTO1+(3*7) ;RSIDE
.WORD VCTO1+(3*7),VCTO1+(3*6),VCTO1+(3*4) ;BACK
* LINE EQUATION TABLE PTS 2-6-7-3
LEQTABI .WORD LEQTAB
LEQTAB
.WORD VCTO+(3*2)+1,VCTO+(3*6)+1,VCTO+(3*7)+1
.WORD VCTO+(3*3)+1,VCTO+(3*2)+1
.END