
	.align	4
	.thumb
	.include	"obj_kollision.i"

@****************************:	
@*:
@*: n_over_2
@*:
@*: r0 = n
@*: r1 = (n over 2)
@*:	  

	.global		n_over_2
	.type		n_over_2,function
  
n_over_2:
       
	@ n*(n-1)/2
       
       	sub	r1,r0,#1		
       	mul	r1,r0
       	asr	r1,r1,#1
       	
  	bx	lr

@****************************:	
@*:
@*: get_poly_middle_th
@*:
@*: r0 = anzahl punkte von Polygon
@*: r1 = &punkte von Polygon (punkte immer 16Bit)
@*:	
@* return:
@*:
@*: r5 = mittelpunktx
@*: r6 = mittelpunkty
@*:

	.global		get_poly_middle_th
	.type		get_poly_middle_th,function

get_poly_middle_th:
	
	mov	r8,lr
	push	{r0-r4,r7}
	
	mov	r5,#0
	mov	r6,#0
	
	mov	r7,r0
	
fall_pointsm:

	ldmia	r1!,{r4}	@x:y	!LE also y:x
	
	asr	r2,r4,#16	@x
	lsl	r3,r4,#16
	asr	r3,r3,#16	@y
	
	add	r5,r5,r3
	add	r6,r6,r2

	sub	r0,r0,#1
	bne	fall_pointsm	
	
	ldr r4,=fdiv		@divfunk
	
	mov	r0,r5		@x
	mov	r1,r7		@  / count
	
	
	mov	r3,pc
	add	r3,r3,#5	@+2befehle | 1
	mov	lr,r3
	bx	r4
	
	
	mov	r5,r0		@xm
	
	mov	r0,r6		@y
	mov	r1,r7		@  / count
	
	mov	r3,pc
	add	r3,r3,#5	@+2befehle | 1
	mov	lr,r3
	bx	r4

	mov	r6,r0		@ym
	
	pop	{r0-r4,r7}
	bx	r8
	
@****************************:
@*:
@*: get_poly_radius_th
@*:
@*: r0 = anzahl punkte von Polygon
@*: r1 = &punkte von Polygon (punkte immer 16Bit)
@*:
@*: r2 = mittelpunktx
@*: r3 = mittelpunkty
@*:
@* return:
@*:
@*: r7 = radius*radius
@*:


	.global		get_poly_radius_th
	.type		get_poly_radius_th,function
	
get_poly_radius_th:

	push	{r1-r6}
		
	mov	r7,#0
	
fall_points_th:	

	ldmia	r1!,{r4}	@x:y	!LE y:x
	
	asr	r6,r4,#16	@x
	lsl	r5,r4,#16
	asr	r5,r5,#16	@y
		
	sub	r5,r2,r5	@xm-x
	sub	r6,r3,r6	@ym-y
	
	mul	r5,r5		@(xm-x)²
	mul	r6,r6		@(ym-y)²
	
	add	r6,r6,r5
	
	cmp	r6,r7
	ble	no_rad_max
	
	mov	r7,r6

no_rad_max:
	sub	r0,r0,#1
	bne	fall_points_th
		
	pop	{r1-r6}	
	bx	lr
	
@****************************:
@*:
@*: check_obj_th (test auf spherische kollision, wenn ja teste punkt kollision)
@*:
@*: r4 = obj1
@*: r5 = obj2
@*:
@* return:
@*:
@*: r7 = 0 = no koll / 1 = koll
@*:
	
	.global		check_obj_th
	.type		check_obj_th,function
	
check_obj_th:

@:
	push	{r0-r4,lr}

	ldr	r0,[r4,#OBJ_STRUCT_MX]	
	ldr	r1,[r4,#OBJ_STRUCT_MY]
	ldr	r6,[r4,#OBJ_STRUCT_RAD]
	
	ldr	r2,[r5,#OBJ_STRUCT_MX]	
	ldr	r3,[r5,#OBJ_STRUCT_MY]
	ldr	r7,[r5,#OBJ_STRUCT_RAD]
	
	add	r6,r6,r7	@gesamtradius=radius1+radius2
	mul	r6,r6		@gesamtradius²

	sub	r0,r0,r2	@dx
	sub	r1,r1,r3	@dy
	
	mul	r0,r0		@dx²
	mul	r1,r1		@dy²
	
	add	r0,r0,r1	@dx²+dy²
	
	cmp	r0,r6		@abstand <> minabstand
	bgt	no_sphere_coll

	@****   teste obj1 gegen obj2
	
	push	{r4,r5}
	
	ldr r1,=obj_line_test
	mov	r2,pc
	add	r2,r2,#5
	mov	lr,r2
	bx	r1		

	pop	{r4,r5}

	cmp	r7,#1
	beq	no_sphere_coll
	
	@**** teste punkt - obj
	
	bl	pobj_in_obj_th		@punkt von obj1 in obj2
	cmp	r7,#1
	beq	no_sphere_coll
	
	eor	r4,r5
	eor	r5,r4
	eor	r4,r5
	
	bl	pobj_in_obj_th		@punkt von obj2 in obj1

no_sphere_coll:	

@no_reverse_test:

	pop	{r0-r4}
	pop	{r6}			@lr
	bx	r6
	
@****************************:
@*:
@*: pobj_in_obj_th (teste ob erste punkt von obj1 (r4) in obj2 (r5))
@*:
@*: ! kein bx
@*:
@*: r4 = obj1
@*: r5 = obj2
@*:
@* return:
@*:
@*: r7 = 0 = no koll / 1 = koll	
	
	
	@.global	pobj_in_obj_th
	@.type		pobj_in_obj_th,function
		
pobj_in_obj_th:

	push	{r4,r5,lr}
	
	ldr	r4,[r4,#OBJ_STRUCT_PT]		@&pt obj1
	
	ldr	r0,[r5,#OBJ_STRUCT_ECKEN]
	ldr	r1,[r5,#OBJ_STRUCT_PT]		@punkte von polygon
	ldr	r0,[r0]				@anzahl ecken polygon

	ldmia	r4!,{r2}			@get p1x,p1y von obj1
	
	ldr r7,=point_in_poly	
	mov	r5,pc
	add	r5,r5,#5
	mov	lr,r5
	bx	r7	
	
	pop	{r4,r5,pc}

	
@****************************:
@*:
@*: obj_sphere_coll_th (gehe über alle punkte von obj1 und teste ob diese in obj2)
@*:
@*: ! kein bx
@*:
@*: r4 = obj1
@*: r5 = obj2
@*:
@* return:
@*:
@*: r7 = 0 = no koll / 1 = koll
@*:


	.global		obj_sphere_coll_th
	.type		obj_sphere_coll_th,function

obj_sphere_coll_th:

	push	{r4,r5,lr}

	ldr	r0,[r4,#OBJ_STRUCT_ECKEN]
	ldr	r6,[r4,#OBJ_STRUCT_PT]		@&pt obj1
	ldr	r4,[r0]				@anzahl ecken obj1

	ldr	r0,[r5,#OBJ_STRUCT_ECKEN]
	ldr	r1,[r5,#OBJ_STRUCT_PT]
	ldr	r0,[r0]				@anzahl ecken obj2



for_all_pobj1:

	ldmia	r6!,{r2}	@get px,py

	@**
	
	@* r0 = anzahl punkte von Polygon
	@* r1 = &punkte von Polygon (punkte immer 16Bit)
	@* r2 = x:y
	@*
	@* r7 = 0 nicht in Polygon, 1 in Polygon
	@*
	
	ldr r7,=point_in_poly
	mov	r5,pc
	add	r5,r5,#5
	mov	lr,r5
	bx	r7		@check point against obj 2	
	cmp	r7,#1
	beq	pcoll_detected

	
	sub	r4,r4,#1
	bne	for_all_pobj1	
	
	mov	r7,#0		@keine kollision
	
pcoll_detected:
	pop	{r4,r5,pc}


@****************************:
@*:
@*: obj_line_x_line_wrapper_function (tested ob line1,line2 kreuzt)
@*:
@*: !!!läuft in obj_line_x_line hinein!!!
@*:
@* r0=x1:y1
@* r1=x2:y2
@* r5=x3:y3
@* r6=x4:y4
@*:

	.global		line_x_line_overhead
	.type		line_x_line_overhead,function
	
	.global		obj_line_x_line
	.type		obj_line_x_line,function

line_x_line_overhead:


	mov	r9,r0
	mov	r12,r1

	asr	r1,r5,#16			@y1
	lsl	r5,r5,#16
	asr	r0,r5,#16			@x1
	
	asr	r3,r6,#16			@y2
	lsl	r6,r6,#16
	asr	r2,r6,#16			@x2
	
	mov	r6,r9				@r6=r9 (r0)
	
	asr	r5,r6,#16			@y3
	lsl	r6,r6,#16
	asr	r4,r6,#16			@x3
	
	mov	r6,r12				@r6=r12 (r1)
	
	asr	r7,r6,#16			@y4
	lsl	r6,r6,#16
	asr	r6,r6,#16			@x4
	


@****************************:
@*:
@*: obj_line_x_line (tested ob line1,line2 kreuzt)
@*:
@*: r0=x1
@*: r1=y1
@*: r2=x2
@*: r3=y2
@*: r4=x3
@*: r5=y3
@*: r6=x4
@*: r7=y4
@*:
@*: r10=fdivs
@*: r11=schnittpunkt berechnen (wenn <> 0)
@*:
@* return:
@*: 
@*: r2 = xs (bei r11 an)
@*: r3 = ys (bei r11 an)
@*:
@*: r7 = 0 (nicht) / 1 (kreuzen)
@*:

	.set	LINE_MAXP	,16

obj_line_x_line:

	push	{lr}

	cmp	r0,r4
	bne	nicht_gleich
	cmp	r1,r5
	bne	nicht_gleich
	cmp	r2,r6
	bne	nicht_gleich
	cmp	r3,r7
	bne	nicht_gleich
	b	kreuz
	
nicht_gleich:	

	mov	r12,r0
	mov	r0,r11
	cmp	r0,#0
	mov	r0,r12
	bne	x_push			@speichere x1,x2,y1,y2 (r0,r1,r2,r3)
x_push_r:
		 
	sub	r3,r3,r1		@y21=y2-y1
	sub	r7,r7,r5		@y43=y4-y3
	sub	r1,r1,r5		@y13=y1-y3
	
	sub	r2,r2,r0		@x21=x2-x1
	sub	r6,r6,r4		@x43=x4-x3
	sub	r0,r0,r4		@x13=x1-x3

	@used r0,r1,r2,r3,r6,r7
	@free r4,r5


	mov	r5,#1
	lsl	r5,r5,#LINE_MAXP
	mov	r12,r5			@r12 = 2^LINE_MAXP
	
	@****

	mov	r4,r7			@y43
	mov	r5,r6			@x43
	
	mul	r4,r2			@y43*x21
	mul	r5,r3			@x43*y21
	
	sub	r4,r4,r5		@(y43*x21) - (x43*y21)
	beq	nokreuz
	
	mov	r8,r4			@den
	
	@test den
	
	mov	r4,r6			@x43
	mov	r5,r7			@y43
	
	mul	r4,r1			@x43*y13
	mul	r5,r0			@y43*x13
	
	sub	r4,r4,r5		@(x43*y13) - (y43*x13)	
	mov	r9,r4			@t1

	mov	r4,r2			@x21
	mov	r5,r3			@y21
	
	mul	r4,r1			@x21*y13
	mul	r5,r0			@y21*x13
	
	sub	r5,r4,r5		@(x21*y13) - (y21*x13)	= t2

	@t1 = (t1*2^n)/den
	@t2 = (t2*2^n)/den
	
	mov	r4,r9
	lsl	r5,r5,#LINE_MAXP		@t2<<LINE_MAXP
	lsl	r0,r4,#LINE_MAXP		@t1<<LINE_MAXP
	
	mov	r1,r8			@/den
	mov	r3,pc
	add	r3,r3,#5
	mov	lr,r3
	bx	r10

	mov	r6,r0			@t1 
	cmp	r0,#0			@if <=0 ot >= 2^LINE_MAXP then nokreuz
	ble	nokreuz
	
	cmp	r0,r12
	bge	nokreuz
	
	mov	r0,r5			@t2
	mov	r1,r8			@/den			
	mov	r3,pc
	add	r3,r3,#5
	mov	lr,r3
	bx	r10

	cmp	r0,#0			@if <=0 ot >= 2^LINE_MAXP then nokreuz
	ble	nokreuz
	
	cmp	r0,r12
	bge	nokreuz

	@**** geschnitten 

kreuz:
	mov	r7,r11
	cmp	r7,#0
	bne	x_calc		@schnittpunkt berechnen?
x_calc_r:

	mov	r7,#1		@kreuz
	pop	{r0}
	bx	r0
	
	@**** nicht geschnitten
	
nokreuz:

	mov	r7,r11
	cmp	r7,#0
	bne	x_redo_stack	@schnittpunkt berechnen? da keiner da mach stack sauber
x_redo_stack_r:

	mov	r7,#0		@nix
	pop	{r0}
	bx	r0	


@****: sichere x0,x1,x2,x3

x_push:
	push	{r0,r1,r2,r3}
	b	x_push_r


@****: calculiere schnittpunkt
x_calc:
	@(r0,r1,r2,r3,r6) = x1,y1,x2,y2t1

	pop	{r0,r1,r2,r3}	

	@ xs=x1+(t1*(x2-x1))Sar power
	@ ys=y1+(t1*(y2-y1))Sar power
	
	sub	r4,r2,r0		@x21=x2-x1
	sub	r5,r3,r1		@y21=y2-y1
	
	mul	r4,r4,r6		@*t1
	mul	r5,r5,r6		@*t1
	
	asr	r4,r4,#LINE_MAXP
	asr	r5,r5,#LINE_MAXP
	
	add	r2,r4,r0
	add	r3,r5,r1
	
	b	x_calc_r
	
@****: säubere stack bei keinem schnittpunkt

x_redo_stack:
	
	add	sp,sp,#4*4
	b	x_redo_stack_r
	
	.pool
	.end