*****************************************************************
* MODULE TITLE     :button_routines                             *
*                                                               *
* DESCRIPTION      :Button display and handling software        *
*                                                               *
*                                                               *
*                                                               *
*                        NAME                          DATE     *
*                                                               *
* LIST OF ROUTINES :setup_button_list                           *
*                   check_for_call_routine                      *
*                   check_to_see_hit                            *
*                   draw_buttons                                *
*                   delete_buttons                              *
*                   display_button                              *
*                   remove_button                               *
*                   display_button_list                         *
*                   remove_button_list                          *
*                                                               *
*****************************************************************

NOT_DEPRESSED	equ 0
DEPRESSED	equ 1

CUSTOM_BUTTON	equ 1
STANDARD_BUTTON	equ 0
TOGGLE_BUTTON	equ 2
HOLD_BUTTON	equ 4
NO_WAIT_BUTTON  equ 8

BUTTON_WIDTH	equ 112
BUTTON_HEIGHT	equ 16

OFFSET	equ 3	;to position in middle of button
EDGE	equ 4	;bass relief edge size



**************************************
***** SETUP BUTTON LIST          *****
**************************************
setup_button_list
	move.l	#$FFFFFFFF,button_list
	move.l	#$FFFFFFFF,button_delete_list
	move.l	#$FFFFFFFF,button_draw_list
	move.w	#0,button_counter
	rts

**************************************
***** CHECK FOR CALL ROUTINE     *****
**************************************
check_for_call_routine
	cmp.l	#$ffffffff,jump_routine
	beq.s	end_call_routine
	move.l	jump_routine,a0
	jsr	(a0)
end_call_routine	
	move.l	#$ffffffff,jump_routine
	rts
	
jump_routine
	dc.l	$ffffffff
		
**************************************
***** CHECK TO SEE HIT           *****
**************************************
check_to_see_hit

	
	cmp.w	#1,mouse_button_ind
	bne	button_not_down
	move.l	clicked_button,a0	;
	move.b	button_type(a0),d0	;
	btst	#2,d0			;
	beq.s	not_a_hold_button	;
	btst	#6,$bfe001		;
	bne.s	has_been_released	;
	btst	#3,d0
	bne.s	execute_button_proc
	cmp.w	#0,button_wait_counter
	beq	execute_button_proc
	subq.w	#1,button_wait_counter
	bra	quit_check_buttons
execute_button_proc
	move.l	button_proc(a0),jump_routine
	bra	quit_check_buttons	;
not_a_hold_button			;
	btst	#6,$bfe001
	beq	quit_check_buttons
has_been_released			;
	
	move.w	#0,mouse_button_ind
	move.l	clicked_button,a1
	btst	#1,button_type(a1)	;toggle button test
	bne.s	jump_to_button_routine	
	move.b	#0,button_clicked(a1)
	move.l	button_draw_ptr,a2
	move.l	button_delete_ptr,a3
	move.l	a1,(a2)+
	move.l	a1,(a3)+
	move.l	#$ffffffff,(a2)
	move.l	#$ffffffff,(a3)
	move.l	a2,button_draw_ptr
	move.l	a3,button_delete_ptr
jump_to_button_routine	
	btst	#2,button_type(a1)		;
	beq.s	not_hold_button			;
	cmp.w	#0,button_wait_counter
	bne.s	not_hold_button			;give nice feel to hold button
	move.w	#BUTTON_HOLD_WAIT,button_wait_counter
	move.l	#$ffffffff,jump_routine		;
	bra	quit_check_buttons		;
not_hold_button				
	move.w	#BUTTON_HOLD_WAIT,button_wait_counter	;
	move.l	button_proc(a1),jump_routine
	bra	quit_check_buttons
button_not_down	
	btst	#6,$bfe001		;test only
	beq	check_hits_by_user	;frig for editor only
	move.w	#0,left_first	
	bra	quit_check_buttons
check_hits_by_user	
	move.l	#button_list,a0	
check_buttons_loop	
	cmp.l	#$ffffffff,(a0)
	beq	quit_check_buttons		
	move.l	(a0),a1
	move.w	button_x(a1),d0
	move.w	button_y(a1),d1

test_current_window	
	cmp.w	#MAIN_BUTTON_SCREEN,current_frame	;jiggery pokery
	bne.s	window_up
	cmp.w	#MAIN_SCREEN,frame_type(a1)
	beq.s	check_button_frame_type
window_up
	move.w	frame_type(a1),d7
	cmp.w	current_frame,d7
	bne	not_a_hit

check_button_frame_type
	cmp.w	#WINDOW,frame_type(a1)	;is button in window
	bne.s	not_test_in_window
	cmp.w	#0,window_count		;any windows up??
	beq.s	check_that_button	
	move.l	window_list_ptr,a3
	move.l	-(a3),a4
	cmp.l	button_window(a1),a4
	bne	not_a_hit
	move.w	window_x(a4),d2
	add.w	d2,d0
	add.w	#BORDER_X,d0	;allow for border
	add.w	window_y(a4),d1	
	add.w	#BORDER_Y,d1	;allow for window y border
	bra.s	check_that_button


not_test_in_window
	cmp.w	#MAIN_BUTTON_SCREEN,frame_type(a1)
	bne.s	check_that_button
***---	STUFF TO ALLOW MYLES FULLSCREEN MODE
	tst.w	fullscreen_mode	
	beq.s	not_in_fc_mode
	bra	not_a_hit
not_in_fc_mode	
***---
	add.w	#BUTTON_WINDOW_OFFSET,d1
check_that_button
	move.w	d0,d2
	move.w	d1,d3
	btst	#0,button_type(a1)	;standard button test
	beq	normal_check_button
	***else get details***
	move.l	button_custom(a1),a2
	add.w	custom_button_x_size(a2),d2
	add.w	custom_button_y_size(a2),d3
	bra.s	check_for_click_in_button
normal_check_button	
	add.w	#BUTTON_WIDTH,d2	
	add.w	#BUTTON_HEIGHT,d3
	
check_for_click_in_button
	move.w	mouse_x,d7
	
***---	Another frig for fullscreen mode	

		cmp.w	#MAIN_BUTTON_SCREEN,frame_type(a1)
		beq.s	.skip

		btst	#INTB_HIRES,screen_mode
		bne.s	asr_needed
		beq.s	no_asr_needed
.skip

***---	
		cmp.w	#BUTTON_WINDOW_OFFSET,mouse_y
		ble.s	no_asr_needed
asr_needed	asl.w	#1,d7
no_asr_needed
	
	cmp.w	d7,d0
	bgt.s	not_a_hit		
	cmp.w	d7,d2
	blt.s	not_a_hit
	cmp.w	mouse_y,d1
	bgt.s	not_a_hit
	cmp.w	mouse_y,d3
	blt.s	not_a_hit
	move.l	a1,clicked_button
	move.w	#1,mouse_button_ind
	cmp.b	#1,button_clicked(a1)
	beq.s	button_already_down
	move.b	#1,button_clicked(a1)
	bra.s	put_button_in_list
button_already_down	
	move.b	#0,button_clicked(a1)
put_button_in_list	
	move.l	button_draw_ptr,a2
	move.l	button_delete_ptr,a3
	move.l	a1,(a2)+
	move.l	a1,(a3)+
	move.l	#$ffffffff,(a2)
	move.l	#$ffffffff,(a3)
	move.l	a2,button_draw_ptr
	move.l	a3,button_delete_ptr
	bra.s	quit_check_buttons
not_a_hit				
	add.l	#4,a0
	bra	check_buttons_loop
quit_check_buttons			
	rts	
	
*delete buttons should always be run before draw buttons	
	
**************************************
***** DRAW BUTTONS               *****
**************************************	

*takes in the draw button list and draws these, clearing
*the list as it goes. It is done like this (and for delete)
*because then it will be synced up proper;y

draw_buttons
	ifnd	hard_only
	bsr	own_the_blitter
	endc

	move.l	#button_draw_list,a0
draw_buttons_loop	
	cmp.l	#$ffffffff,(a0)
	beq	quit_draw_buttons		
	*****DRAW BLITS****

	move.l	#button_window_struct,a4 ;default structure	
	move.l	screen_mem(a4),a2	 ;default place to draw
	move.l	(a0),a1

	cmp.w	#WINDOW,frame_type(a1)	;are we drawing in window?
	bne.s	not_window_button
	move.l	window_list_ptr,a3
	move.l	-(a3),a4
	move.l	screen_mem(a4),a2	;replace place to draw
	move.l	#main_screen_struct,a4
not_window_button
	
	moveq	#0,d0
	moveq	#0,d1
	move.w	button_x(a1),d0
	move.w	button_y(a1),d1
	move.w	screen_x_size(a4),d4
	asr.w	#3,d4
	mulu	d4,d1		;y pos
	add.l	d1,a2
	move.w	d0,d1
	andi.w	#$000f,d1
	andi.w	#$fff0,d0
	asr.w	#3,d0
	move.l	a2,a5			;save for later
	add.l	d0,a2			;x pos
	ror.w	#4,d1			;shift
	or.w	#$0dfc,d1		;or blit
	btst.b	#0,button_type(a1)	;standard button test
	beq.s	normal_button

	*******get details about custom button

	move.l	button_custom(a1),a5
	cmp.b	#0,button_clicked(a1)
	beq.s	unclicked_custom_butt
	tst.l	custom_button_click_graphics(a5)
	beq	do_next_button	;null graphics button
	move.l	custom_button_click_graphics(a5),a3
	bra.s	calc_custom_blit_details
unclicked_custom_butt
	tst.l	custom_button_graphics(a5)
	beq	do_next_button	;null graphics button
	move.l	custom_button_graphics(a5),a3
calc_custom_blit_details	
	move.w	custom_planes(a5),d4
	subq.w	#1,d4

	move.w	custom_button_height(a5),d3	;calc custom blit size
	asl.w	#6,d3
	move.w	custom_button_width(a5),d0
	add.w	#16,d0
	asr.w	#4,d0
	add.w	d0,d3

	moveq	#0,d6

	move.w	screen_x_size(a4),d0	;calculate custom modulus
	asr.w	#3,d0
	move.w	custom_button_width(a5),d7
	asr.w	#3,d7
	move.w	d7,d6
	addq.w	#2,d7
	sub.w	d7,d0

	mulu.w	custom_button_height(a5),d6

	bra.s	blit_on_button
	

normal_button	
	cmp.b	#0,button_clicked(a1)
	beq.s	unclicked_butt
	move.l	#button_clicked_plane1,a3
	bra.s	draw_the_butt
unclicked_butt	
	move.l	#button_plane1,a3
draw_the_butt	
	move.w	#3-1,d4		;number of planes for normal_button

	move.w	#BUTTON_HEIGHT,d3	;calc blit size
	asl.w	#6,d3
	move.w	#BUTTON_WIDTH+16,d0
	asr.w	#4,d0
	add.w	d0,d3

	move.w	screen_x_size(a4),d0	;calculate modulus
	asr.w	#3,d0
	sub.w	#(BUTTON_WIDTH+16)/8,d0

	move.l	#BUTTON_WIDTH/8*BUTTON_HEIGHT,d6

blit_on_button
	btst	#14,DMACONR(a6)
	bne.s	blit_on_button
	move.l	a3,bltapt(a6)
	move.l	a2,bltdpt(a6)
	move.l	a2,bltbpt(a6)
	move.w	d0,bltdmod(a6)
	move.w	d0,bltbmod(a6)
	move.w	#-2,bltamod(a6)
	move.w	d1,bltcon0(a6)
	clr.w	bltcon1(a6)
	move.l	#$ffff0000,bltafwm(a6)
	move.w	d3,bltsize(a6)

	
	add.l	d6,a3
	moveq	#0,d7
	move.w	screen_x_size(a4),d7
	asr.w	#3,d7
	mulu	screen_y_size(a4),d7
	add.l	d7,a2
	dbra	d4,blit_on_button

	btst.b	#0,button_type(a1)	;custom button test
	bne	do_next_button	

***a5 contains y position on screen

	moveq	#0,d7
	move.w	screen_x_size(a4),d7
	asr.w	#3,d7
	mulu	#OFFSET,d7
	add.l	d7,a5
	move.l   a1,a3
	add.l    #button_text,a3
	move.l	a3,a2	;**used to be a4 but i want to keep a4
	moveq	#0,d7
count_letters	
	cmp.b	#0,(a2)+
	beq.s	counted_letters
	addq.w	#1,d7
	bra.s	count_letters
counted_letters	
	mulu	#FONT_PIX_WIDTH,d7
	move.w	#BUTTON_WIDTH-(EDGE*2),d6
	sub.w	d7,d6
	asr.w	#1,d6
	moveq	#0,d0
	move.w	button_x(a1),d7
	add.w	#EDGE,d7		;start in a bit
	add.w	d6,d7		;to centre text
draw_in_text
	move.w	d7,d0
	move.l	a5,a2
	moveq	#0,d1	
	move.w	d0,d1
	andi.w	#$000f,d0
	andi.w	#$fff0,d1
	ror.w	#4,d0
	or.w	#$0d0c,d0	;not and b
	asr.w	#3,d1
	add.l	d1,a2
	moveq	#0,d4
	move.b	(a3)+,d4
	beq.s	do_next_button
	movem.l	a5,-(sp)
	move.l	#button_font,a5
	sub.w	#32,d4
	mulu	#FONT_HEIGHT*4,d4	;get letter in font
	add.l	d4,a5
	
	
blit_on_text
	btst	#14,DMACONR(a6)
	bne.s	blit_on_text
	move.l	a5,bltapt(a6)
	move.l	a2,bltdpt(a6)
	move.l	a2,bltbpt(a6)
	move.w	screen_x_size(a4),d4
	asr.w	#3,d4
	subq.w	#4,d4
	move.w	d4,bltdmod(a6)
	move.w	d4,bltbmod(a6)
	clr.w	bltamod(a6)
	move.w	d0,bltcon0(a6)
	clr.w	bltcon1(a6)
	move.l	#$ffffffff,bltafwm(a6)
	move.w	#11<<6+2,bltsize(a6)
	
	movem.l	(sp)+,a5

	add.w	#FONT_PIX_WIDTH,d7
	bra.s	draw_in_text 
	
do_next_button	
	addq.l	#4,a0
	bra	draw_buttons_loop
quit_draw_buttons			
	move.l	#$ffffffff,button_draw_list
	move.l	#button_draw_list,button_draw_ptr
	
	ifnd	hard_only
	bsr	disown_the_blitter
	endc

	rts
	
	
**************************************
***** DELETE BUTTONS             *****
**************************************	
delete_buttons
	ifnd	hard_only
	bsr	own_the_blitter
	endc

	move.l	#button_delete_list,a0
delete_buttons_loop	
	cmp.l	#$ffffffff,(a0)
	beq	quit_delete_buttons		
	*****CLEAR BLITS****
	
	move.l	#button_window_struct,a4
	move.l	screen_mem(a4),a2
	move.l	(a0),a1
	cmp.w	#WINDOW,frame_type(a1)	;are we checking in window?
	bne.s	delete_not_window_button
	move.l	window_list_ptr,a3
	move.l	-(a3),a4
	move.l	window_start(a4),a2	;replace default drawing position
	move.l	#main_screen_struct,a4
delete_not_window_button
	moveq	#0,d0
	moveq	#0,d1
	move.w	button_x(a1),d0
	move.w	button_y(a1),d1
	move.w	screen_x_size(a4),d3
	asr.w	#3,d3
	mulu	d3,d1		;y pos
	add.l	d1,a2
	move.w	d0,d1
	andi.w	#$000f,d1
	andi.w	#$fff0,d0
	asr.w	#3,d0
	add.l	d0,a2			;x pos
	ror.w	#4,d1			;shift
	or.w	#$0d0c,d1		;not a and b
	btst.b	#0,button_type(a1)	;standard button test
	beq.s	normal_delete_button
	
	*******get details about custom button
	
	move.l	button_custom(a1),a5	;get our pointer
	
	cmp.b	#0,button_clicked(a1)
	beq	delete_unclicked_custom_butt
	tst.l	custom_button_graphics(a5)
	beq	delete_next_button	;null graphics button
	move.l	custom_button_graphics(a5),a3
	bra	delete_calc_custom_blit_details
delete_unclicked_custom_butt
	tst.l	custom_button_click_graphics(a5)
	beq	delete_next_button	;null graphics button
	move.l	custom_button_click_graphics(a5),a3
delete_calc_custom_blit_details	
	move.w	custom_planes(a5),d4
	subq.w	#1,d4
	move.w	custom_button_height(a5),d3	;calc custom blit size
	asl.w	#6,d3
	move.w	custom_button_width(a5),d0
	add.w	#16,d0
	asr.w	#4,d0
	add.w	d0,d3

	moveq	#0,d6

	move.w	screen_x_size(a4),d0	;calculate custom modulus
	asr.w	#3,d0
	move.w	custom_button_width(a5),d7
	asr.w	#3,d7
	move.w	d7,d6
	addq.w	#2,d7
	sub.w	d7,d0

	mulu.w	custom_button_height(a5),d6

	bra.s	delete_on_button

normal_delete_button	
	cmp.b	#0,button_clicked(a1)
	beq.s	delete_clicked_butt
	move.l	#button_plane1,a3
	bra.s	delete_the_butt
delete_clicked_butt	
	move.l	#button_clicked_plane1,a3
delete_the_butt	
	moveq	#3-1,d4		;number of planes for normal_button

	move.w	#BUTTON_HEIGHT,d3
	asl.w	#6,d3
	move.w	#BUTTON_WIDTH+16,d0
	asr.w	#4,d0
	add.w	d0,d3

	move.w	screen_x_size(a4),d0
	asr.w	#3,d0
	sub.w	#(BUTTON_WIDTH+16)/8,d0

	move.l	#(BUTTON_WIDTH/8)*BUTTON_HEIGHT,d6


delete_on_button
	btst	#14,DMACONR(a6)
	bne.s	delete_on_button
	move.l	a3,bltapt(a6)
	move.l	a2,bltdpt(a6)
	move.l	a2,bltbpt(a6)
	move.w	d0,bltdmod(a6)
	move.w	d0,bltbmod(a6)
	move.w	#-2,bltamod(a6)
	move.w	d1,bltcon0(a6)
	clr.w	bltcon1(a6)
	move.l	#$ffff0000,bltafwm(a6)

	move.w	d3,bltsize(a6)
	add.l	d6,a3

	moveq	#0,d7
	move.w	screen_x_size(a4),d7
	asr.w	#3,d7
	mulu	screen_y_size(a4),d7
	add.l	d7,a2
	dbra	d4,delete_on_button
delete_next_button	
	addq.l	#4,a0
	bra	delete_buttons_loop
quit_delete_buttons			
	move.l	#$ffffffff,button_delete_list
	move.l	#button_delete_list,button_delete_ptr
	
	ifnd	hard_only
	bsr	disown_the_blitter
	endc

	rts	
	
**************************************
***** DISPLAY BUTTON             *****
**************************************
display_button

*send button pointer in a0
	movem.l	a0-a3/d0/d7,-(sp)
	cmp.w	#99,button_counter
	beq.s	no_more_buttons_available
	move.l	button_head_ptr,a1
	move.l	button_draw_ptr,a2
	move.b	button_start(a0),d7
	move.b	d7,button_clicked(a0)	;reset
	move.l	window_list_ptr,a3
	move.l	-(a3),button_window(a0)
	move.l	a0,(a1)+
	move.l	a0,(a2)+
	move.l	#$ffffffff,(a2)
	move.l	#$ffffffff,(a1)
	move.l	a2,button_draw_ptr
	move.l	a1,button_head_ptr
	add.w	#1,button_counter
	moveq	#0,d0
	bra.s	quit_display_button
no_more_buttons_available	
	moveq	#-1,d0
quit_display_button	
	movem.l	(sp)+,a0-a3/d0/d7
	rts


**************************************
***** REMOVE BUTTON              *****
**************************************
remove_button
*send button in a0
	movem.l	a0-a4/d0,-(sp)
	moveq	#-1,d0
	move.l	#button_list,a1
	move.l	a1,a2
check_for_button
	cmp.l	#$ffffffff,(a1)
	beq.s	quit_remove_button
	cmp.l	(a1),a0
	beq.s	found_button
	move.l	(a1)+,(a2)+
	bra.s	check_for_button
found_button
	move.l	button_delete_ptr,a4
	cmp.b	#1,button_clicked(a0)
	beq.s	set_to_zero
	move.b	#1,button_clicked(a0)
	bra.s	move_into_delete
set_to_zero
	move.b	#0,button_clicked(a0)	
move_into_delete	
	move.l	a0,(a4)+
	move.l	#$ffffffff,(a4)
	move.l	a4,button_delete_ptr
	moveq	#0,d0		;found ok
	sub.w	#1,button_counter
	addq.l	#4,a1
	bra.s	check_for_button		
quit_remove_button
	move.l	#-1,(a2)
        move.l  a2,button_head_ptr
	movem.l	(sp)+,a0-a4/d0
	rts


**************************************
***** DISPLAY BUTTON LIST        *****
**************************************
display_button_list
*list in a0
	movem.l	d0-d7/a1-a6,-(sp)
	move.l	a0,a1
insert_loop	
	move.l	(a1)+,a0
	cmp.l	#$ffffffff,a0
	beq.s	done_all_list
	bsr	display_button
	bra.s	insert_loop
done_all_list
	movem.l	(sp)+,d0-d7/a1-a6
	rts

**************************************
***** REMOVE BUTTON LIST         *****
**************************************
remove_button_list
*list in a0
	movem.l	d0-d7/a1-a6,-(sp)
	move.l	a0,a1
insert_loop2	
	move.l	(a1)+,a0
	cmp.l	#$ffffffff,a0
	beq.s	done_all_remove_list
	bsr	remove_button
	bra.s	insert_loop2
done_all_remove_list
	movem.l	(sp)+,d0-d7/a1-a6
	rts

Force_Buttons
	bsr	delete_buttons
	bsr	draw_buttons
	rts
	
*button details

FIRST_ROW		equ 0
SECOND_ROW		equ 16
THIRD_ROW		equ 32
FOURTH_ROW		equ 48

BUTTON_1		equ 0
BUTTON_2		equ 112
BUTTON_3		equ 224
BUTTON_4		equ 336
BUTTON_5		equ 448

MAIN_BUTTON_SCREEN	equ 0
WINDOW			equ 1
MAIN_SCREEN		equ 2

BUTTON_HOLD_WAIT	EQU 10

**************B U T T O N   S T R U C T U R E *****************

	rsreset
	
button_x		rs.w	1
button_y		rs.w	1
frame_type	rs.w	1	;specifies which buttons to search through
button_type	rs.b	1	;0- standard, 1-custon
button_start	rs.b	1	;0 or 1, 1 = down already
button_data	rs.b	1	;associated button data
button_clicked	rs.b	1
button_custom	rs.l	1	;if custom = pointer to custom struct
button_window	rs.l	1	;if custom not required
button_proc	rs.l	1
button_text	rs.b	1	;not if custom
	even
	
**************C U S T O M  B U T T O N   S T R U C T U R E *****************

	rsreset

custom_button_width	rs.w	1
custom_button_height    rs.w	1
custom_button_x_size	rs.w	1
custom_button_y_size	rs.w	1
custom_planes		rs.w	1
custom_button_graphics rs.l	1
custom_button_click_graphics	rs.l 1


current_frame
	dc.w	0

mouse_button_ind
	dc.w	0
	
clicked_button
	dc.l	0
	
button_list
	ds.l	100	
button_draw_list
	ds.l	100
button_delete_list
	ds.l	100	
			
button_head_ptr
	dc.l	button_list
button_draw_ptr
	dc.l	button_draw_list
button_delete_ptr
	dc.l	button_delete_list

button_wait_counter
	dc.w	BUTTON_HOLD_WAIT
			
button_counter
	dc.w	0		
	


	
