; new version of selection button system, using properly flexible structure
; commands are mixed sizes, so go with care
; register allocations 
; d0/a0 scratch
; a3 is current data
; a2 is object list address, and hence free most of the time
; a1 is subroutine address
; d2 is highlight offset qty - for both button types, in high / low words
; d4 is button roll offset - this exists for both primary and secondary but is only used for secondary (low word)
; a4 is current loop address
; d3 is failure offset from loop address
; a5 is current forward branch address - so that any test can use forward branching, and so guarantee re-processing of video etc

.include 'memdefs.inc'
.include 'menumacs.inc'
.include 'joypad.inc'
.include 'jaguar.inc'
.include 'grsize.inc'

.text

; enters with a3 pointing to menu data

Menu::	moveq.l	#1,d0			; initialise bits
	move.w	d0,program_area.w
	move.w	d0,delay.w
	move.b	#255,speedo.w

;	bsr	sync			; clear screen
	bsr	VidOff

	move.l	#$77307730,d2		; set background to dark red
	movea.w	#background,a1		; addr of background storage
	move.l	d2,(a1)+
	move.l	d2,(a1)

	clr.l	viewmove.w		; make sure screen flip works
	bsr	readpad			; to ensure first key presses are not registered as edges !

loop:	move.b	(a3)+,d0		; read command
	beq.b	exit			; zero is quit

.nex:	ext.w	d0
	asl.w	#1,d0
	lea	menu_jump_table-2-2-*(PC),a0	
	move.w	(a0,d0.w),d0
basic:	jsr	-2(PC,d0.w)
	bra	loop

exit:	bsr	update_configuration	; wrecks d4 - hopefully not needed anyway
	tst.b	eeprom_change.w
	beq.b	Null
	bsr	sendeep
Null:	rts

menu_jump_table:
	entry	do_rle_decode		; 1
	entry	do_3d_reloc		; 2
	entry	do_init_buttons		; 3
	entry	do_light_button		; 4
	entry	do_key_test		; 5
	entry	do_dull_button		; 6
	entry	do_next_option		; 7
	entry	do_last_option		; 8
	entry	do_new_3d_obj		; 9
	entry	do_adjust_obj		; 10
	entry	do_set_variable		; 11
	entry	do_add_variable		; 12
	entry	do_test_minimum		; 13
	entry	do_test_maximum		; 14
	entry	do_another_menu		; 15
	entry	do_this_again		; 16
	entry	do_button		; 17
	entry	do_screen_setup		; 18
	entry	do_variable_object 	; 19
	entry	do_variable_button 	; 20
	entry	do_light_n_buts		; 21
	entry	do_dull_n_buts		; 22
	entry	do_rmw_switch		; 23
	entry	do_change_z		; 24
	entry	do_rlp_decode		; 25
	entry	do_rmw_make		; 26
	entry	do_rlp_var_decode 	; 27
	entry	do_numeric_button 	; 28
	entry	do_key_test2		; 29
	entry	do_stopit		; 30
	entry	do_ypos_button		; 31
	entry	do_abc_buttons		; 32
	entry	do_constant_button	; 33
	entry	do_test_number		; 34
	entry	do_test_exact		; 35
	entry	do_sequence_decode	; 36
	entry	do_set_variable_button	; 37
	entry	do_switch_mode		; 38
	entry	do_numeric_single	; 39
	entry	do_set_var_but_var	; 40
	entry	do_var_copy		; 41

getfont::
movem.l	a0-a1,-(sp)
	movea.l	#cffont,a0			; point at font
	movea.l	#cockpit+$30000+complete_set,a1	; point at end of button data
	move.w	#menu_font>>2-1,d0		; get number of longs in font
.lp:	move.l	(a0)+,(a1)+
	dbra	d0,.lp
	movem.l	(sp)+,a0-a1
	rts

ntsc_fix:
	movem.l	d0/a0-a1,-(sp)

	tst.b	ntsc_type.w
	beq.b	.pal

	movea.l	#cockpit+$30000+all_bars+menu_options+menu_colours+menu_small+menu_medium+$3300,a0
	movea.l	#cockpit+$30000+all_bars+menu_options+menu_colours+menu_small+menu_medium+$2200,a1

	move.w	#$1100>>1-1,d0
.lp:	move.l	(a0)+,(a1)+
	dbra	d0,.lp

.pal:	movem.l	(sp)+,d0/a0-a1
	rts

butgrey:movem.l	d0-d1/a0-a1,-(sp)
	movea.l	#cockpit+$30000+all_bars,a0
	movea.l	#cockpit+all_bars,a1
	move.l	#(all_buttons+config_all+menu_font)>>1-1,d0
	swap	d0
.lp0:	swap	d0
.lp1:	move.w	(a0)+,d1
	beq.b	.ok
	lsr.b	#1,d1
	sub.b	#$20,d1
	ext.w	d1
.ok:	move.w	d1,(a1)+	
	dbra	d0,.lp1
	swap	d0
	dbra	d0,.lp0
	movem.l	(sp)+,d0-d1/a0-a1
	rts

butcol:	movem.l	d0-d3/a0-a1,-(sp)
	movea.l	#cockpit+$30000+all_bars+menu_options,a0
	movea.l	#cockpit+all_bars+menu_options,a1
	move.w	#$8880,d0	; conversion colour
	moveq	#$60-1,d2	; number lines - 6 buttons $10 lines each

	lea	$28(a0),a0	; skip blanks
	lea	$28(a1),a1

.lp0:	moveq	#$16-1,d3		; number to transfer

.lp1:	move.w	(a0)+,d1
	beq.b	.ok
	eor.w	d0,d1
.ok:	move.w	d1,(a1)+
	dbra	d3,.lp1
	lea	$34(a0),a0
	lea	$34(a1),a1
	dbra	d2,.lp0

	movem.l	(sp)+,d0-d3/a0-a1
	rts

do_rmw_make:
	bsr	getfont
	bsr	ntsc_fix
	bsr	butgrey
	bsr	butcol
	addq.l	#1,a3
	rts

do_rlp_decode:
	movem.l	a0-a2,-(sp)
	moveq.l	#0,d0
	move.b	(a3)+,d0	; rle screen
rlpj:	asl.w	#2,d0
	movea.l	rlepoint.w,a2
	adda.w	d0,a2
	movea.l	(a2),a1		; source address
	move.l	(a3)+,a0	; decode address
	move.l	(a3)+,a2	; palette address
	bsr	rlpin
	movem.l	(sp)+,a0-a2
	rts

do_rlp_var_decode:
	movem.l	a0-a2,-(sp)
	moveq.l	#0,d0
	move.b	(a3)+,d0	; rle screen
	move.w	(a3)+,a0	; variable address
	add.b	(a0),d0		; apply offset value
	bra	rlpj

do_rle_decode:
	moveq.l	#0,d0
	move.b	(a3)+,d0	; rle screen
	move.l	(a3)+,a0	; decode address
	bsr	rldin
	rts

do_3d_reloc:
	moveq.l	#0,d0
	move.b	(a3)+,d0
	bsr	Mwrite
	rts

do_key_test2:
	move.l	joy_rep.w,d0
	bra.b	f1

do_key_test:
	move.l	joy_edge.w,d0
f1:	move.b	(a3)+,d3	; failure offset
	move.l	(a3)+,d1	; mask
	ext.w	d3
	lea	-6(a3,d3.w),a5	; apply offset to create new jump ahead address
	and.l	d0,d1
	bne.b	.exit		; if pressed then do nothing, just allow to roll on
	movea.l	a5,a3		; force jump if test failed
.exit:	rts

do_test_number:
	move.l	joy_edge.w,d0
	move.b	(a3)+,d3
	move.w	(a3)+,d1
	ext.w	d3
	lea	-4(a3,d3.w),a5
	btst.l	d1,d0
	beq.b	.exit
	movea.l	a5,a3
.exit:	rts
	
point_to_button:
	move.b	(a3)+,d0
	ext.w	d0
	movea.w	#reset_list,a0
	asl.w	#4,d0
	rts

point_to_button_2:
	move.w	(a3)+,d0
	ext.w	d0
	movea.w	#reset_list,a0
	asl.w	#4,d0
	rts

do_light_button:
	bsr	point_to_button
	swap	d2
	add.w	d2,(a0,d0.w)
	swap	d2
	rts			; must put d2 = highlight amount

do_dull_button:
	bsr	point_to_button
	swap	d2
	sub.w	d2,(a0,d0.w)
	swap	d2
	rts	

do_light_n_buts:
	bsr	point_to_button
	bmi.b	.ex
	swap	d2
	add.w	d2,(a0,d0.w)
	swap	d2
	bra	do_light_n_buts
.ex:	move.l	a3,d0		; realign address to even address
	addq.l	#1,d0
	bclr.l	#0,d0
	move.l	d0,a3
	rts

do_dull_n_buts:
	bsr	point_to_button
	bmi.b	.ex
	swap	d2
	sub.w	d2,(a0,d0.w)
	swap	d2
	bra	do_dull_n_buts
.ex:	move.l	a3,d0
	addq.l	#1,d0
	bclr.l	#0,d0
	move.l	d0,a3
	rts	

do_next_option:
	bsr	point_to_button
	add.w	d4,(a0,d0.w)
	rts			; must put d4 = button size

do_last_option:
	bsr	point_to_button
	sub.w	d4,(a0,d0.w)
	rts

do_set_variable_button:
	move.l	a1,-(sp)
	bsr	point_to_button
	move.w	(a3)+,a1	; read variable address
	move.w	(a3)+,d1	; read target amount
	sub.b	(a1),d1		; calculate change required
	add.b	d1,(a1)		; apply change to variable
	ext.w	d1		; make it multipliable
	muls	d4,d1		; calculate button address change
	add.w	d1,(a0,d0.w)	; apply
	move.l	(sp)+,a1
	rts

do_set_var_but_var:
	movem.l	a1/a2,-(sp)
	bsr	point_to_button
	move.w	(a3)+,a1	; read variable address
	move.w	(a3)+,a2	; read variable to use as target
	move.b	(a2),d1		; read target amount
	sub.b	(a1),d1		; calculate change required
	add.b	d1,(a1)		; apply change to variable
	ext.w	d1		; make it multipliable
	muls	d4,d1		; calculate button address change
	add.w	d1,(a0,d0.w)	; apply
	movem.l	(sp)+,a1/a2
	rts

do_var_copy:
	movem.l	a1/a2,-(sp)
	addq.l	#1,a3		; skip 0 byte
	move.w	(a3)+,a1
	move.w	(a3)+,a2
	move.b	(a1),(a2)
	movem.l	(sp)+,a1/a2
	rts

do_ypos_button:
	bsr	point_to_button
	move.w	6(a0,d0.w),d1	; read current ypos and surrounding stuff
	and.w	#$C003,d1	; remove ypos from it
	ror.w	#3,d1		; push down so new value can be stuffed in
	or.w	(a3)+,d1	; read new ypos into place
	rol.w	#3,d1		; relocate
	move.w	d1,6(a0,d0.w)	; write out
	rts

do_button:			; this performs : highlight 1 or 2 buttons and change the re-run address
	bsr	point_to_button
	swap	d2
	add.w	d2,(a0,d0.w)
	swap	d2
	bsr	point_to_button_2
	beq.b	.ex
	add.w	d2,(a0,d0.w)
.ex:	move.l	(a3),a3		; get new buttons address
	move.l	a3,a4		; retain for 'do again's
	clr.l	joy_edge.w
	rts

do_rmw_switch::			; multiple switching routine
	bsr	point_to_button
	bmi.b	.done
	lea	8(a0,d0),a0
	move.l	(a0),d0		; get current data (including rmw flag)
	bchg.l	#14,d0		; switch rmw flag
	move.l	d0,(a0)
	bra	do_rmw_switch
.done:	move.l	a3,d0
	addq.l	#1,d0
	bclr.l	#0,d0
	move.l	d0,a3
	rts

do_abc_buttons::				; special system, gives 3 button codes and one variable
	bsr	point_to_button
	movea.w	(a3)+,a2			; gets variable pointer, which must be held for triple decoding
	moveq	#0,d1
	move.b	(a2),d1
	asr.b	#1,d1				; first letter is based on upper two bits
	beq.b	.nul				; if 0 then go straight through
	subq	#1,d1				; cut down to see if it was 1
	beq.b	.ad1				; if so, then now 0, so add $300 will make into $300
	move.w	#$700,d1			; otherwise make $300 then add $300 to give overall
.ad1:	add.w	#$700,d1			; result of 0/$300/$600 for each case
.nul:	add.l	#cockpit+$30000+all_bars+all_buttons+config_options,d1		; address of first letter button
	bsr	set_address

	bsr	point_to_button			; start on next button / letter
	moveq	#0,d1
	move.b	(a2),d1				; re-read number
	beq.b	.x1		; if 0
	subq	#1,d1
	beq.b	.x2		; if 1
	subq	#1,d1
	beq.b	.x0		; if 2
	subq	#1,d1
	beq.b	.x2		; if 3
	subq	#1,d1
	beq.b	.x0		; if 4
	subq	#1,d1
	beq.b	.x1		; if 5
.x2:	move.w	#$700,d1
.x1:	add.w	#$700,d1
.x0:	add.l	#cockpit+$30000+all_bars+all_buttons+config_options,d1
	bsr	set_address

db3:	bsr	point_to_button			; start on next button / letter
	moveq	#0,d1
	move.b	(a2),d1				; re-read number
	beq.b	.x2		; if 0
	subq	#1,d1
	beq.b	.x1		; if 1
	subq	#1,d1
	beq.b	.x2		; if 2
	subq	#1,d1
	beq.b	.x0		; if 3
	subq	#1,d1
	beq.b	.x1		; if 4
	subq	#1,d1
	beq.b	.x0		; if 5
.x2:	move.w	#$700,d1
.x1:	add.w	#$700,d1
.x0:	add.l	#cockpit+$30000+all_bars+all_buttons+config_options,d1
	bsr	set_address
	rts

point_to_object:
	move.b	(a3)+,d0
	ext.w	d0
	movea.l	#Genstr+$44,a0	; address of first 3d objects pointer
	asl.w	#5,d0		; 32 bytes per 3d object
	rts

do_new_3d_obj:
	bsr	point_to_object
	move.l	(a3)+,(a0,d0.w)
	rts

do_change_z:
	bsr	point_to_object
	move.l	(a3)+,-8(a0,d0.w)
	rts

do_adjust_obj:
	bsr	point_to_object
	adda.w	d0,a0
	move.w	(a3)+,d0
	ext.l	d0
	add.l	d0,(a0)
	rts

do_set_variable:
	move.b	(a3)+,d0
	movea.w	(a3)+,a0
	move.b	d0,(a0)
	rts

do_add_variable:
	move.b	(a3)+,d0
	movea.w	(a3)+,a0
	add.b	d0,(a0)
	rts

do_test_minimum:
	move.b	(a3)+,d0
	movea.w	(a3)+,a0
	cmp.b	(a0),d0
	blt.b	.exit
	movea.l	a5,a3		; test failure now forces jump to pre-defined forward location
.exit:	rts			; and hence obviates the need for keypad cheats

do_test_maximum:
	move.b	(a3)+,d0
	movea.w	(a3)+,a0
	cmp.b	(a0),d0
	bgt.b	.exit
	movea.l	a5,a3
.exit:	rts	

do_test_exact:
	move.b	(a3)+,d0
	movea.w	(a3)+,a0
	cmp.b	(a0),d0
	beq.b	.exit
	movea.l	a5,a3
.exit:	rts

do_another_menu:
	move.l	#Menu,(sp)	; change return address to restart routine - ultra dodgy tactics !
	move.l	1(a3),a3	; read new address - skipping blank byte
	rts

do_this_again:
	movea.l	a4,a3
	jsr	(a1)		; re-display - jsr not made relocatable because not in speedy part of game
	bsr	readpad
	bsr	ResetKey	; test for reset - must always allow this in all parts of the game
	bsr	FX		; do special effects - in particular, allow zero to stop music
	rts

do_variable_object:
	move.b	(a3)+,d0	; object number to effect
	ext.w	d0
	asl.w	#5,d0		; 32 bytes per 3d object
	ext.l	d0
	add.l	#Genstr+$44,d0	; address of first 3d objects pointer
	move.w	(a3)+,a0	; address of variable
	move.b	(a0),d1		; variable value
	ext.w	d1
	ext.l	d1		; make long
	movea.l	d0,a0		; prepare output address
	asl.l	#2,d1		; 4 *
	move.l	d1,d0		; and
	asl.l	#2,d0		; 4*4* = 16*
	add.l	d1,d0		; gives 20*
	add.l	d0,(a0)		; which is the standard limz gap !
	rts

do_variable_button:
	move.b	(a3)+,d0	; button number to effect
	ext.w	d0
	asl.w	#4,d0
	add.w	#reset_list,d0	; get button address
	move.w	(a3)+,a0	; address of variable
	move.b	(a0),d1		; variable value
	ext.w	d1
	muls	d4,d1		; times button size
	movea.w	d0,a0		; prepare output address
	add.w	d1,(a0)		; and apply
	rts

do_constant_button:		; apply a word length signed shift to allow (eg) looping off option 6 round to 0
	bsr	point_to_button
	adda.w	d0,a0
	move.w	(a3)+,d0
	muls	d4,d0
	add.w	d0,(a0)
	rts

do_screen_setup:
	addq.l	#1,a3		; skip zero
	move.l	(a3)+,a2
	move.l	(a3)+,a1
	jsr	(a1)		; not made relocatable
	movea.l	a2,a0
	bsr	ObjSetup
	bsr	sync		; to ensure list is in place
	rts

do_init_buttons:
	move.b	(a3)+,d4	; read main button size
	ext.w	d4
	move.w	(a3)+,d2	; read main button highlight value
	swap	d4
	move.w	(a3)+,d4	; read option button size
	swap	d2
	move.w	(a3)+,d2	; read option button highlight value
	rts

set_address:					; generic address setting for objects sets (a0,d0) to d1
	movem.l	d1/d4,-(sp)
	asl.l	#8,d1
	move.l	#$3ff,d4			; mask for 'other' data
	and.w	2(a0,d0),d4
	or.w	d4,d1
	move.l	d1,(a0,d0)
	movem.l	(sp)+,d1/d4
	rts

display_digit:				; routine to set one digit, with value in d1, button in d0,a0 (as per point_to_buton)
	move.l	d1,-(sp)		; returns d1 unchanged
	mulu.w	#3*8*16,d1
	add.l	#cockpit+$30000+complete_set,d1	; points at the address for zero
	bsr	set_address
	move.l	(sp)+,d1
	rts

do_numeric_button:		; for providing a two digit display on object numbers n.b and n+1 based on variable x.w
	movem.l	a1/d2,-(sp)
	bsr	point_to_button		; gives a0,d0 such that (a0,d0) is the object address
	movea.w	(a3)+,a1		; get pointer
	moveq	#0,d1			; prepares counter for tens
	move.b	(a1),d2			; get variable value
.lp:	addq.w	#1,d1	
	sub.b	#10,d2
	bpl	.lp
	subq.w	#1,d1
	add.b	#10,d2
	bsr	display_digit

	add.w	#$10,d0			; to point at next button
	moveq	#0,d1
	move.b	d2,d1
	bsr	display_digit

	movem.l	(sp)+,a1/d2
	rts

do_numeric_single:			; one digit display
	move.l	a1,-(sp)
	bsr	point_to_button
	movea.w	(a3)+,a1
	moveq	#0,d1
	move.b	(a1),d1
	bsr	display_digit
	move.l	(sp)+,a1	
	rts

do_sequence_decode:
	move.l	a1,-(sp)
	move.b	(a3)+,d3		; read offset first
	ext.w	d3
	lea	-2(a3,d3.w),a5		; prepare jump address
	movea.w	(a3)+,a0		; get variable location
	move.b	(a0),d0			; read variable - which is pointer into string
	ext.w	d0
	movea.l	(a3)+,a1
	move.b	(a1,d0.w),d1		; read key required
	bmi.b	.exit			; only hitting the -1 jackpot at the end is a successful termination
	move.l	joy_edge.w,d0
	btst.l	d1,d0			; see if the right key has been pressed
	bne.b	.ok			; if so then increment counter etc
	tst.l	d0			; test for any other keys
	beq.b	.none			; if none then ok, simply fall out
	clr.b	(a0)			; cancel count if wrong key hit
	bra.b	.none
.ok:	addq.b	#1,(a0)			; move on to next entry
.none:	move.l	a5,a3
	move.l	(sp)+,a1
	rts
.exit:	clr.b	(a0)			; cancel count when succesful, so that can be restarted
	move.l	(sp)+,a1
	rts

do_stopit:
	illegal

do_switch_mode:
	addq.l	#1,a3			; skip zero
	tst.b	vis_mode.w
	beq.b	.on
	move.w	#$6c1,VMODE
	clr.b	vis_mode.w
	rts
.on:	move.w	#$6c7,VMODE
	st.b	vis_mode.w
	rts

;==============================================================================================

; Converted data for current screens

.data

key_up		= $100000
key_down	= $200000
key_left	= $400000
key_right	= $800000
key_option	= $000200

Opt1::	Do_rle	48,cockpit			; decode top section
	Do_rle	49,cockpit+menu_top		; decode side section
	Do_rle	50,cockpit+menu_top+menu_side
	Do_rlpv	57,ntsc_type,cockpit+$30000+all_bars,butpal	; decode buttons which are country dependent
	Do_rlp	59,cockpit+$30000+all_bars+menu_options,butpal	; decode the rest
	Do_make_rmw
Opt1a:	Do_3d	2				; gets the standard one car spinning set-up
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_screen	ObjDef3,Display_routine
	Do_var_but	12,car_colour
	Do_var_but	13,weather
	Do_var_but	14,foil_type
	Do_var_but	15,tyre_type
	Do_init		$b,$300,$c,$300		; set up for large option buttons
	Do_var_but	16,gear_type
	Do_init		$b,$300,$11,$300	; set up for very large buttons
	Do_var_but	18,race_type
	Do_var_but	20,track_no
	Do_numeric	21,qty_laps
	Do_digit	23,num_drones
	Do_dulln	21,22,23
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_rmw		3,12
	Do_but		3,12,b0

b0:	Do_new_3d	0,Ncar
	Do_newz		0,$a00
	Do_var_obj	0,car_colour
	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_key		.k0,key_down
	Do_dulln	3,12
	Do_rmw		3,4,12,13
	Do_3d		1
	Do_set		0,secret
	Do_but		4,13,b1
.k0:	Do_key		.k1,ANY_FIRE
	Do_menu		Opt2

.k1:	Do_key		.k2,key_left
	Do_max		2,race_type			; no change when in tournament mode
	Do_last		12
	Do_add		-1,car_colour
	Do_max		0,car_colour
	Do_add		6,car_colour
	Do_next		12
	Do_var_but	12,car_colour
	Do_max		1,tourn_track			; check whether the current tournament track is the first one
	Do_copy_var	car_colour,tourn_car_col	; and if so allow the tournament car colour to change
				; this is in case some idiot tries to change the colour, by changing the race type then changing it back.
				; since the car colour only gets updated if tournament is on track 0, then we can be sure they ain't messin.
				; also, since the tournament track gets reset whenever tournament is finished, and at boot-up, it won't go wrong.

.k2:	Do_key		.k3,key_right
	Do_max		2,race_type
	Do_next		12
	Do_add		1,car_colour
	Do_min		5,car_colour		; check for overrun
	Do_const_but	12,-6			; if overrun, backup 6 buttons
	Do_add		-6,car_colour		; and backup the value as well
	Do_max		1,tourn_track		; check whether the current tournament track is the first one
	Do_copy_var	car_colour,tourn_car_col

.k3:	Do_key		.k4,key_up		; this allows to go up off top for bottom
	Do_dulln	3,12
	Do_rmw		3,11,12,20
	Do_init		$b,$300,$11,$300	; set up for large option buttons
	Do_3d		0
	Do_but		11,20,b8
.k4:	Do_again


b1:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_key		.k0,key_up
	Do_dulln	4,13
	Do_rmw		3,4,12,13
	Do_3d		2
	Do_but		3,12,b0
.k0:	Do_key		.k1,key_down
	Do_dulln	4,13
	Do_rmw		4,5,13,14
	Do_3d		2
	Do_but		5,14,b2
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2

.k2:	Do_key		.k3,key_left
	Do_max		2,race_type
	Do_last		13
	Do_add		-1,weather
	Do_max		0,weather		; check for overflow
	Do_add		3,weather		; only wrap round normal weather types
	Do_const_but	13,3	

.k3:	Do_key		.k4,key_right
	Do_max		2,race_type
	Do_next		13
	Do_add		1,weather
	Do_min		2,weather		; check that weather is valid
	Do_add		-3,weather
	Do_const_but	13,-3

.k4:	Do_sequence	.k5,secret,seqadd
	Do_set_var_but	13,weather,3
.k5:	Do_again


b2:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_new_3d	0,AeroLow
	Do_newz		0,$a00
	Do_var_obj	0,foil_type
	Do_key		.k0,key_up
	Do_dulln	5,14
	Do_rmw		4,5,13,14
	Do_3d		1
	Do_set		0,secret
	Do_but		4,13,b1
.k0:	Do_key		.k1,key_down
	Do_dulln	5,14
	Do_rmw		5,6,14,15
	Do_but		6,15,b3
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2

.k2:	Do_key		.k3,key_left
	Do_last		14
	Do_add		-1,foil_type
	Do_max		0,foil_type
	Do_add		2,foil_type
	Do_const_but	14,2

.k3:	Do_key		.k4,key_right
	Do_next		14
	Do_add		1,foil_type
	Do_min		1,foil_type
	Do_add		-2,foil_type
	Do_const_but	14,-2
.k4:	Do_again


b3:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_new_3d	0,DryW
	Do_newz		0,$d00
	Do_var_obj	0,tyre_type
	Do_key		.k0,key_up
	Do_dulln	6,15
	Do_rmw		5,6,14,15
	Do_but		5,14,b2
.k0:	Do_key		.k1,key_down
	Do_dulln	6,15
	Do_rmw		6,7,15,16
	Do_init		$b,$300,$c,$300		; set up for large option buttons
	Do_but		7,16,b4
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2

.k2:	Do_key		.k3,key_left
	Do_last		15
	Do_add		-1,tyre_type
	Do_max		0,tyre_type
	Do_add		2,tyre_type
	Do_const_but	15,2

.k3:	Do_key		.k4,key_right
	Do_next		15
	Do_add		1,tyre_type
	Do_min		1,tyre_type
	Do_add		-2,tyre_type
	Do_const_but	15,-2
.k4:	Do_again


b4:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_new_3d	0,Auto
	Do_newz		0,$900
	Do_var_obj	0,gear_type
	Do_key		.k0,key_up
	Do_dulln	7,16
	Do_rmw		6,7,15,16
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_but		6,15,b3
.k0:	Do_key		.k1,key_down
	Do_dulln	7,16
	Do_rmw		7,8,16,17,23
	Do_lite		23
	Do_but		8,17,b5
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_left
	Do_last		16
	Do_add		-1,gear_type
	Do_max		0,gear_type
	Do_add		2,gear_type
	Do_const_but	16,2
.k3:	Do_key		.k4,key_right
	Do_next		16
	Do_add		1,gear_type
	Do_min		1,gear_type
	Do_add		-2,gear_type
	Do_const_but	16,-2
.k4:	Do_again

b5:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_new_3d	0,Dronecar		; this is due to be removed anyway
	Do_digit	23,num_drones
	Do_newz		0,$a00
	Do_key		.k0,key_up
	Do_dulln	8,17,23
	Do_rmw		7,8,16,17,23
	Do_init		$b,$300,$c,$300
	Do_but		7,16,b4
.k0:	Do_key		.k1,key_down
	Do_dulln	8,17,23
	Do_rmw		8,9,17,18,23
	Do_init		$b,$300,$11,$300
	Do_but		9,18,b6
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_left
	Do_test		0,race_type		; only change allowed when on single race mode
	Do_add		-1,num_drones
	Do_max		1,num_drones
	Do_add		5,num_drones
.k3:	Do_key		.k4,key_right
	Do_test		0,race_type
	Do_add		1,num_drones
	Do_min		5,num_drones
	Do_add		-5,num_drones
.k4:	Do_again

b6:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_new_3d	0,Clock
	Do_newz		0,$5000
	Do_key		.k0,key_up
	Do_dulln	9,18
	Do_rmw		8,9,17,18,23
	Do_lite		23
	Do_init		$b,$300,$6,$300
	Do_but		8,17,b5
.k0:	Do_key		.k1,key_down
	Do_dulln	9,18
	Do_rmw		9,10,18,19,21,22
	Do_init		$b,$300,$6,$300
	Do_3d		0
	Do_liten	21,22
	Do_but		10,19,b7
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_left
	Do_last		18
	Do_add		-1,race_type
	Do_max		0,race_type
	Do_add		3,race_type	; this line changes race type to 2, so we start by changing to correct track number etc
	Do_const_but	18,3		; (after we fix the button)
	Do_set_var_but_var	20,track_no,tourn_track
	Do_copy_var		tourn_qty_laps,qty_laps
	Do_numeric		21,qty_laps
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_set_var_but_var	13,weather,tourn_weather
	Do_init		$b,$300,$11,$300	; and reset for normal
	Do_set		5,num_drones
	Do_digit	23,num_drones
	Do_dulln	21,22,23
	Do_min		0,track_no	; check that we are on not the first stage before the next line is used
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_set_var_but_var	12,car_colour,tourn_car_col
	Do_init		$b,$300,$11,$300	; and reset for normal

.k3:	Do_key		.k3a,key_left		; things to check if we just changed the race type
	Do_test		1,race_type		; type 1 = free practice	
	Do_set		0,num_drones
	Do_digit	23,num_drones
	Do_dull		23
.k3a:	Do_key		.k3b,key_left
	Do_test		0,race_type		; type 0 = just changed from free practice to normal
	Do_set		5,num_drones
	Do_digit	23,num_drones
	Do_dull		23

.k3b:	Do_key		.k4,key_right
	Do_next		18
	Do_add		1,race_type
	Do_min		2,race_type		; test that 3 has been reached 
	Do_add		-3,race_type
	Do_const_but	18,-3
.k4:	Do_key		.k5,key_right		; additional check for the case where race type went from 1 to 2
	Do_min		1,race_type		; make sure value is now 2 (that is more than 1)
	Do_set_var_but_var	20,track_no,tourn_track
	Do_copy_var		tourn_qty_laps,qty_laps
	Do_numeric		21,qty_laps
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_set_var_but_var	13,weather,tourn_weather
	Do_init		$b,$300,$11,$300	; and reset for normal
	Do_set		5,num_drones
	Do_digit	23,num_drones
	Do_dulln	21,22,23
	Do_min		0,track_no		; check that we are on not the first stage before the next line is used
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_set_var_but_var	12,car_colour,tourn_car_col	; because then the car colour stays in place for the first stage only
	Do_init		$b,$300,$11,$300	; and reset for normal
.k5:	Do_key		.k6,key_right		; additional checks for free practice
	Do_test		1,race_type
	Do_set		0,num_drones
	Do_digit	23,num_drones
	Do_dull		23
.k6:	Do_again

b7:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_new_3d	0,Laparrow		; wrap around on this one just added
	Do_numeric	21,qty_laps
	Do_key		.k0,key_up
	Do_dulln	10,19,21,22
	Do_rmw		9,10,18,19,21,22
	Do_init		$b,$300,$11,$300
	Do_3d		2
	Do_but		9,18,b6
.k0:	Do_key		.k1,key_down
	Do_dulln	10,19,21,22
	Do_rmw		10,11,19,20,21,22
	Do_init		$b,$300,$11,$300
	Do_but		11,20,b8
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key_rep	.k3,key_left
	Do_max		2,race_type		; no change in tournament
	Do_add		-1,qty_laps
	Do_max		1,qty_laps		; check that gone below 1 so can wrap
	Do_add		99,qty_laps
.k3:	Do_key_rep	.k4,key_right
	Do_max		2,race_type
	Do_add		1,qty_laps
	Do_min		99,qty_laps		; check that overflow has occurred
	Do_add		-99,qty_laps
.k4:	Do_again

b8:	Do_key		.ko,key_option
	Do_menu		Opt3

.ko:	Do_new_3d	0,Base1
	Do_var_obj	0,track_no
	Do_key		.k0,key_up
	Do_dulln	11,20
	Do_rmw		10,11,19,20,21,22
	Do_init		$b,$300,$6,$300
	Do_liten	21,22
	Do_but		10,19,b7
.k0:	Do_key		.k1,key_down
	Do_dulln	11,20
	Do_rmw		3,11,12,20
	Do_init		$b,$300,$6,$300		; set up for small option buttons
	Do_3d		2
	Do_but		3,12,b0
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_left
	Do_max		2,race_type
	Do_last		20
	Do_add		-1,track_no
	Do_max		0,track_no
	Do_const_but	20,10
	Do_add		10,track_no
.k3:	Do_key		.k4,key_right
	Do_max		2,race_type
	Do_next		20
	Do_add		1,track_no
	Do_min		9,track_no
	Do_const_but	20,-10
	Do_add		-10,track_no
.k4:	Do_sequence	.k6,predmode,seq2
	Do_switch_mode
.k6:	Do_again



Opt2::	Do_quit


Opt3::	; note no decodes because now uses data generated by first option screen

	Do_3d	3		; new 3d setup, just for joypad (for easy modification)
	Do_init		$1b,$300,$b,$300
	Do_screen	Objdef5,Display_routine
	Do_var_but	11,map_spin
	Do_var_but	12,tach_set
	Do_rmw		3,4,5,8,9,10
	Do_liten	4,5,9,10
	Do_but		3,8,c0

c0:	Do_abc		8,9,10,key_config
	Do_key		.ko,key_option
	Do_menu		Opt1a
.ko:	Do_key		.k0,key_down
	Do_dulln	3,4,5,8,9,10
	Do_rmw		3,4,5,8,9,10,6,11
	Do_but		6,11,c1
.k0:	Do_key		.k1,key_up
	Do_dulln	3,4,5,8,9,10
	Do_rmw		3,4,5,8,9,10,7,12
	Do_but		7,12,c2
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_right
	Do_add		1,key_config
	Do_min		5,key_config
	Do_add		-6,key_config
.k3:	Do_key		.k4,key_left
	Do_add		-1,key_config
	Do_max		0,key_config
	Do_add		6,key_config
.k4:	Do_again




c1:	Do_key		.ko,key_option
	Do_menu		Opt1a
.ko:	Do_key		.k0,key_down
	Do_dulln	6,11
	Do_rmw		7,12,6,11
	Do_but		7,12,c2
.k0:	Do_key		.k1,ANY_FIRE
	Do_menu		Opt2
.k1:	Do_key		.k2,key_left
	Do_last		11
	Do_add		-1,map_spin
	Do_max		0,map_spin
	Do_add		3,map_spin
	Do_const_but	11,3
.k2:	Do_key		.k3,key_right
	Do_next		11
	Do_add		1,map_spin
	Do_min		2,map_spin
	Do_add		-3,map_spin
	Do_const_but	11,-3
.k3:	Do_key		.k4,key_up
	Do_dulln	6,11
	Do_liten	4,5,9,10
	Do_rmw		3,4,5,8,9,10,6,11
	Do_but		3,8,c0
.k4:	Do_again

c2:	Do_key		.ko,key_option
	Do_menu		Opt1a
.ko:	Do_key		.k0,key_up
	Do_dulln	7,12
	Do_rmw		7,12,6,11
	Do_but		6,11,c1
.k0:	Do_key		.k1,ANY_FIRE
	Do_menu		Opt2
.k1:	Do_key		.k2,key_left
	Do_last		12
	Do_add		-1,tach_set
	Do_max		0,tach_set
	Do_add		2,tach_set
	Do_const_but	12,2
.k2:	Do_key		.k3,key_right
	Do_next		12
	Do_add		1,tach_set
	Do_min		1,tach_set
	Do_add		-2,tach_set
	Do_const_but	12,-2
.k3:	Do_key		.k4,key_down
	Do_dulln	7,12
	Do_liten	4,5,9,10
	Do_rmw		3,4,5,8,9,10,7,12
	Do_but		3,8,c0
.k4:	Do_again


seqadd:	dc.b	KEY_8,KEY_4,KEY_7,KEY_3,-1
seq2:	dc.b	JOY_UP,JOY_DOWN,JOY_UP,JOY_DOWN,KEY_6,KEY_7,JOY_RIGHT,KEY_9,KEY_4,-1
.even


.end
	Do_init		$0,$0,$15,$0		; set up just for options
	Do_screen	ObjDef5,sync
	Do_var_but	1,map_spin
	Do_var_but	2,tach_set
	Do_but		0,0,c0			; buttons don't get highlighted, but have to use same structure [or write extra one]

c0:	Do_ypos		3,92*2			; for now just highlight and move
	Do_abc		4,5,6,key_config
	Do_key		.ko,key_option
	Do_menu		Opt1a
.ko:	Do_key		.k0,key_down
	Do_but		0,0,c1
.k0:	Do_key		.k1,key_up
	Do_but		0,0,c2
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_right
	Do_max		5,key_config
	Do_add		1,key_config
.k3:	Do_key		.k4,key_left
	Do_min		0,key_config
	Do_add		-1,key_config
.k4:	Do_again

c1:	Do_ypos		3,165*2			; for now just highlight and move
	Do_key		.ko,key_option
	Do_menu		Opt1a
.ko:	Do_key		.k0,key_down
	Do_but		0,0,c2
.k0:	Do_key		.k1,key_up
	Do_but		0,0,c0
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_right
	Do_max		2,map_spin
	Do_next		1
	Do_add		1,map_spin
.k3:	Do_key		.k4,key_left
	Do_min		0,map_spin
	Do_last		1
	Do_add		-1,map_spin
.k4:	Do_again

c2:	Do_ypos		3,197*2			; for now just highlight and move
	Do_key		.ko,key_option
	Do_menu		Opt1a
.ko:	Do_key		.k0,key_down
	Do_but		0,0,c0
.k0:	Do_key		.k1,key_up
	Do_but		0,0,c1
.k1:	Do_key		.k2,ANY_FIRE
	Do_menu		Opt2
.k2:	Do_key		.k3,key_right
	Do_max		1,tach_set
	Do_next		2
	Do_add		1,tach_set
.k3:	Do_key		.k4,key_left
	Do_min		0,tach_set
	Do_last		2
	Do_add		-1,tach_set
.k4:	Do_again


****** the above is not code anymore, it used to run the different style config screen.
