
	.include	"road.i"
	.include	"car.i"
	.include	"playfield.i"
	.include	"mem_macros.i"

	.text
	.align	4
	.thumb
	
;***********************************************************
;*
;* search_nextmark_th (suche nächste wegmarke) 
;*
;* r6  = car_struct
;* r7  = road_struct
;*
;* return r0,r1 

	.global		search_nextmark_th
	.type		search_nextmark_th,function

	.align	4

search_nextmark_th

	mov	r2,pc
	bx	r2
	.arm	
	stmfd	sp!,{r3-r12,lr}
	orr	r2,pc,#1
	bx	r2
	.thumb
	
	ldr	r0,=(64*64)/8			;get Mem for Buffer
	stack_alloc_th_mc	r0		;get mem for Strecken_strukt (auf stack)
	
	ldr	r0,=rek_buffer
	str	r1,[r0]				;merke pointer
	
	ldr	r2,=(64*64)/8			;len
	bl	memclear32
	

	ldr	r0,[r6,#CAR_XE]
	ldr	r1,[r6,#CAR_YE]
	
	lsr	r0,r0,#16+4			;get 16ner pos
	lsr	r1,r1,#16+4
	
	ldr	r2,=setMapR			;set funk
	ldr	r3,=testMapR			;test funk
	ldr	r4,[r6,#CAR_LASTWMARK]		;last waymark $40 $80 $c0

	
	add	r4,#$40				;+$40
	cmp	r4,#$c0
	ble	lw_notc0
	mov	r4,#$40
lw_notc0
	str	r4,[r6,#CAR_LASTWMARK]		;last waymark $40 $80 $c0
	mov	r11,r6				;carstruct
	
	mov	r10,r7				;roadstrukt
	bl	search_rbr_th
	
	;****

	stack_free_th_mc
	
;
; r0        = x
; r1   	    = y
; r2        = searchvalue
; r6       = &suchgebiet
; r5       = breite

	;hier werden bist zu 2 Startest ausgeführt	

	bl	rand
	mov	r2,#1
	and	r1,r2
	add	r1,r1,#1
	mov	r11,r1
	
	mov	r0,r12
	mov	r1,r12
	
	lsr	r1,r1,#16	;y
	lsl	r0,r0,#16	;x:16
	lsr	r0,r0,#16	;x

	mov	r10,r7		;carstruct
starzuff

	mov	r2,#$4
	mov	r7,r10
	ldr	r3,[r7,#R_MAP_SP]	;&map
	mov	r4,#64
	mov	r5,#$4
	mov	r6,#3
	mov	r7,#3

	bl	quadr_test_th
	
	mov	r2,r11
	sub	r2,r2,#1
	mov	r11,r2
	bne	starzuff
	
	lsl	r0,r0,#16+4
	lsl	r1,r1,#16+4
	
	;****
	
	.align	4		;assembler füllt mit 0000 -> lsl r0,r0,#0 also nop
	mov	r2,pc
	bx	r2
	.arm	
	ldmfd	sp!,{r3-r12,lr}
	bx	lr
	.thumb

	
;***********************************************************
;*
;* suche nach ziel 
;*
;* r0  = x
;* r1  = y
;* r2  = setMapfunktion
;* r3  = testMapfunktion
;* r10 = &suchmap
;* r11 = suchwort


search_rbr_th	
	
	push	{r4,r5,r7,lr}
	ldr	r4,=sp_rek_save
	mov	r5,sp
	str	r5,[r4]			;save sp
	
	bl	fillRowByRow_th
	
breakRbRB
	
	ldr	r4,=sp_rek_save
	ldr	r5,[r4]			;save sp
	mov	sp,r5
	
	pop	{r4,r5,r7}			;ist der lr-wert
	pop	{r0}
	bx	r0	
;
; r0       = x
; r1   	   = y
; r2       = searchvalue
; r3       = &suchgebiet
; r4       = breite (suchgebiet)
; r5       = maske
; r6       = breite
; r7       = hoehe

quadr_test_th

	push	{r0-r7}
	
	mov	r8,r6
	mov	r9,r7
	lsr	r6,r6,#1	;/2
	lsr	r7,r7,#1	;/2

	sub	r0,r0,r6	;x-b/2
	sub	r1,r1,r7	;y-h/2

	add	r0,r0,r0	;x*2
	add	r1,r1,r1	;y*2
	add	r0,r0,r3	;+adr
	mul	r1,r4		;y*breite
	add	r0,r0,r1	;r0 = x*2+y*2+adr

	mov	r1,r8
	sub	r4,r1		;arraybreite - testbreite
	add	r4,r4,r4	;*2
	
	mov	r7,r9	
	
qfy	
	mov	r6,r8
qfx
	ldrh	r1,[r0]		;get word
	and	r1,r5		;maske
	cmp	r1,r2		;searchvalue ??
	beq	quadr_t
	add	r0,r0,#2

	sub	r6,r6,#1
	bne	qfx
		
	add	r0,r0,r4	;nächste zeile	
		
	sub	r7,r7,#1
	bne	qfy

	pop	{r0-r7}		;wenn wir hier sind ist etwas schief gegangen

	mov	r0,#0
	mvn	r0,r0
	mov	r1,r0

	bx	lr

quadr_t

	mov	r2,r8
	mov	r3,r9
	
	lsr	r4,r2,#1	;/2
	lsr	r5,r2,#1	;/2
	
	sub	r2,r4		
	sub	r3,r5

	sub	r2,r6
	sub	r3,r7
	
	mov	r8,r2
	mov	r9,r3

	pop	{r0-r7}

	add	r0,r8
	add	r1,r9
		
	bx	lr

;
; r0       = x
; r1   	   = y
; r2       = searchvalue
; r6       = &suchgebiet
; r5       = breite
; r7       = maske
;
; return r0,r1 x,y

star_test_th

	push	{r2-r5}
	
	sub	r0,r0,#1		;x-1
	sub	r1,r1,#1		;y-1
	
	add	r4,r0,r0		;x*2
	add	r3,r1,r1		;y*2
	
	add	r4,r4,r6		;+adr
	mov	r6,r5
	mul	r6,r3			;br*y
	add	r4,r6,r4		;br*y+x
	
	
	add	r5,r5,r5		;breite *2 (wegen addition später)
	
	;123 1=start
	;4x5
	;678 
	
	ldrh	r3,[r4]			;1
	and	r3,r7
	cmp	r3,r2
	beq	star_found
	
	add	r0,r0,#1		;x+1
	
	ldrh	r3,[r4,#2]		;2
	and	r3,r7
	cmp	r3,r2
	beq	star_found	
	
	add	r0,r0,#1		;x+1
	
	ldrh	r3,[r4,#4]		;3
	and	r3,r7
	cmp	r3,r2
	beq	star_found	
	
	add	r4,r4,r5		;nächste zeile
	sub	r0,r0,#2		;x-2
	add	r1,r1,#1		;y+1
		
	ldrh	r3,[r4]			;4
	and	r3,r7
	cmp	r3,r2
	beq	star_found
	
	add	r0,r0,#2		;x+2
	
	ldrh	r3,[r4,#4]		;5
	and	r3,r7
	cmp	r3,r2
	beq	star_found	
	
	add	r4,r4,r5		;nächste zeile
	sub	r0,r0,#2		;x-2
	add	r1,r1,#1		;y+1
	
	ldrh	r3,[r4]			;6
	and	r3,r7
	cmp	r3,r2
	beq	star_found
	
	add	r0,r0,#1		;x+1
	
	ldrh	r3,[r4,#2]		;7
	and	r3,r7
	cmp	r3,r2
	beq	star_found	
	
	add	r0,r0,#1		;x+1
	
	ldrh	r3,[r4,#4]		;8
	and	r3,r7
	cmp	r3,r2
	beq	star_found	
	
star_found	
	pop	{r2-r5}
	bx	lr

	.pool
	.arm


;***********************************************************
;*                     IWRAM                               *
;***********************************************************

	
	.SECTION    .iwram,"ax"  
    	.ARM
    	.align		4

sp_rek_save		.long	0
rek_buffer		.long	0

;***********************************************************
;*
;* byte2bit (kopiert puffer in bitpuffer (macht aus byte<>0 bit=1))
;*
;* r0  = input
;* r1  = output
;* r2  = länge (in byte)

fillBuffer



	mov	r2,#(30*20)/8	;länge
	
	mvn	r9,#0
	mov	r8,r9,lsl #16	;r8 = $ffff0000
	mov	r9,r9,lsr #16	;r9 = $0000ffff

fb_l	
	
	mov	r11,#0
		
	ldmia	r0!,{r3,r4,r5,r6}	;get 8 Bytes
	
	tst	r3,r9
	orrne	r11,r11,#1<<7
	tst	r3,r8
	orrne	r11,r11,#1<<6
	tst	r4,r9
	orrne	r11,r11,#1<<5
	tst	r4,r8
	orrne	r11,r11,#1<<4
	tst	r5,r9
	orrne	r11,r11,#1<<3
	tst	r5,r8
	orrne	r11,r11,#1<<2
	tst	r6,r9
	orrne	r11,r11,#1<<1
	tst	r6,r8
	orrne	r11,r11,#1<<0
	
	strb	r11,[r1],#1
	
	subs	r2,r2,#1
	bne	fb_l

	bx	lr


;***********************************************************
;*
;* testMapR (teste)
;*
;* r0  = x
;* r1  = y
;* r10 = roadstruct
;* r11 = carstruct
;*
;* return r0 = 0 nichts / 1 rand
	
testMapR

	stmfd	sp!,{r2,r3}
	
	orr	r12,r0,r1, lsl #16	;r12 = r0:r1

	add	r0,r0,r0		; = x*2
	add	r0,r0,r1, lsl #7	; = x + y * 64*2
	
	ldr	r2,[r10,#R_MAP_SP]	;&map
	ldrh	r1,[r2,r0]		;map(x,y)
	and	r3,r1,#$ff00		;koll
	and	r1,r1,#$00ff		;code
	ldr	r2,[r10,#R_MAP_SPI]	;&map_in
	ldr	r1,[r2,r1, lsl #2]	;get real word (code = r1)
		
	ldr	r0,[r11,#CAR_LASTWMARK]	;suchwert
	
	and	r2,r1,#$c0		;nur 40 80 c0
	cmp	r2,r0			;ist suchwert
	ldreq	r1,=breakRbRB+1
	bxeq	r1	
	
	;**** wenn nicht der suchwert dann
		
	;**** BG Stat übernehmen
		
		
	
	cmp	r1,#$01			;wenn 01 dann unten	
	streq	r1,[r11,#CAR_STAT]	;merke das
	cmp	r1,#$02			;wenn 02 dann oben
	streq	r1,[r11,#CAR_STAT]	;merke das
	
	;**** Filter darüber/darunter Kollision
	
	
	
	;r1 = data
	
	ldr	r2,[r11,#CAR_STAT]	;bekomme daten ob drüber oder drunter
	
	cmp	r1,#$10			;r5=$10 && data=1 dann r5 and not $10
	cmpeq	r2,#$01
	biceq	r1,r1,#$10
	
	cmp	r1,#$20			;r5=$20 && data=2 dann r5 and not $20		
	cmpeq	r2,#$02
	biceq	r1,r1,#$20	

	bic	r1,r1,#$07		;remove 1,2 & 4	
	
	orr 	r1,r1,r3		;koll dran
	;**** 

	cmp	r1,#0			;wenns nicht null ist dann ist es rand
	movne	r1,#0
	bne	eer

	;**** bittest

	mov	r1,r12, lsr #16
	bic	r0,r12,r1, lsl #16

	add	r0,r0,r1, lsl #6	; = x + y * 64
	mov	r1,r0, lsr #3		;r1 = bytes
	and	r0,r0,#$7		;r0 = bit im byte
	mov	r12,#$80	
	mov	r0,r12,lsr r0		;r0 = $80 >> r0
	ldr	r12,=rek_buffer		;get bitmap
	ldr	r12,[r12]
	ldrb	r12,[r1,r12]		;get byte
	and	r0,r12,r0		;get bit
		
eer	ldmfd	sp!,{r2,r3}	
	bx	lr

;***********************************************************
;*
;* setMapR (setze)
;*
;* r0  = x
;* r1  = y
;*

setMapR

	add	r0,r0,r1, lsl #6	; = x + y * 64 
	mov	r1,r0, lsr #3		;r1 = bytes
	and	r0,r0,#$7		;r0 = bit im byte
	mov	r12,#$80
	mov	r0,r12,lsr r0		;r0 = 1 << r0
	ldr	r12,=rek_buffer		;get bitmap
	ldr	r12,[r12]
	add	r1,r1,r12
	ldrb	r12,[r1]		;get byte
	orr	r12,r12,r0		;get bit
	strb	r12,[r1]		;get byte
		
	bx	lr
	
	.end