; In order to allow maximum flexibility of the track generator system, every
; command will be defined as an equ in here, and then these values will be used
; for the track source files and the interpreter code.
; Codes will be one byte, with on extra byte following containing object numbers etc, to assure alignment

; Required codes :

; Start [abs x] [abs z] [y rot]			- set the start location and direction
; Add track piece [object number]		- object number is number of object within the LIMZ list
; Add other object [obj number] [x rel] [z rel] [y rot]

; Split [obj number]				- place piece, push alternate x,z and set main x,z
; Unsplit [obj number]				- pops x,z and places piece

; Flag on [flag number]				- flag number refers to a long word of current flags including :
;	also:					- barriers left/right
; Flag off [flag number]			- trees left/right
; Flag change [flag number]			- trees double/single
;						- palms left/right
;						- chevrons on bends (side auto determined, auto detection of bends)
;						- dotted centre line
;						- 

; Trigger [event no] [x rel] [z rel] [radius]	- a whole section of memory will be reserved for these 'events' which will be
;						  dealt with by vectored subroutines which will be passed the vehicle number which
;						  has triggered the event.  These may include the lap timer, and the race arbiter.
; Monitor [event no] [[x rel] [z rel]] *2	- same event codes, but detects when a vehicle passes BETWEEN two points, which will
;						  be ideal for the lap timer.

; This should cover most eventualities, but one thing is worth noting :
; landscape features such as rivers will need to be coded separately in all likelihood,
; so there probably needs to be the option of passing these kind of features first, and then 
; adding the rest on afterwards, reserving space of course.
; Also, the main list (trees buildings etc) will include the data for the cars, the wheels of which need to
; have 'rotation' set up, so the generator needs to pass the appropriate address for the spinner.
; At the same time, the cars address can be set up - these will probably best be placed after the other data.
; The starting positions need to be fixed somehow as well - probably using something like the trigger points.

; Additional item :
; to allow changing between different barriers / but using as little extra data as possible, we now have :
; New barriers [bar-left] [bar-right]		- where barrier codes are object codes
; entered simply by setting an extra bit in the command code - and then placing the two bytes after it.
; this will : a) if bar-left and bar-right are both 0, clear a flag in the flags register and 
; set the left and right bar codes (two bytes in vardefs)
;		b) otherwise, set the same flag, and set the bar codes
; the mods to tgen will then go as follows :
; 1. modify the decode stage to take account of the above extra bit incorporation
; 2. allocate space for extra codes and additional flag
; 3. modify output stage to check for special barrier codes when about to output the barriers
; 4. modify pre-scan stage to allow for remote possibility that special barriers are not on stream 6

; Further addition :
; to allow sensible easy entry of the large scale landscape objects such as lakes,
; which are defined as a combination of fixed sized (grid) objects, we add a grid command and a
; set of extra commands to go with it. The grids are axis aligned and data is entered in x lines through z.
; New commands :

; Grid [obj no] [abs x] [abs z] [y rot] [grid x] [grid z]	- first piece, start location and grid step size
; Grid_obj [object number] [y rot]		- place object and then move one x step
; Grid_line [offset]				- reset x to start size, increment z, then skip offset x steps - must be plus !
; Grid_skip [offset]				- skip x steps - positive only
; Grid_end					- stop entering grid data, use normal structure again

;====================================================
;		COMMAND CODES
;====================================================
; command values are in three main groups - object commands (those that add an object to a list)
; flag commands (those that switch something on or off) and 
; position commands (those that set a position for detection or placement - including triggers, monitors, and starting grid positions)
; they are separate to facilitate easy counting of the list elements

START	=	$BB85		; because its so rare, and it must be the first byte for a valid track definition
REVB	=	7
EXTRAB	=	6
REVERSE	=	1<<REVB		; flag to append to (OR with) command code for left turns and reversed segments
EXTRAS	=	1<<EXTRAB	; flag to signify manual barrier codes following
STOP	=	0
ADDT	=	1		; code for adding an object like track - fitting end to end
BEND	=	2		; same idea, but non-straight
CORNER	=	3		; and same but tight corner - separated out because of need for changes to trees, arrows etc
PUSH	=	4		; stack the current position, for later use (basically for start of pits)
POP	=	5		; unstack the saved position
ADDO	=	6		; code for placing an object at a specific position relative to the track, and absolute rotation
ADDR	=	7		; same but relative position considered with track direction as z axis, rotation relative to track

FLAGON	=	8		; these commands (8-15) are all treated specially
FLAGOFF	=	9
FLAGCHG	=	10
FLAGIN	=	11

VIEW	=	12		; a special command for inserting the view data as in the old format - will be superceded
OLDDATA	=	13		; another special - insert data in old format, into stream number n, with the first long being the object count.

GRID_I	=	14
GRID_O	=	15
GRID_L	=	16
GRID_S	=	17

TRIGGER	=	18		; all values above 16 are assumed not to effect the number of 3d objects in any way.
MONITOR	=	19

NEWTWIST =	20		; set both target twist and target direction - byte for twist, word for direction
INCTWIST =	21		; set both increments - as above

ADDLONG	=	22		; quick and dirty direct long range relative positioning (no rotation, so x,z are real world)
VIEWMAX = 	23		; set a viewpoint number limit to prevent difficulty in tunnels etc
BITOPS  =	24		; various track flag operations (eg rain on/off, tight corners (for ai))
ADDHIGH	=	25		; standard object add but sets height as well (given AFTER the normal co-ordinates)
MOVE	=	26		; works with same data as objrel, in similar way, but moves co-ordinates and doesn't add any objects
PARK	=	27		; like objrel, but adds position to a list of parking spaces
FLY	=	28		; does nothing, but stores preceding entry address for use by flying code
PITEND	=	29		; does nothing, just notes current track segment number

UNUSED	=	30		; modify whenever more commands are entered to ensure error checking works.

;====================================================
;		COMMAND MACROS
;====================================================

.macro	start	xabs,zabs,yrot
dc.w	START
dc.l	\xabs,\zabs
dc.w	\yrot
.print 'commencing new track.'
.endm

put_extra	set	0
extra_left	set	0
extra_right	set	0
put_reverse	set	0
main_command	set	0


.macro	manbars		obj1,obj2
put_extra	set	1
extra_left	set	\obj1
extra_right	set	\obj2
.endm

.macro	write_data	obj
.iif	put_reverse,	main_command set main_command + REVERSE
.iif	put_extra,	main_command set main_command + EXTRAS
			dc.b	main_command,\obj
.iif	put_extra,	dc.b	extra_left,extra_right
	put_extra set	0
.endm


.macro	straight	obj
put_reverse	set	0
main_command	set	ADDT
write_data	\obj
.endm

.macro	reverse		obj
put_reverse	set	1
main_command	set	ADDT
write_data	\obj
.endm

.macro	bendr		obj
put_reverse	set	0
main_command	set	BEND
write_data	\obj
.endm

.macro	bendl		obj
put_reverse	set	1
main_command	set	BEND
write_data	\obj
.endm

.macro	right		obj
put_reverse	set	0
main_command	set	CORNER
write_data	\obj
.endm

.macro	left		obj
put_reverse	set	1
main_command	set	CORNER
write_data	\obj
.endm

.macro	commobj	comm,obj
	dc.b	\comm,\obj
.endm

.macro	object	obj,xrel,zrel,yrot
	commobj	ADDO,\obj
	dc.w	\xrel,\zrel,\yrot
.endm

.macro	objrel	obj,xrel,zrel,yrot
	commobj	ADDR,\obj
	dc.w	\xrel,\zrel,\yrot
.endm

.macro	moveit	xrel,zrel,yrot
	dc.b	MOVE
	dc.w	\xrel,\zrel,\yrot
.endm

.macro	objlong	obj,xrel,zrel,yrot
	commobj	ADDLONG,\obj
	dc.l	\xrel,\zrel
	dc.w	\yrot
.endm

.macro	objhigh	obj,xrel,zrel,yrot,height
	commobj	ADDHIGH,\obj
	dc.w	\xrel,\zrel,\yrot
	dc.l	\height
.endm

.macro	pushpos
	dc.b	PUSH,0
.endm

.macro	poppos
	dc.b	POP,0
.endm

.macro	park	xrel,zrel,yrot
	dc.b	PARK,0
	dc.w	\xrel,\zrel,\yrot
.endm

.macro	fly		; no parameters - orders flying for previous object
	dc.b	FLY,0
.endm

.macro	pitmark
	dc.b	PITEND,0
.endm

.macro	flagon	flag
	dc.b	FLAGON,\flag
.endm

.macro	flagoff	flag
	dc.b	FLAGOFF,\flag
.endm

.macro	flagchg	flag
	dc.b	FLAGCHG,\flag
.endm

.macro	flaginit bin
	dc.b	FLAGIN,(\bin >> 16)
dc.w	(\bin & $FFFF)
.endm

.macro	view
	dc.b	VIEW,0		; the actual view data should follow in its original format (dc.w etc)
.endm

.macro	olddata	stream
dc.b	OLDDATA,\stream		; actual data follows in original format
.endm

.macro	depth str,dep,v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13
dc.b	DEPTH,\stream
dc.l	\dep
.iif	\?v0,	depth \v0,\v1,\v2,\v3,\v4,\v5,\v6,\v7,\v8,\v9,\v10,\v11,\v12,\v13
.endm

.macro	gridinit obj,xabs,zabs,yrot,xstep,ystep
	commobj	GRID_I,\obj
	dc.l	\xabs,\zabs
	dc.w	\yrot,\xstep,\ystep
.endm

.macro	gridobj	obj,yrot
	commobj	GRID_O,\obj
	dc.w	\yrot
.endm

.macro	gridline skip
	dc.b	GRID_L,\skip
.endm

.macro	gridskip skip
	dc.b	GRID_S,\skip
.endm

.macro	gridstop
	dc.b	GRID_S,0
.endm

.macro	endtrack
	dc.w	STOP
.endm

.macro	twisttgt twist,dir
	dc.b	NEWTWIST,\twist
	dc.w	\dir
.endm

.macro	twistinc twist,dir
	dc.b	INCTWIST,\twist
	dc.w	\dir
.endm

.macro	viewmax max		; use viewmax 0 to reset
	dc.b	VIEWMAX,\max
.endm

.macro	setbit value
	dc.b	BITOPS,$10+\value	; set bit 'value' in track flags
.endm

.macro	clrbit value
	dc.b	BITOPS,$00+\value	; clear bit 'value' in track flags
.endm

.macro	chgbit value
	dc.b	BITOPS,$20,+\value	; change bit 'value' in track flags
.endm

;====================================================
;		FLAG NAMES
;====================================================

BARL	equ	0	; first off the flags which do affect the
TREEL0	equ	1	; object count per track object
TREEL1	equ	2
PALML	equ	3



BARR	equ	8
TREER0	equ	9
TREER1	equ	10
PALMR	equ	11

WARN	equ	16
DOT	equ	17
LINE	equ	18
CARPET	equ	19
CLOSE	equ	20	; flag to require that trees (only) use the closer version (obj +1)

LASTFG	equ	20	; to allow quick mods later - used in tgen.s

EXTRAL	equ	30	; flags which don't affect the object count
REVL	equ	31

; detailed notes on certain flags :
; EXTRAL holds the status of the non-standard barrier codes, so if it is set, then barrier codes are read in from elsewhere, 
; rather than the usual read from the definition of the object - it is only modified by changing the 'manbars' codes

; REVL holds the status on a short term basis of the reversal of objects

; LASTFG is used to make sure no deliberate or acceidental attempt is made to change flags which are undefined

; bit numbers for track flags

COVERED	equ	0	; whence no rain in tunnels - manually specified
TURNING	equ	1	; whence more slow down on turns - this is any piece which changes direction at all - auto-generated
TIGHT	equ	2	; for careful driving round curves - applied manually
WIDE	equ	3	; for the wider sections of track (eg 3 laners) where maximum distance from track can be increased
