
	.include	"road.i"
	.include	"car.i"
	.include	"playfield.i"
	.include	"mem_macros.i"
	.include	"obj_kollision.i"
	
	.text
	.align	4
	.arm
	
;***********************************************************
;*
;* init kollision für alle fahrzeuge 
;*
;* r6  = road_struct
;*
	
	.global		init_car_koll
	.type		init_car_koll,function		
		
init_car_koll

	stmfd	sp!,{r0-r12,lr}

	;**** get mem for cars

	ldr	r0,[r6,#R_CARCOUNT]
	
	mov	r1,#OBJ_KOLL_LEN		;anzahl cars * structuren
	mul	r2,r0,r1
	
	stmfd	sp!,{r6}
	mem_malloc_mc	membaseW_adr,r2	;get mem
	ldmfd	sp!,{r6}
	
	str	r2,[r6,#R_KOLL]			;merke

	;**** init structs
	
	ldr	r0,[r6,#R_CARCOUNT]
	ldr	r1,=car_ecken
	ldr	r4,=car_punkteorg
	ldr	r3,[r6,#R_KOLL]		
	ldr	r7,[r6,#R_CARS]			;carstruct
	
iks

	stmfd	sp!,{r0-r1,r3-r12}
	mem_malloc_mc	membaseW_adr,#8*4	;get mem for points
	ldmfd	sp!,{r0-r1,r3-r12}
	
	ldr	r8,[r7,#CAR_X_POS]
	ldr	r9,[r7,#CAR_Y_POS]
	ldr	r10,[r7,#CAR_WINKEL]
	ldr	r11,[r7,#CAR_ZOOM]


	mov	r8,r8,lsr #16
	mov	r9,r9,lsr #16

	add	r7,r7,#CAR_STRUCT_LEN
	
	str	r10,[r3,#OBJ_STRUCT_ROT]
	str	r11,[r3,#OBJ_STRUCT_ZOOM]
	str	r8,[r3,#OBJ_STRUCT_X]
	str	r9,[r3,#OBJ_STRUCT_Y]
	str	r2,[r3,#OBJ_STRUCT_PT]		;mem for points
	str	r1,[r3,#OBJ_STRUCT_ECKEN]	;anzahl ecken
	str	r4,[r3,#OBJ_STRUCT_PO]		;original punkte


	add	r3,r3,#OBJ_KOLL_LEN

	subs	r0,r0,#1
	bne	iks	

	ldmfd	sp!,{r0-r12,lr}
	bx	lr
	
;***********************************************************
;*
;* berechnenen der kollision 
;*
;* r11  = road_struct
;*	

	.global		test_car_koll
	.type		test_car_koll,function	
	
test_car_koll

	stmfd	sp!,{r0-r12,lr}
	
	;**** berechne daten neu (mx,my,...)
	
	ldr	r0,[r11,#R_CARCOUNT]
	ldr	r1,[r11,#R_KOLL]
	ldr	r7,[r11,#R_CARS]		

recs

	ldr	r2,[r7,#CAR_X_POS]
	ldr	r3,[r7,#CAR_Y_POS]
	ldr	r4,[r7,#CAR_WINKEL]		;0..ffff
	ldr	r5,[r7,#CAR_ZOOM]

	mov	r2,r2,lsr #16
	mov	r3,r3,lsr #16
	
	mov	r4,r4,lsr #6			;winkel/64

	add	r7,r7,#CAR_STRUCT_LEN
	
	str	r2,[r1,#OBJ_STRUCT_X]
	str	r3,[r1,#OBJ_STRUCT_Y]
	str	r4,[r1,#OBJ_STRUCT_ROT]		;0..1023
	str	r5,[r1,#OBJ_STRUCT_ZOOM]
	
	mov	r6,r1
	bl	recalc_obj
	
	add	r1,r1,#OBJ_KOLL_LEN

	subs	r0,r0,#1
	bne	recs
	
	b	notest
	;******************************************************************* TEST
	
	stmfd	sp!,{r0-r12}
	
	mov 	r6,#$4000000   		;dma
	mov	r1,#$0400
	orr	r1,r1,#$04		;mode 4 bg 2	
	strh 	r1,[r6]			;store
	
	mov	r1,#$6000000
	mov	r2,#240*160
	bl	memclear32
	mov	r2,#$0
	bl	wait
	
	
	ldr	r11,[r11,#R_KOLL]
	ldr	r2,[r11,#OBJ_STRUCT_ECKEN]	;&ecken	
	ldr	r10,[r11,#OBJ_STRUCT_PT]		;punkte
	

	ldr	r11,[r2]
	mov	r12,r10

draw_obj_l

	ldrsh	r0,[r10],#2
	ldrsh	r1,[r10],#2
	
	cmp	r11,#1
	moveq	r10,r12		;letzter ist erster
	
	ldrsh	r3,[r10]
	ldrsh	r4,[r10,#2]

	stmfd	sp!,{r10,r11,r12}
	
	mov	r9,#3
	ldr	r2,=draw_pixel
	bl	goline

	ldmfd	sp!,{r10,r11,r12}

	subs	r11,r11,#1
	bne	draw_obj_l		
	
	ldmfd	sp!,{r0-r12}
notest	
	;**********************************************************************
	
	;**** max berechne kollisionsanzahl
	
	ldr	r0,[r11,#R_CARCOUNT]	;objekte
	ldr	r2,=n_over_2+1
	mov	lr,pc
	bx	r2
	
	add	r1,r1,#1
	mov	r0,r1,lsl #2		;anzahl test * 4 (weil long)

	;**** get mem for kollision return
	
	stack_alloc_mc	r0		;r9=rückgabe speicher 
	mov	r9,r1
	
	ldr	r0,[r11,#R_CARCOUNT]	;objekte
	mov	r0,r0,lsl #2
	stack_alloc_mc	r0		;r3=r1=pointerspeicher
	mov	r3,r1
	
	;**** fill pointerarray
	
	ldr	r0,[r11,#R_CARCOUNT]	;objekte
	ldr	r2,[r11,#R_KOLL]	;objekte
fparr
	str	r2,[r1],#4	
	add	r2,r2,#OBJ_KOLL_LEN
	subs	r0,r0,#1
	bne	fparr
		
	;**** check kollision
		
	mov	r0,r3			;objstructs (pointerarray)
	ldr	r1,[r11,#R_CARCOUNT]	;anzahl
					;r9=&data
	stmfd	sp!,{r11}					
	bl	check_obj_coll
	ldmfd	sp!,{r11}
	
	;**** kollision auswerten
	
	ldr	r1,[r11,#R_CARCOUNT]	;anzahl
		
testk

	ldr	r0,[r9],#4
	cmp	r0,#-1
	beq	testke

	;**** kollision aufgetreten (1111:2222)


	mov	r2,r0,lsr #16		;obj 1111 = r2
	bic	r3,r0,r2,lsl #16	;obj 2222 = r3
	
	bl	cars_koll

	subs	r1,r1,#1
	bne	testk	
testke
	
	stack_free_mc
	stack_free_mc
	
	ldmfd	sp!,{r0-r12,lr}
	bx	lr


; r12 = fkt(r0,r1,r9)  ( r0,r1,r6 for free use )

draw_pixel
	
	add	r6,r0,#$6000000
	add	r6,r6,r1, lsl #8
	sub	r6,r6,r1, lsl #4
		
	bic	r6,r6,#1
	tst	r0,#1
	mov	r0,#$ff
	
	ldrh	r1,[r6]
	
	mov	r12,#$1
	moveq	r0,r0,lsl #8
	movne	r12,r12, lsl #8
	
	and	r1,r1,r0
	orr	r1,r1,r12
	
	movne	r12,r12, lsr #8
	
	strh	r1,[r6]	

	bx	lr
	

;***********************************************************
;*
;* bearbeite kollision 
;*
;* r2   = obj1
;* r3   = obj2
;* r11  = road_struct
;*
cars_koll
	stmfd	sp!,{r0-r12}

	mov	r0,#CAR_STRUCT_LEN
	
	mul	r2,r2,r0
	mul	r3,r3,r0
	
	ldr	r4,[r11,#R_CARS]

	add	r2,r2,r4
	add	r3,r3,r4
	
	ldr	r0,[r2,#CAR_BGMODE]	;BG_MODES
	ldr	r1,[r3,#CAR_BGMODE]	;BG_MODES
	
	;**** Wenn BG_Modes ungleich -> Fahrzeuge auf unterschiedlichen ebenen -> keine kollision
	
	cmp	r0,r1
	ldmnefd	sp!,{r0-r12}
	bxne	lr	
		
	ldr	r0,[r2,#CAR_WINKEL]	;winkel1
	ldr	r1,[r3,#CAR_WINKEL]	;winkel2
	
	add	r4,r0,r1
	mov	r4,r4, lsr #1		;dwinkel
	
	mov	r7,#$ff
	orr	r7,r7,#$ff00
	
	sub	r5,r4,#$2000		;-90°	aw
	add	r6,r4,#$2000		;+90°	bw
	
	and	r5,r5,r7
	and	r6,r6,r7
	
	cmp	r5,r6
	eorgt	r5,r6,r6
	eorgt	r6,r5,r5
	eorgt	r5,r6,r6
	
	ldr	r0,[r2,#CAR_X_POS]
	ldr	r1,[r2,#CAR_Y_POS]
	ldr	r7,[r3,#CAR_X_POS]
	ldr	r8,[r3,#CAR_Y_POS]
	
	sub	r0,r0,r7
	sub	r1,r1,r8
	
	mov	r0,r0,asr #16
	mov	r1,r1,asr #16
			
	stmfd	sp!,{r2,r3}	
	swi	$a0000		;arctan2 (r0,r1) = r0
	ldmfd	sp!,{r2,r3}
	
	;(tw>bw And tw<aw)
	
	mov	r1,#1		;p2p1
	
	cmp	r0,r6		
	ble	p2p1
	cmp	r0,r5
	bge	p2p1
	
	mov	r1,#0		;p1p2
	
p2p1	

	;**** setze fahrzeug das hintendrauf gefahren ist zurück

	cmp	r0,#0
	moveq	r4,r2		
	movne	r4,r3
	
	ldr	r7,[r4,#CAR_X_POS]
	ldr	r1,[r4,#CAR_Y_POS]
	ldr	r5,[r4,#CAR_DX]
	ldr	r6,[r4,#CAR_DY]
	mov	r5,r5,asr #6
	mov	r6,r6,asr #6
	sub	r7,r7,r5
	sub	r1,r1,r6
	str	r7,[r4,#CAR_X_POS]
	str	r1,[r4,#CAR_Y_POS]
	
	;cmp	r0,#0
	;movne	r4,r2		
	;moveq	r4,r3
	
	;ldr	r7,[r4,#CAR_X_POS]
	;ldr	r1,[r4,#CAR_Y_POS]
	;ldr	r5,[r4,#CAR_DX]
	;ldr	r6,[r4,#CAR_DY]
	;mov	r5,r5,asr #6
	;mov	r6,r6,asr #6
	;add	r7,r7,r5
	;add	r1,r1,r6
	;str	r7,[r4,#CAR_X_POS]
	;str	r1,[r4,#CAR_Y_POS]
	
	ldmfd	sp!,{r0-r12}
	bx	lr

car_kollision		
	
;***********************************************************
;*
;* aufräumen der kollsionsdaten 
;*
;* r6  = road_struct
;*
		
		
	.global		remove_car_koll
	.type		remove_car_koll,function			
		
remove_car_koll

	stmfd	sp!,{r0-r12,lr}



	ldr	r0,[r6,#R_CARCOUNT]
	ldr	r3,[r6,#R_KOLL]		
	
rks
	ldr	r12,[r3,#OBJ_STRUCT_PT]		;get temppoint adr
	stmfd	sp!,{r0,r1,r3,r6}
	mem_free_mc	membaseW_adr,r12
	ldmfd	sp!,{r0,r1,r3,r6}

	add	r3,r3,#OBJ_KOLL_LEN

	subs	r0,r0,#1
	bne	rks	
	

	ldr	r12,[r6,#R_KOLL]			;merke
	mem_free_mc	membaseW_adr,r12


	ldmfd	sp!,{r0-r12,lr}
	bx	lr
		
	
		
	
car_ecken	.long	4		;Ecken Anzahl
car_punkteorg	.hword	-10,6
		.hword	10,6
		.hword	10,-6
		.hword	-10,-6

		
	.end