; ; INTER-CAR COLLISION CODE ; includesym bank00 include macro ; ; Local macros ; mSwapVectors macro v0 v1 ld bc,CarStructures+(v0*TSSize)+(TSXvector-CarStruc) ld de,CarStructures+(v1*TSSize)+(TSXvector-CarStruc) call SwapVectors endm ; ; Local equates ; MAG equ $100 ;DEBUG was $40 ;Add this to vector when cars touch thisbank $16 otherbank $02 org A_SWITCH_BANK jp InterCarCollisions ;$4000 ; ; Inter-car collisions ; Input: Car structures ; Output: Collisions global array collision bits set ; InterCarCollisions ; ; Collect the information we need from car data ; ld hl,T0X ;Local data destination ; ; ; otherbank 0 ld a,0 ;Car 0 push hl call GetCar pop hl ld a,(TSXpos+1) ;Xpos ld (hl),a ld a,(TSXpos+2) ld (hl),a ld a,(TSYpos+1) ;Ypos ld (hl),a ld a,(TSYpos+2) ld (hl),a ld a,(TSRot) ;Rot ld (hl),a ; ; ; ld a,1 ;Car 1 push hl call GetCar pop hl ld a,(TSXpos+1) ;Xpos ld (hl),a ld a,(TSXpos+2) ld (hl),a ld a,(TSYpos+1) ;Ypos ld (hl),a ld a,(TSYpos+2) ld (hl),a ld a,(TSRot) ;Rot ld (hl),a ; ; ; ld a,2 ;Car 2 push hl call GetCar pop hl ld a,(TSXpos+1) ;Xpos ld (hl),a ld a,(TSXpos+2) ld (hl),a ld a,(TSYpos+1) ;Ypos ld (hl),a ld a,(TSYpos+2) ld (hl),a ld a,(TSRot) ;Rot ld (hl),a ; ; ; ld a,3 ;Car 3 push hl call GetCar pop hl ld a,(TSXpos+1) ;Xpos ld (hl),a ld a,(TSXpos+2) ld (hl),a ld a,(TSYpos+1) ;Ypos ld (hl),a ld a,(TSYpos+2) ld (hl),a ld a,(TSRot) ;Rot ld (hl),a otherbank 2 ;RAM bank ; ; Solve for every possible inter-car collision ; L0 ld a,(Offscreen+0) ;If either offscreen, abort ld hl,Offscreen+1 or a jr nz,L9 ld bc,T0X+0 ;Cars 0,1 ld hl,T1X+0 call DetectCollision jr z,L9 ld hl,Collisions+0 ;Flag car 0 collision bit 1,(hl) ld hl,Collisions+1 ;Flag car 0 collision bit 0,(hl) mSwapVectors 0 1 L9 L0 ld a,(Offscreen+0) ;If either offscreen, abort ld hl,Offscreen+2 or a jr nz,L9 ld bc,T0X+0 ;Cars 0,2 ld hl,T2X+0 call DetectCollision jr z,L9 ld hl,Collisions+0 bit 2,(hl) ld hl,Collisions+2 bit 0,(hl) mSwapVectors 0 2 L9 L0 ld a,(Offscreen+0) ;If either offscreen, abort ld hl,Offscreen+3 or a jr nz,L9 ld bc,T0X+0 ;Cars 0,3 ld hl,T3X+0 call DetectCollision jr z,L9 ld hl,Collisions+0 bit 3,(hl) ld hl,Collisions+3 bit 0,(hl) mSwapVectors 0 3 L9 L0 ld a,(Offscreen+1) ;If either offscreen, abort ld hl,Offscreen+2 or a jr nz,L9 ld bc,T1X+0 ;Cars 1,2 ld hl,T2X+0 call DetectCollision jr z,L9 ld hl,Collisions+1 bit 2,(hl) ld hl,Collisions+2 bit 1,(hl) mSwapVectors 1 2 L9 L0 ld a,(Offscreen+1) ;If either offscreen, abort ld hl,Offscreen+3 or a jr nz,L9 ld bc,T1X+0 ;Cars 1,3 ld hl,T3X+0 call DetectCollision jr z,L9 ld hl,Collisions+1 bit 3,(hl) ld hl,Collisions+3 bit 1,(hl) mSwapVectors 1 3 L9 L0 ld a,(Offscreen+2) ;If either offscreen, abort ld hl,Offscreen+3 or a jr nz,L9 ld bc,T2X+0 ;Cars 2,3 ld hl,T3X+0 call DetectCollision jr z,L9 ld hl,Collisions+2 bit 3,(hl) ld hl,Collisions+3 bit 2,(hl) mSwapVectors 2 3 L9 ret ; ; Function: DetectCollision ; Input: X,Y,Rot car positions pointed by bc and hl ; DetectCollision ; ; Get X difference ; ld a,(bc) ;de = X difference sub (hl) ld e,a inc bc inc hl ld a,(bc) sbc a,(hl) ld d,a inc bc inc hl bit 7,a ;switch on sign bit jr z,PositiveX jr nz,NegativeX PositiveX ld a,e ;If >31 apart, abort sub <(CAR_WP-1) ld a,d sbc a,>(CAR_WP-1) bit 7,a L0 jr nz,L1 cp a ;Returning zero ret L1 ld a,e sra a ;collision detected at half resolution ld (DX),a ;save delta x jr DoneX NegativeX ;Here if x1-x2 < 0 ld a,e ;If >31 apart, abort sub <(0-CAR_WP+1) ld a,d sbc a,>(0-+1) bit 7,a L0 jr z,L1 cp a ;Returning zero ret L1 ld a,e ;Calc bit shift count inc a ;Round up negative numbers! sra a ;collision detected at half resolution ld (DX),a ;save delta x jr DoneX DoneX ld a,(bc) ;get difference in Y sub (hl) ld e,a inc bc inc hl ld a,(bc) sbc a,(hl) ld d,a inc bc inc hl bit 7,a ;switch on sign bit jr z,PositiveY jr nz,NegativeY PositiveY ;Here if x1-x2 >= 0 ld a,e ;If >31 apart, abort sub <(CAR_HP-1) ld a,d sbc a,>(CAR_HP-1) bit 7,a L0 jr nz,L1 cp a ;Returning zero ret L1 ld a,e ;Calc line count sra a ;collision detected at half resolution ld (DY),a ;save delta y jr DonePositiveY NegativeY ;Here if x1-x2 < 0 ld a,e ;If >31 apart, abort sub <(0-CAR_HP+1) ld a,d sbc a,>(0-CAR_HP+1) bit 7,a L0 jr z,L1 cp a ;Returning zero ret L1 ld a,e ;Calc line count inc a ;Round up negative numbers! sra a ;collision detected at half resolution ld (DY),a ;save delta y jr DoneNegativeY DonePositiveY ld a,(hl) ;Get car 0 rotation ld hl,Rot2BitImage ;Lookup collision image bits LookupWord IndirectHL ld a,(DY) ;Offset by DY LookupWord push hl ld a,(bc) ;Get car 1 rotation ld hl,Rot2BitImage LookupWord IndirectHLBC pop hl jr ProcessBits DoneNegativeY ld a,(hl) ;Get car 0 rotation ld hl,Rot2BitImage ;Lookup collision image bits LookupWord IndirectHL push hl ld a,(bc) ;Get car 1 rotation ld hl,Rot2BitImage LookupWord IndirectHL ld a,(DY) ;Offset by DY xor $FF inc a ld (DY),a LookupWord ld_bc_hl pop hl jr ProcessBits ProcessBits ld a,(DX) ;Save for MagnifyVector call ld (SavedDX),a ld a,(DY) ld (SavedDY),a LineLoop ld e,(hl) ;Load and shift primary bits inc hl ld d,(hl) inc hl ld a,(DX) ;Get shift count bit 7,a jr nz,RightShiftLoop ;Skip shift if zero or a ;Test for zero jr z,DoneShift ;Exit loop if zero LeftShiftLoop sla e ;Execute shift rl d dec a ;Count iterations jr nz,LeftShiftLoop ;Loop jr DoneShift RightShiftLoop srl d ;Execute shift rr e inc a ;Count iterations jr nz,RightShiftLoop ;Loop DoneShift ld a,(bc) ;AND primary with secondary bits inc bc and e ret nz ld a,(bc) inc bc and d ret nz ld a,(DY) ;Count lines until 16 inc a ld (DY),a cp 16 jr nz,LineLoop ret ;Will return zero if lines exhausted ; ; Function: Swap vecors ; Input: v0 addr in bc, v1 addr in de ; Output: 4 bytes pointed to, v0 swapped with v1 ; SwapVectors rept 2 push bc ;(temp)=(bc)-(de) push de ld_hl_de ld de,temp call SubtractWords pop de pop bc ld hl,temp ;DEBUG call MagnifyVector ld a,(SavedDY) ld (SavedDX),a push bc ;(bc)-=(temp) push de ld_de_bc ld hl,temp call SubtractWords pop de pop bc push bc ;(de)+=(temp) push de ld hl,temp call AddWords pop de pop bc inc bc ;Done with X, now do Y inc bc inc de inc de endm ret ; ; Subtract Words: (de)=(bc)-(hl) ; SubtractWords ld a,(bc) sub (hl) ld (de),a inc bc inc hl inc de ld a,(bc) sbc a,(hl) ld (de),a ret ; ; Add Words: (de)=(bc)+(hl) ; AddWords ld a,(bc) add a,(hl) ld (de),a inc bc inc hl inc de ld a,(bc) adc a,(hl) ld (de),a ret ; ; Magnify Vector in (hl) ; MagnifyVector ld a,(SavedDX) ;Test DX or DY or a ret z ;If zero, no magnification and %10000000 ;Sign bit determines polarity L0 jr nz,L1 jr z,L2 L1 ;Positive vector ld a,(hl) add a,MAG ld (hl),a jr L9 L2 ;Negative vector ld a,(hl) sub MAG ld (hl),a jr L9 L9 ret ; ; Binary data ; Rot2BitImage dw BI00, BI01, BI02, BI03, BI04, BI05 dw BI06, BI07, BI08, BI09, BI10, BI11 dw BI12, BI13, BI14, BI15, BI16, BI17 dw BI18, BI19, BI20, BI21, BI22, BI23 align 16 ;eliminate need for 2-byte increments BI00 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0111111111111111 dw %1111111111111111 dw %1111111111111111 dw %0111111111111110 dw %0011110000011110 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI01 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000001 dw %0000000011111111 dw %1111111111111111 dw %1111111111111110 dw %0111111111111000 dw %0011110000011000 dw %0001110000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI02 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000011110 dw %0000011111111110 dw %0000111111111110 dw %0011111111111110 dw %1111111111111110 dw %0111111111100110 dw %0011111100000000 dw %0001111000000000 dw %0000111000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI03 dw %0000000000000000 dw %0000000000000000 dw %0000000000010000 dw %0000000011111100 dw %0000001111111110 dw %0000111111111100 dw %0011111111111110 dw %0111111111101100 dw %1111111110000000 dw %0001111000000000 dw %0000111110000000 dw %0000001100000000 dw %0000001000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI04 dw %0000000000000000 dw %0000000000000000 dw %0000000111000000 dw %0000001111111000 dw %0000011111110000 dw %0000111111111100 dw %0000111111101100 dw %0001111111100000 dw %0011111111000000 dw %0011111110000000 dw %0011111111100000 dw %0000000011000000 dw %0000000001000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI05 dw %0000000000000000 dw %0000000000000000 dw %0000000111000000 dw %0000001111110000 dw %0000111111111000 dw %0000011111111000 dw %0000011111111000 dw %0000111111100000 dw %0000111111100000 dw %0001111111100000 dw %0001111111110000 dw %0000000000010000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI06 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000011111100000 dw %0001111111111000 dw %0001111111111000 dw %0000011111100000 dw %0000011111100000 dw %0000011111100000 dw %0000011111110000 dw %0001111111110000 dw %0001111111110000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI07 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000111111000000 dw %0000111111110000 dw %0001111111110000 dw %0001111111110000 dw %0001111111110000 dw %0000011111110000 dw %0000001111111000 dw %0000001111111000 dw %0000110000001100 dw %0000110000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI08 dw %0000000000000000 dw %0000000000000000 dw %0000000110000000 dw %0000111111000000 dw %0000111111000000 dw %0011111111100000 dw %0011111111110000 dw %0000011111111000 dw %0000001111111000 dw %0000000111111110 dw %0000011111111100 dw %0000011100000000 dw %0000001000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI09 dw %0000000000000000 dw %0000000000000000 dw %0000011100000000 dw %0001111110000000 dw %0011111111000000 dw %0001111111100000 dw %0000111111111000 dw %0011101111111100 dw %0010000111111110 dw %0000000011111000 dw %0000000101110000 dw %0000000111000000 dw %0000000010000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI10 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000111000000000 dw %0001111111000000 dw %0011111111110000 dw %0011111111111100 dw %0111011111111111 dw %0000000111111100 dw %0000000000111000 dw %0000000001110000 dw %0000000001100000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI11 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0001111000000000 dw %0011111111100000 dw %0111111111111110 dw %0001111111111110 dw %0110000011111100 dw %0010000000011000 dw %0000000000011000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI12 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0011111111111111 dw %0011111111111111 dw %0111111111111110 dw %0111111111111110 dw %0111000000111100 dw %0111000000111100 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI13 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000100 dw %0000000011111100 dw %0000111111111110 dw %0111111111111110 dw %0111111111111110 dw %0111111110011100 dw %0011100000001110 dw %0011100000000000 dw %0011100000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI14 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000001111000 dw %0000000111111100 dw %0000011111111110 dw %0001111111111100 dw %0111111111111100 dw %0111111100001100 dw %0111110000000000 dw %0011111000000000 dw %0000111000000000 dw %0000100000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI15 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000001111000 dw %0000000111111100 dw %0000001111111100 dw %0000111111111100 dw %0001111111111110 dw %0011111110001000 dw %0000111100000000 dw %0000011000000000 dw %0000011100000000 dw %0000001000000000 dw %0000000000000000 dw %0000000000000000 BI16 dw %0000000000000000 dw %0000000000000000 dw %0000000111110000 dw %0000000111111000 dw %0000001111111000 dw %0000001111111000 dw %0000011111111100 dw %0000111111101000 dw %0001111111000000 dw %0001111110000000 dw %0011111110000000 dw %0010000111000000 dw %0000000011000000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI17 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000000111100000 dw %0000000111110000 dw %0000001111111100 dw %0000001111111000 dw %0000011111101000 dw %0000011111100000 dw %0000111111000000 dw %0000111111000000 dw %0011100111110000 dw %0011100001100000 dw %0000000000100000 dw %0000000000000000 dw %0000000000000000 BI18 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0000011111100000 dw %0000011111100000 dw %0001111111111000 dw %0001111111111000 dw %0000011111100000 dw %0000011111100000 dw %0000011111100000 dw %0000111111110000 dw %0001111111111000 dw %0001100000011000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI19 dw %0000000000000000 dw %0000000000000000 dw %0000001111000000 dw %0000111111000000 dw %0000111111100000 dw %0001111111110000 dw %0001111111110000 dw %0000001111110000 dw %0000001111110000 dw %0000001111111000 dw %0000011111111100 dw %0000111111001100 dw %0000011100000110 dw %0000110000000000 dw %0000000000000000 dw %0000000000000000 BI20 dw %0000000000000000 dw %0000000000000000 dw %0000001110000000 dw %0000111111000000 dw %0000111111000000 dw %0001111111100000 dw %0011111111100000 dw %0001011111110000 dw %0000001111111000 dw %0000000111111000 dw %0000000111111110 dw %0000011110000110 dw %0000011100000000 dw %0000001000000000 dw %0000000000000000 dw %0000000000000000 BI21 dw %0000000000000000 dw %0000000000000000 dw %0000111000000000 dw %0001111100000000 dw %0011111110000000 dw %0111111111100000 dw %0011111111110000 dw %0111111111111000 dw %0011000111111100 dw %0001000011111011 dw %0000000001110001 dw %0000000111100000 dw %0000000011110000 dw %0000000000100000 dw %0000000000000000 dw %0000000000000000 BI22 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0001111100000000 dw %0011111111000000 dw %0111111111110000 dw %0001111111111100 dw %0111111111111111 dw %0011100011111110 dw %0001000000111100 dw %0000000001110000 dw %0000000001111000 dw %0000000000010000 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 BI23 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 dw %0011111000000000 dw %0011111111000000 dw %0111111111111000 dw %1111111111111111 dw %0011111111111110 dw %0011111111111100 dw %0001100000111100 dw %0000000000111100 dw %0000000000011100 dw %0000000000000100 dw %0000000000000000 dw %0000000000000000 dw %0000000000000000 if $ > A_SWITCH_BANK_END pseudwarn "Switch bank overflow" endif end