*=======================================================*
*	Falcon030 Doom project (Bad Mood) v1.32 alpha	*
*=======================================================*
*	Display engine based on DVIEW by Jake Hill	*
*		(DVIEW is a PC C++ program)		*
*=======================================================*
*	Main core: latest update 27/11/95		*
*=======================================================*
* Team members:		(in no particular order)...	*
*-------------------------------------------------------*
* Coordinator:		Bertrand Le Roy.		*
*-------------------------------------------------------*
* Atari C port/code:	Johan Klockars.			*
*-------------------------------------------------------*
* Map & game code:	Laurent Sallafranque.		*
*-------------------------------------------------------*
* 3D & rendering code:	Douglas  Little.		*
*-------------------------------------------------------*
* WAD & Ikbd modules:	Dave Murphy.			*
*-------------------------------------------------------*
* (other team members should append their names here!)	*
*-------------------------------------------------------*

	OPT		P=68030

	OPT		O+,W-

;test			; enable for forced WAD path (debugging only)
;debuggable		; enable this for 'soft' interrupts
enable_timing		; enable this for timing information
dsp			; enable for DSP rendering

*-------------------------------------------------------*
*	Initial display size				*
*-------------------------------------------------------*

max_width		=	320
max_height		=	200

*-------------------------------------------------------*
*	Keycodes for control & player movement		*
*-------------------------------------------------------*

quit_key		=	1	; 'ESC' key
map_key			=	15	; 'TAB' key

minus_key		=	12	;
plus_key		=	13	;

left_key		=	$4b	; left arrow
right_key		=	$4d	; right arrow
forward_key		=	$48	; up arrow
back_key		=	$50	; down arrow
alt_key			=	$38	; 'ALT' key

*-------------------------------------------------------*
*	Main program includes				*
*-------------------------------------------------------*

	include		include\header.s
	include		include\macros.s
	include		include\video.s

*-------------------------------------------------------*
*	Path for forced WAD file			*	
*-------------------------------------------------------*
	bra	Doom
*-------------------------------------------------------*

fixcase	macro
	cmp.b		#'a',\1
	blo.s		.no\@
	cmp.b		#'z',\1
	bhi.s		.no\@
	and.w		#$FF,\1
	sub.w		#'a'-'A',\1
.no\@:	
	endm	

TestName:	dc.b		'l:\wads\doom.wad e1m1'
		;dc.b		'l:\wads\map01.wad'
		;dc.b		'l:\wads\e1m1.wad'
		;dc.b		'l:\wads\e3m2.wad'
		;dc.b		'l:\wads\e4m7.wad'
		;dc.b		'l:\wads\uac_dead.wad'
		;dc.b		'l:\wads\doomtrek.wad'
		dc.b		0
		even

WadName:	ds.b	256
WadLevel:	ds.b	16
		even

*-------------------------------------------------------*
*	Program starts here				*	
*-------------------------------------------------------*
Doom:	move.l		4(sp),a5
	lea		128(a5),a4	; command string
	move.l		a4,cli
	move.l		12(a5),d0	; text segment
	add.l		20(a5),d0	; data segment
	add.l		28(a5),d0	; bss segment
	add.l		#$100,d0	; base page
	move.l		d0,-(sp)
	move.l		a5,-(sp)
	clr.w		-(sp)
	move.w		#$4a,-(sp)
	trap		#1		; mshrink
	lea		12(sp),sp
	dc.w		$A00A
*-------------------------------------------------------*
*	Commandline module				*
*-------------------------------------------------------*
	move.l		cli,a5
*-------------------------------------------------------*
	ifnd		test
*-------------------------------------------------------*
	output		doom.ttp
*-------------------------------------------------------*
	moveq		#0,d0
	move.b		(a5)+,d0
	bne.s		.load
	moveq		#4,d0
	bra		Error
*-------------------------------------------------------*
	elseif
*-------------------------------------------------------*
	lea		TestName,a5
	move.w		#255,d0
*-------------------------------------------------------*
	endc
*-------------------------------------------------------*
.load:	lea		WadName,a0
	lea		WadLevel,a2	
.nwad:	move.b		(a5)+,d1
	beq.s		.lwad
	fixcase		d1
	cmp.b		#' ',d1
	beq.s		.lwad
	move.b		d1,(a0)+
	subq.w		#1,d0
	bne.s		.nwad
	move.l		#-1,(a2)+
	bra.s		.done
.nlwad:	move.b		(a5)+,d1
	beq.s		.done
	fixcase		d1
	move.b		d1,(a2)+
.lwad	subq.w		#1,d0
	bne.s		.nlwad
.done:	clr.b		(a0)
	clr.b		(a2)
*-------------------------------------------------------*
*	Flush out BSS					*
*-------------------------------------------------------*
	bss
*-------------------------------------------------------*
bss_start:
*-------------------------------------------------------*
	text
*-------------------------------------------------------*
	lea		bss_start,a0
	move.l		#(bss_end-bss_start)/4,d0
	moveq		#0,d1
.clr:	move.l		d1,(a0)+
	subq.l		#1,d0
	bne.s		.clr
*-------------------------------------------------------*
*	Flush keyboard buffer				*
*-------------------------------------------------------*
	bsr		empty_buffer
*-------------------------------------------------------*
*	Prepare arrays for WAD parser			*
*-------------------------------------------------------*
	bsr		init_wadarrays
*-------------------------------------------------------*
*	Parse Doom WAD file				*
*-------------------------------------------------------*
	bsr		OpenWad
*-------------------------------------------------------*
*	Supervisor mode					*
*-------------------------------------------------------*
	pea		ourstack
	push.w		#32
	trap		#1
	addq.l		#6,sp
	push.l		d0
*-------------------------------------------------------*
*	Allocate space for new screenbuffers		*
*-------------------------------------------------------*
	bsr		allocate_screens
*-------------------------------------------------------*
*	Setup new display configuration			*
*-------------------------------------------------------*
	bsr		select_video
*-------------------------------------------------------*
*	Kickstart DSP AddWall function			*
*-------------------------------------------------------*
	ifd		dsp
	bsr		start_dsp_addwall
	endc
*-------------------------------------------------------*
*	Select initial window size & init tables	*
*-------------------------------------------------------*
	move.w		#window_max,window_size
	bsr		select_window
*-------------------------------------------------------*
*	Set up display engine				*
*-------------------------------------------------------*
	bsr		init_engine
*-------------------------------------------------------*
*	Enable VBI & timing interrupts			*
*-------------------------------------------------------*
	bsr		init_timing
*-------------------------------------------------------*
*	Replace keyboard handler			*
*-------------------------------------------------------*
	ifnd		debuggable
	bsr		Initialise_ikbd
	endc
*-------------------------------------------------------*

*-------------------------------------------------------*
*	Main program loop				*
*-------------------------------------------------------*
game_loop:
*-------------------------------------------------------*
*	Move player					*
*-------------------------------------------------------*
	bsr		player_control
*-------------------------------------------------------*
*	Get player direction				*	
*-------------------------------------------------------*
	bsr		triangulate
*-------------------------------------------------------*
*	Display environment				*
*-------------------------------------------------------*
	bsr		display_engine
*-------------------------------------------------------*
*	Display level map				*	
*-------------------------------------------------------*
	bsr		display_map
*-------------------------------------------------------*
*	Display framerate in corner of screen		*
*-------------------------------------------------------*
	ifd		enable_timing
	bsr		timing
	endc
*-------------------------------------------------------*
*	Double-buffered display				*
*-------------------------------------------------------*
	vsync
	bsr		adjust_scanlines
	triplebuffer
*-------------------------------------------------------*
*	Check for exit key				*
*-------------------------------------------------------*
	tst.b		program_quit
	beq.s		game_loop

*-------------------------------------------------------*
*	Program end - restore parameters & exit		*
*-------------------------------------------------------*
game_exit:
*-------------------------------------------------------*
*	Restore system					*
*-------------------------------------------------------*
	ifnd		debuggable
	bsr		Remove_ikbd
	endc
	bsr		reset_timing
	bsr		empty_buffer
	bsr		restore_video
	bsr		deallocate
*-------------------------------------------------------*
*	Return to user mode				*
*-------------------------------------------------------*
	move.w		#32,-(sp)
	trap		#1
	lea		10(sp),sp
*-------------------------------------------------------*
*	Exit program					*
*-------------------------------------------------------*
Error_Quit:
*-------------------------------------------------------*
	dc.w		$A009
	clr.w		-(sp)
	trap		#1

*-------------------------------------------------------*
*	Player control module with turning & movement	*
*-------------------------------------------------------*
player_control:
*-------------------------------------------------------*
	lea		key_buffer,a6
	tst.b		left_key(a6)
	beq.s		not_left
	tst.b		alt_key(a6)
	bne.s		move_left
	add.w		#turn_speed,Pangle
	bra.s		not_left
move_left:
	move.w		#$4000,d1
	move.w		#player_speed,d0
	bsr		move_player
not_left:
	tst.b		right_key(a6)
	beq.s		not_right
	tst.b		alt_key(a6)
	bne.s		move_right
	sub.w		#turn_speed,Pangle
	bra.s		not_right
move_right:
	move.w		#$4000,d1
	move.w		#-player_speed,d0
	bsr		move_player
not_right:
	tst.b		forward_key(a6)
	beq.s		not_forward
	move.w		#player_speed,d0
	moveq		#0,d1
	bsr		move_player
not_forward:
	tst.b		back_key(a6)
	beq.s		not_back
	move.w		#-player_speed,d0
	moveq		#0,d1
	bsr		move_player
not_back:
	move.w		mouse_dy,d0
	beq		no_mouse_y
	neg.w		d0
	moveq		#0,d1
	bsr		move_player
	clr.w		mouse_dy
no_mouse_y:
	move.w		mouse_dx,d0
	beq		no_mouse_x
	cmp.b		#1,buttons
	bne.s		rotate
	neg.w		d0
	move.w		#$4000,d1
	bsr		move_player
	bra.s		no_mouse_x
rotate:
	move.w		mouse_dx,d0
	asl.w		#5,d0
	sub.w		d0,Pangle
no_mouse_x:
	clr.w		mouse_dx
	tst.b		plus_key(a6)
	beq.s		.nwp
	add.w		#32,window_size
	bsr		select_window
.nwp:	tst.b		minus_key(a6)
	beq.s		.nwm
	sub.w		#32,window_size
	bsr		select_window
.nwm:	tst.b		quit_key(a6)
	beq.s		.nox
	st		program_quit
.nox:	tst.b		map_key(a6)
	beq.s		.nmk
	not.b		map_enabled
.wlp:	tst.b		map_key(a6)
	bne.s		.wlp
.nmk:	rts

*-------------------------------------------------------*
* Generic movement routine -	d0 = distance		*
*				d1 = angle offset	*
*-------------------------------------------------------*
move_player:
*-------------------------------------------------------*
	move.w		d0,d2			; save distance for later 
	add.w		Pangle,d1
	lsr.w		#(16-12),d1
	muls.w		(sine.l,d1.w*2),d0
	lsl.l		#2,d0
	add.l		d0,Py
	add.w		#sinres/4,d1
	and.w		#sinres-1,d1
	muls.w		(sine.l,d1.w*2),d2
	lsl.l		#2,d2
	add.l		d2,Px
	rts

*-------------------------------------------------------*
*	Convert rotational angle into a vector		*
*-------------------------------------------------------*
triangulate:
*-------------------------------------------------------*
	move.w		Pangle,d0
	andi.l		#$ffff,d0	
	neg.l		d0
	lsr.w		#(16-12),d0
	lea		sine,a0
	move.w		(a0,d0.w*2),d1
	add.w		#sinres/4,d0
	and.w		#sinres-1,d0
	ext.l		d1
	lsl.l		#2,d1
	move.l		d1,SinPangle
	move.w		(a0,d0.w*2),d1
	ext.l		d1
	lsl.l		#2,d1
	move.l		d1,CosPangle
	rts
	
*-------------------------------------------------------*
*	Flush keyboard buffer				*
*-------------------------------------------------------*
empty_buffer:
*-------------------------------------------------------*
.bk	push.w		#11
	trap		#1
	addq		#2,sp
	tst.w		d0
	beq.s		.ot
	move.w		#7,-(sp)
	trap		#1
	addq		#2,sp
	bra.s		.bk
.ot	rts

*-------------------------------------------------------*
*	Clear all arrays for WAD parser			*
*-------------------------------------------------------*
init_wadarrays:
*-------------------------------------------------------*
	clr.l		Seg_Array
	clr.l		Side_Array
	clr.l		Line_Array
	clr.l		Node_Array
	clr.l		PNode_Array
	clr.l		Sector_Array
	clr.l		Vertex_Array
	clr.l		SSector_Array
	rts

*-------------------------------------------------------*
*	Deallocate all buffers				*
*-------------------------------------------------------*
deallocate:
*-------------------------------------------------------*
	Mfree		Thing_Array
	Mfree		Seg_Array
	Mfree		Side_Array
	Mfree		Line_Array
	Mfree		Node_Array
	Mfree		PNode_Array
	Mfree		Sector_Array
	Mfree		Vertex_Array
	Mfree		SSector_Array
	Mfree		ScreenLog
	Mfree		ScreenPhy
	Mfree		ScreenBak
	rts

*-------------------------------------------------------*
*	Program modules					*
*-------------------------------------------------------*

	include		dview_io.s
	include		levelmap.s
	include		keyboard.s
	include		screen.s
	include		engine.s

*-------------------------------------------------------*
		bss
*-------------------------------------------------------*

Px:		ds.l	1	
Py:		ds.l	1
Ph:		ds.l	1
Pangle:		ds.l	1	
CosPangle:	ds.l	1	
SinPangle:	ds.l	1	
program_quit:	ds.b	1
		even

cli:		ds.l	1

		ds.b	65536
ourstack:	ds.l	4

*-------------------------------------------------------*
bss_end:
*-------------------------------------------------------*
