
;*======================================================================*
;*                TITLE:                  TURTLE.S                      *
;*                Function:               Complete 3D Turtle Demo       *
;*                                                                      *
;*                Project #:              RAPIER                        *
;*                Programmer:             Rob Zdybel                    *
;*                                                                      *
;*              COPYRIGHT 1993 Atari Computer Corporation               *
;*          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
;*          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
;*        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
;*                            ALL RIGHTS RESERVED.                      *
;*                                                                      *
;*======================================================================*

try_sort	equ 1

	include "jaguar.inc"
	include "blit.inc"
	include "joypad.inc"
	include "objlist.inc"
	
;
;	EXTERNAL SYMBOLS
;

	.extern	cube		; Hand-Made Cube

	.extern	_Hots
	.extern _Look
	.extern _C_Test
	.extern _Check_Turtles

	.extern input
	.extern	centdata
	.extern	cwnndata
	.extern	cwwwdata
	.extern	cwssdata
	.extern	cweedata
	.extern roaddata
	.extern avendata
	.extern shpedata
	.extern shpwdata
	.extern shpsdata
	.extern shpndata
	.extern swnndata
	.extern swssdata
	.extern swwwdata
	.extern sweedata

	.globl _centdata
	.globl _cwnndata
	.globl _cwwwdata
	.globl _cwssdata
	.globl _cweedata
	.globl _roaddata
	.globl _avendata
	.globl _shpedata
	.globl _shpwdata
	.globl _shpsdata
	.globl _shpndata
	.globl _swnndata
	.globl _swssdata
	.globl _swwwdata
	.globl _sweedata

	.globl xposn
	.globl yposn
	.globl zposn
	.globl xrite
	.globl yrite
	.globl zrite
	.globl xdown
	.globl ydown
	.globl zdown
	.globl xhead
	.globl yhead
	.globl zhead
	
	.globl	do_sort

	.globl turtle
	.globl _ttop
	.globl _ttsize
	.globl turtlnk

	.extern TXTCRY_S
	.extern	text3D
	.extern	SORT_S
	.extern	bsort
	.extern	TURTLE_S
	.extern turtpak
	.extern TXTCRY_E
	.extern	SORT_E
	.extern	TURTLE_E
	.extern	gpuload
	.extern	gpurun
	.extern	gpuwait
	.extern	make_olist
	.extern	pad_now
	.extern	pad_shot
	.extern	readpad
	.extern	vblank
	.extern	vidinit
	.extern	Transform

	.extern	framecnt

	.extern	lastObj
	.extern objData
	
	.extern BuildObjList
	.extern	DISPBUF0
	.extern DISPBUF1
	.extern ZBUF


	.extern	TexVertPtr
	.extern	VertexPtr
	.extern	EndOfPack

	.extern	sort		;* GPU "painter's sort" program

	.globl	_main
	.globl	eyepts
	.globl	texpts
	.globl	mthpts
	.globl	brpts
	.globl	map1pts
	.globl	map2pts
	.globl	map3pts
	.globl	map4pts
	.globl	map5pts
	.globl	map6pts
	.globl	map7pts
	.globl	map8pts
	.globl   do_turtle
;
;	USEFUL DEFINES
;

RAMSIZE		EQU	$1000		; 4K bytes
INPUT6		EQU	G_ENDRAM-$4	; pointer to parameter 6 for GPU
INPUT5		EQU	INPUT6-$4	; pointer to parameter 5 for GPU
INPUT4		EQU	INPUT5-$4	; pointer to parameter 4 for GPU
INPUT3		EQU	INPUT4-$4	; pointer to parameter 3 for GPU
INPUT2		EQU	INPUT3-$4	; pointer to parameter 2 for GPU
INPUT1		EQU	INPUT2-$4	; pointer to parameter 1 for GPU

;
;	PROGRAM SEGMENT
;

	.text

_main:
	move.l	#DISPBUF0+15,	d0	; Set up screen buffers with
	and.l	#~15,	d0	; draw_ptr on a 256 byte boundary
	move.l	d0,	draw_ptr
	addq	#8,	d0
	move.l	d0,	disp_ptr

	jsr		initurtl	; initialize turtles

	moveq.l	#0,	d0
	moveq.l	#-1,	d1
	move	d0,	gameover	; Game not over yet
	move.l	d1,	pad_now		; Clear the joypad
	move	d0,	ncubes

	move	d0,	rotate_flg
	move	d1,	amb_flg
	move	d1,	sun_flg
	move	d1,	bulb_flg
	move	d0,	scrublist	; ScrubList = Nil
	move	#1,	drawlist	; One Object

framelp:
	move.l	#$FFFFFFFF,PIT0

	jsr	clrscreen	; Clear the draw buffer
	
	jsr	_Look		; Look to see what's visable
	
;	move.l	#turtle, a0		; camera's model-ptr is top of list
;	move.w	turtlnk(a0), d0		; see what first turtle is
if try_sort	
	move.w	#1,	drawlist	; set top of drawlist to it
	move.w	#0,	scrublist	; always start with empty scrublist
	jsr	do_sort			; sort our list
endif

	lea	TXTCRY_S,	a0
	lea	text3D,		a1
	move.l	#TXTCRY_E,	d0
	sub.l	#TXTCRY_S,	d0
	jsr	gpuload		; Load Polyhedron Draw Routine into GPU RAM

	move.l	PIT0,		d0
	move.l	d0,		time1

	jsr	Inner_Loop

	jsr	readpad		; Read the Joypad

	jsr	gpuwait		; Wait for GPU Idle
	
	move.l	PIT0,d0
	move.l	d0,time2

	move.l	disp_ptr,d0
	move.l	draw_ptr,disp_ptr
	move.l	d0,draw_ptr	; Swap buffers

	lea	objData,a1
	move.l	disp_ptr,O_DATA(a1)

	clr.l	d6
	move.w	lastObj,d6
	add.w	#1,d6

	jsr	BuildObjList

	jsr	input		; DEBUG Interpret the Joypad input

	move.l	framecnt,d7	; D7 = Current Frame for sync later

.wsync:	cmp.l	framecnt,d7
	beq	.wsync		; Wait for video sync

timecheck:
	move.l	PIT0,d0
	move.l	d0,time3
	bra	framelp		; go forever
stop:
	illegal			; **KLUDGE** FORCE EXIT TO ADB
	nop

;
;	SUBROUTINE AREA
;

;
;	INITURTL   Initialize the TURTLE database
;
;	Given:
;		Control
;
;	Returns:
;		All Turtles initialized to Origin
;
;	Register Usage:
;		All Registers Restored
;
;	Externals:
;		
;
initurtl:
	movem.l	d0-d2/a0,-(sp)

	move.l	#141,nturtles
	move.w	#0,stretch

	lea	turtle,a0
	clr	d0
	move	#$4000,d1
	move	#((maxturtl+hotturtl)-1),d2
.clrlp:	
   move	d1,xrite(a0)	; FOR (All Turtles) DO
	move	d0,yrite(a0)	; Init to Origin - Ordirnally aligned
	move	d0,zrite(a0)
	move	d0,xdown(a0)
	move	d1,ydown(a0)
	move	d0,zdown(a0)
	move	d0,xhead(a0)
	move	d0,yhead(a0)
	move	d1,zhead(a0)
	move	d0,xposn(a0)
	move	d0,yposn(a0)
	move	d0,zposn(a0)
	move	d0,turtlnk(a0)
	add.l	#turtlsiz,a0
	dbra	d2,.clrlp

	jsr Chaos_Turtles

	lea	turtle,a0
;	move	#$fe00,zposn(a0)	; Position Viewpt in front of object
	moveq	#0, d6
	move	#$4000,d7
	move	d7,xrite(a0)	; Init to Origin - Ordirnally aligned
	move	d6,yrite(a0)	; Init to Origin - Ordirnally aligned
	move	d6,zrite(a0)
	move	d6,xdown(a0)
	move	d7,ydown(a0)
	move	d6,zdown(a0)
	move	d6,xhead(a0)
	move	d6,yhead(a0)
	move	d7,zhead(a0)
	
	move.w	#(14 * 2 * 128),	xposn(a0)
	move.w	#(9 * 2 * 128),   zposn(a0)
	move.w	#0,					yposn(a0)
	sub.w		#100,					yposn(a0)

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


;
;	CLRSCREEN   BLTTER Zero fill the draw buffer and Zbuffer
;
;	Given:
;		DRAW_PTR = Ptr to Current draw buffer
;
;	Returns:
;		Draw buffer and Zbuffer zeroed
;
;	Register Usage:
;		All Registers Restored
;
;	Externals:
;		clrbuffer
;
clrscreen:
	movem.l	d0/a0,-(sp)

	moveq.l	#0,d0
	move.l	draw_ptr,a0
	jsr	clrbuffer

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


;
;	CLRBUFFER   BLTTER Zero fill a 320x200x2 screen buffer
;
;	Given:
;		D0 = Data Pattern to fill with
;		A0 = Ptr to Buffer to Clear
;
;	Returns:
;		Draw buffer zeroed
;
;	Register Usage:
;		All Registers Restored
;
;	Externals:
;		None
;
clrbuffer:
	movem.l	d0-d1/a0-a1,-(sp)

	move.l	#B_CMD,a1
.waitblit:			; Wait for BLTTER Idle
	move.l	(a1),d1
	lsr.w	#1,d1
	bcc	.waitblit

 	move.l	#(PITCH2|PIXEL16|WID320|XADDPHR),A1_FLAGS
	move.l	a0,A1_BASE	; Point to the buffer

	move.l	d0,B_PATD
	move.l	d0,B_PATD+4	; Select Fill Pattern

	clr.l	d0
	move.l	d0,A1_PIXEL	; Point to (0,0)

	move.w	#1,d0
	swap	d0
	move.w	#-320,d0
	move.l	d0,A1_STEP	; Step -320 x, +1 y each line

	move.w	#200,d0
	swap	d0
	move.w	#320,d0
	move.l	d0,B_COUNT	; Do 320x200

	move.l	#(PATDSEL|UPDA1),B_CMD	; Start the BLTTER


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


;
;	DO_TURTLE   Execute the turtle package
;

;	Given:
;		d0 = Index of Turtle to Operate on
;		d1 = PITCH
;		d2 = YAW
;		d3 = ROLL
;		d4 = VELOCITY
;
;	Returns:
;		Turtle updated
;
;	Register Usage:
;		All Registers Restored
;
;	Externals:
;		GPURUN, GPUWAIT
;
do_turtle:
	movem.l	a0/d0-d4,-(sp)

	mulu	#turtlsiz,d0
	add.l	#turtle,d0	; D0 = Address of Turtle Record
	move.l	d0,INPUT1

	move.l	d1,INPUT2
	move.l	d2,INPUT3
	move.l	d3,INPUT4
	move.l	d4,INPUT5	; Remaining inputs

	lea	TURTLE_S,a0
	jsr	gpurun		; run the GPU program

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


;
;	DO_FASTDRAW   Execute the Polyhedron Draw package
;
;	Given:
;		D0 = Ptr to Turtle to Draw
;
;	Returns:
;		Object Drawn
;
;	Register Usage:
;		All Registers Restored
;
;	Externals:
;		GPURUN
;
do_fastdraw:
	movem.l	a0/d0,-(sp)

	jsr	gpuwait

	move.l	d0,INPUT3	; Pass Ptr to Viewed Object

	move.l	model_ptr,INPUT1	; Ptr to Instance

	move.l	#turtle,INPUT2	; Turtle[0] is Viewer

;	move.l	#litemodel,INPUT4	; Ptr to Lighting model
	move.l	#ambient,INPUT4		; Ptr to Lighting model

	move.l	draw_ptr,INPUT5	; tell GPU where to find parameters

	move.l	#instance,INPUT6	; use for vertex copies

	lea	TXTCRY_S,a0
	jsr	gpurun		; run the GPU program

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


;*======================================================================*
;*
;*	DO_SORT   Execute GPU Bubble Sort
;*
;*	Given:
;*		DRAWLIST  = Last Frame's Sorted See-ables (Inverted, Please)
;*		SCRUBLIST = Last Frame's UNSee-ables
;*		NTURTLES  = Number of Active Turtles
;*		TURTLE    = Turtle Record Array
;*
;*	Returns:
;*		DRAWLIST  = Painter's Sorted See-ables list root index
;*		SCRUBLIST =  UNSee-ables list root index
;*
;*	Register Usage:
;*		All Registers Restored
;*
;*	Externals:
;*		GPURUN, GPULOAD
;*
;*======================================================================*
do_sort:
	movem.l	a0/d0-d1,-(sp)

	jsr	gpuwait			;* Wait for GPU Idle

	lea	SORT_S,a0
	lea	bsort,a1
	move.l	#SORT_E,d0
	sub.l	#SORT_S,d0
	jsr	gpuload		

	move.l	#turtle,INPUT1		; Address of Viewpt Record
	
	move.l	#drawlist ,INPUT2	; Address of Drawlist Root
;	move.l	#(drawlist + (1000 * turtlsiz)) ,INPUT2	; Address of Drawlist Root
;	move.l	#1000,INPUT2	; Address of Drawlist Root

	move.l	#scrublist,INPUT3	; Address of Scrublist Root
	
	move.l	#turtle+turtlsiz,INPUT4	; Address of Turtle[1]
;	move.l	#(turtle + (1000 * turtlsiz)),INPUT4	; Address of Turtle[1]

;	move.l	nturtles,d0
;	beq	skipsort
;	move.l	#141,	d0
;	move.l	d0,INPUT5		; Number of Active Turtles
	move.l	_Hots, INPUT5
	move.l	#turtlsiz,d0
	move.l	d0,INPUT6		; Length of a Turtle Record
   
	lea	SORT_S,a0
	jsr	gpurun		; run the GPU program

;;	jsr	gpuwait			;* Wait for GPU Idle
skipsort:
	movem.l	(sp)+,d0-d1/a0
	rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MJP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

if try_sort
	move.w	drawlist,	d0		; get drawlist root
else
	move.l	#turtle, a0		; first turtle is camera, it points to
	move.w	turtlnk(a0), d0		; the first visable turtle
endif	

some_loop:	
	mulu	#turtlsiz, d0		; Get offset for d0th turtle
	add.l	#turtle,   d0		; Add to start of turtle list
	move.l	d0,	   a0	
	
	move.l	model(a0), model_ptr	; turtle knows where its model is
	jsr	gpuwait			; Wait for GPU Idle
	jsr	do_fastdraw		; Start GPU/BLTTER Polyhedron Draw

	move.w	turtlnk(a0), d0		; see what next turtle is
	beq	done_list
	
	bra	some_loop

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Chaos_Turtles:

	move.l	#turtle,	_ttop
	move.l	#centdata,	_centdata
	move.l	#cwnndata,	_cwnndata
	move.l	#cwssdata,	_cwssdata
	move.l	#cwwwdata,	_cwwwdata
	move.l	#cweedata,	_cweedata
	move.l	#roaddata,	_roaddata
	move.l	#avendata,	_avendata
	move.l  #shpedata,      _shpedata
	move.l  #shpwdata,      _shpwdata
	move.l  #shpsdata,      _shpsdata
	move.l  #shpndata,      _shpndata
	move.l  #swnndata,	_swnndata
	move.l  #swssdata,	_swssdata
	move.l  #swwwdata,	_swwwdata
	move.l  #sweedata,	_sweedata

	jsr	_C_Test
			
	rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;
;	VARIABLE RAM
;
	.bss
	.even
disp_ptr:		; Display buffer ptr
	.ds.l	1
draw_ptr:		; Draw buffer ptr
	.ds.l	1
zbuf_ptr:		; Z buffer ptr
	.ds.l	1

drawlist:		; Root (Index really) to List of See-able turtles
	.ds.w	1
scrublist:		; Root (Index really) to List of UNSee-able turtles
	.ds.w	1
newlist:
	.ds.w	1

model_ptr:		; Ptr to Instance
	.ds.l	1
.phrase
instance:		; Storage for INSTANCE
	.ds.l	4*2048	; 32K Bytes
.phrase
litemodel:		; Lighting Model
	.ds.w	12	; Enough for Ambient and 2 sources

gameover:		; Game Over Flag (0 ==> Game Active)
	.ds.w	1
rotate_flg:		; Cube rotation Flag (0 ==> Sit Still)
	.ds.w	1
sun_flg:		; Sun Lighting Flag (0 ==> No Sun)
	.ds.w	1
bulb_flg:		; InScene Lighting Flag (0 ==> No Bulb)
	.ds.w	1
amb_flg:		; Ambient Lighting Flag (0 ==> No Intensity Change)
	.ds.w	1
ncubes:			; Number of Cubes in space (Less One)
	.ds.w	1
nturtles:		; Number of turtles in space
	.ds.l	1
stretch:
	.ds.w	1	; stretch factor to modify the cube
time1: .ds.l	1
time2:	.ds.l	1
time3:	.ds.l	1
;
;	TURTLE RECORDS
;
xrite	=	0		; IMPORTANT NOTE:
yrite	=	xrite+2		; These first record offsets are hard-wired
zrite	=	yrite+2		; into associated GPU routines.
xdown	=	zrite+2		; DO NOT Insert, Delete or Swap any of these
ydown	=	xdown+2		;	^
zdown	=	ydown+2		;	|
xhead	=	zdown+2		;	|
yhead	=	xhead+2		;	|
zhead	=	yhead+2		;	|
xposn	=	zhead+2		;	|
yposn	=	xposn+2		;	|
zposn	=	yposn+2		;	v
turtlnk =	zposn+2		; Dont change this or anything above here
gridx = turtlnk + 2
gridy = gridx + 1
model   =	gridy+1	; Mike added this
turtlsiz =	model+4
maxturtl =	1000
hotturtl =	100

.phrase
turtle:			; All Motion Objects
	.ds.b	maxturtl*turtlsiz
	.ds.b	hotturtl*turtlsiz	; see cmain.s

.phrase
_ttop:		.ds.l	1
_centdata:	.ds.l	1
_cwnndata:	.ds.l	1
_cwwwdata:	.ds.l	1
_cwssdata:	.ds.l	1
_cweedata:	.ds.l	1
_roaddata:	.ds.l	1
_avendata:	.ds.l	1
_shpedata:	.ds.l	1
_shpwdata:	.ds.l	1
_shpsdata:	.ds.l	1
_shpndata:	.ds.l	1
_swnndata:	.ds.l	1
_swssdata:	.ds.l	1
_swwwdata:	.ds.l	1
_sweedata:	.ds.l	1

;
;	CONSTANT DATA
;
	.data
	.long
ambient:			; Ambient Intensity
	.dc.w	$FF		; (was 80)
bulb:				; InScene Light
;	.dc.w	$00FF		; Intensity
;	.dc.w	$f000		; X
;	.dc.w	$f000		; Y
;	.dc.w	$f000		; Z
	.dc.w	$ffFF		; Intensity
	.dc.w	$ffff		; X
	.dc.w	$ffff		; Y
	.dc.w	$ffff		; Z
sun:				; Sun
	.dc.w	$ffff		; Intensity
	.dc.w	$ffff		; X
	.dc.w	$ffff		; Y
	.dc.w	$ffff		; Z
;	.dc.w	$00ff		; Intensity
;	.dc.w	$4000		; X
;	.dc.w	$0000		; Y
;	.dc.w	$0000		; Z


.long
texpts:	dc.w	0,0,63,0,63,63,0,63	; texturemap ptsin		
eyepts: dc.w	0,0,127,0,127,79,0,79
mthpts:	dc.w	0,0,191,0,191,67,0,67
brpts:	dc.w	0,0,191,0,191,119,0,119
;map1pts:	dc.w	0,0,319,0,319,129,0,129 ; Width = 320, Height = 130
;map2pts:	dc.w	0,0,319,0,319,129,0,129 ; Width = 320, Height = 130
map1pts:	dc.w	0,0,95,0,95,95,0,95
map2pts:	dc.w	0,0,95,0,95,95,0,95
map3pts:	dc.w	0,0,95,0,95,95,0,95
map4pts:	dc.w	0,0,95,0,95,95,0,95
map5pts:	dc.w	0,0,95,0,95,95,0,95
map6pts:	dc.w	0,0,95,0,95,95,0,95
map7pts:	dc.w	0,0,95,0,95,95,0,95
map8pts:	dc.w	0,0,95,0,95,95,0,95

	.end
;*======================================================================*
;*                                 EOF                                  *
;*======================================================================*

