
; This code is suitable for applications written for WB2.04+. It assumes that
;GadToolsBox has been used to build the GUI for this application and call the
;subroutines generated by that program to open windows.

	incdir	sys:include/
	include exec/exec.i
	include exec/exec_lib.i

	include libraries/dos.i
	include libraries/dosextens.i
	include libraries/dos_lib.i

	include graphics/gfxbase.i
	include	graphics/graphics_lib.i

	include intuition/intuition.i
	include intuition/intuition_lib.i

	include	devices/console_lib.i
	include devices/inputevent.i
	include	source:include/mmMacros.i


		include		exec/types.i
		include		intuition/classes.i
		include		intuition/classusr.i
		include		intuition/imageclass.i
		include		intuition/gadgetclass.i
		include		libraries/gadtools.i
		include		libraries/gadtools_lib.i
		include		graphics/displayinfo.i
		include		graphics/gfxbase.i

		section		Skeleton,code

		include		misc/easystart.i

_SysBase	equ		4

		lea		Variables,a5		a5->var base
	
		move.l		a0,_args(a5)		save addr of CLI args
		move.l		d0,_argslen(a5)		and the length

		bsr.s		Openlibs		open libraries
		tst.l		d0			any errors?
		beq.s		no_libs			if so quit

		bsr		Init			Initialise data
		tst.l		d0			any errors?
		beq.s		no_libs			if so quit

		bsr		Openwin			open window
		tst.l		d0			any errors?
		beq.s		no_win			if so quit

		bsr		HandleIDCMP		wait for user

no_win		bsr		Closewin		close our window

		bsr		DeInit			free resources

no_libs		bsr		Closelibs		close open libraries

		rts					finish


;**************	Open all required libraries

; Open DOS, Intuition and Graphics libraries.

; If d0=0 on return then one or more libraries are not open.

Openlibs	lea		dosname,a1		a1->lib name
		moveq.l		#0,d0			any version
		CALLEXEC	OpenLibrary		and open it
		move.l		d0,_DOSBase		save base ptr
		beq.s		.lib_error		quit if error

		lea		intname,a1		a1->lib name
		moveq.l		#0,d0			any version
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_IntuitionBase	save base ptr
		beq.s		.lib_error		quit if error

		lea		gfxname,a1		a1->lib name
		moveq.l		#0,d0			any version
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_GfxBase		save base ptr
		beq.s		.lib_error		quit if error

		lea		gadtoolsname,a1
		moveq.l		#0,d0			any version
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_GadToolsBase	save base ptr
		beq.s		.lib_error		quit if error

		lea		utilityname,a1
		moveq.l		#0,d0			any version
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_UtilityBase		save base ptr

.lib_error	rts

*************** Initialise any data

;--------------	At present just set STD_OUT and check for usage text

Init		tst.l		returnMsg		from WorkBench?
		bne.s		.ok			yes, ignore usage

		CALLDOS		Output			determine CLI handle
		move.l		d0,STD_OUT(a5)		save it for later
		beq.s		.err			quit if no handle

		move.l		_args(a5),a0		get addr of CLI args
		cmpi.b		#'?',(a0)		is the first arg a ?
		bne.s		.ok			no, skip next bit

		lea		_UsageText,a0		a0->the usage text
		bsr		DosMsg			and display it
.err		moveq.l		#0,d0			set an error
		bra.s		.error			and finish

;--------------	Your Initialisations should start here

; Initialise visual info as generated by GadToolsBox

.ok		bsr		SetupScreen		prep GadTools
		tst.l		d0
		bne.s		.error

		moveq.l		#1,d0			no errors

.error		rts					back to main

*************** Open An Intuition Window

; Opens an intuition window. If d0=0 on return then window could not be
;opened.

Openwin		bsr		OpenProject0Window
		tst.l		d0
		beq.s		.GotWin
		moveq.l		#0,d0
		bra.s		.done

; Get required pointers to speed things up a little

.GotWin		move.l		Project0Wnd,a0		   a0->win struct
		move.l		a0,win.ptr(a5)		   save window ptr
		move.l		wd_UserPort(a0),win.up(a5) save up ptr
		move.l		wd_RPort(a0),win.rp(a5)    save rp ptr

; Get signal bit for this windows message port

		move.l		win.up(a5),a0
		moveq.l		#1,d0
		moveq.l		#0,d1
		move.b		MP_SIGBIT(a0),d1
		asl.l		d1,d0
		move.l		d0,WinSigMask(a5)

; Signal no errors

		moveq.l		#1,d0			no errors

.done		rts					all done so return

*************** Deal with User interaction

; Handles Gadget, Window, Vanillakey, Refresh, Intuiticks IDCMP messages

HandleIDCMP	PUSHALL					save all but d0

.WaitLoop	move.l		WinSigMask(a5),d0	get bits
		CALLEXEC	Wait			Wait for a signal

; See if signal was from our windows user port

		move.l		WinSigMask(a5),d1	windows bit
		and.l		d0,d1			same as request?
		beq.s		.WaitLoop		nope, escape!

.IDCMPLoop	move.l		win.up(a5),a0		a0->IntuiMessage
		CALLGAD		GT_GetIMsg		wait for a message
		move.l		d0,d7			get one?
		beq.s		.WaitLoop		no, keep waiting

; We have a message, make a copy of it before replying.

		move.l		d0,a0			a0->message
		lea		IMsg(a5),a1		a1->image address
		move.l		#im_SIZEOF,d0		d0=structure size
		CALLEXEC	CopyMem			make a copy

; Now reply the message

		move.l		d7,a1			a1->Message
		CALLGAD		GT_ReplyIMsg		and answer it

; Determine what caused the message and act accordingly.

		lea		IMsg(a5),a4		a4->Message
		move.l		im_Class(a4),d2		d2 = Class
		
;--------------	Gadget Up Messages

		cmp.l		#IDCMP_GADGETUP,d2
		bne.s		.Class1
		
		moveq.l		#0,d0
		move.l		im_IAddress(a4),a0	a0->Gadget
		move.w		gg_GadgetID(a0),d0
		asl.l		#2,d0			x2 = LONG offset
		lea		.GadgetVectors(pc),a0
		move.l		(a0,d0),a0		a0->subroutine

		jsr		(a0)			call routine

		bra		.LoopEnd

;--------------	Gadget down messages

.Class1		cmp.l		#IDCMP_GADGETDOWN,d2
		bne.s		.Class2
		
		moveq.l		#0,d0
		move.l		im_IAddress(a4),a0	a0->Gadget
		move.w		gg_GadgetID(a0),d0
		asl.l		#2,d0			x2 = LONG offset
		lea		.GadgetVectors(pc),a0
		move.l		(a0,d0),a0		a0->subroutine

		jsr		(a0)			call routine

		bra		.LoopEnd

;--------------	Menu selections

.Class2		cmp.l		#IDCMP_MENUPICK,d2
		bne.s		.Class3

; The following loop will deal with multi-selected menu items!

.MenuLoop	moveq.l		#0,d0
		move.w		im_Code(a4),d0		get next item number
		beq.s		.LoopEnd		no more items

; Get address of this menu item, abort if not one!

		move.l		Project0Menus(pc),a0	a0->MenuStrip
		CALLINT		ItemAddress		get address of item
		tst.l		d0
		beq.s		.LoopEnd
		move.l		d0,a3			a0->MenuItem

; Use macro to extract the function pointer from UserData field

		GTMENUITEM_USERDATA	a3,d7		d0=function address
		
		tst.l		d7			is there a function?
		beq.s		.MenuLoopEnd		no, skip this select
		
		move.l		d7,a0

		PUSH		a3-a6
		jsr		(a0)
		PULL		a3-a6

.MenuLoopEnd	move.l		mi_NextSelect(a3),im_Code(a4)
		bra.s		.MenuLoop

;--------------	Window refresh messages

.Class3		cmp.l		#IDCMP_REFRESHWINDOW,d2
		bne.s		.Class4
		
		move.l		win.ptr(a5),a0		a0->Window
		CALLGAD		GT_BeginRefresh
		
		move.l		win.ptr(a5),a0
		moveq.l		#1,d0			TRUE, all done
		CALLSYS		GT_EndRefresh
		
		bra		.IDCMPLoop

;--------------	Intuitick messages

.Class4		cmp.l		#IDCMP_INTUITICKS,d2
		bne.s		.Class5
		
		bra.s		.LoopEnd

;--------------	Vanilla key strokes

.Class5		cmp.l		#IDCMP_VANILLAKEY,d2
		bne.s		.LoopEnd

		move.w		im_Code(a4),d0

		bra.s		.LoopEnd

;--------------	See if operator has decided to quit

		nop

.LoopEnd	cmp.l		#IDCMP_CLOSEWINDOW,d2
		bne		.IDCMPLoop
		
		lea		.QuitMsg(pc),a0
		bsr		TFReq
		tst.l		d0
		beq		.IDCMPLoop

		PULLALL

		rts

.QuitMsg	dc.b		'Sure you want to quit?',0
		even

; Gadget table currently set for gadget IDs 0 to 11. Extend/reduce accordingly

;				Subroutine	Gadgets ID

.GadgetVectors	dc.l		DoPalette	    0
		dc.l		.NoFunction	    1
		dc.l		DoQuit		    2	Quit Gadget
		dc.l		DoPalEnable	    3   Palette Check Box
		dc.l		DoName		    4
		dc.l		DoAge		    5
		dc.l		DoSex		    6
		dc.l		DoCycle		    7
		dc.l		DoLV		    8
		dc.l		DoScroll	    9
		dc.l		DoSlide		    10
		dc.l		.NoFunction	    11
		

.NoFunction	rts

;--------------	General purpose QUIT function

DoQuit		move.l		#IDCMP_CLOSEWINDOW,d2
		rts

*************** Close the Intuition window.

Closewin	bsr		CloseProject0Window

		rts

***************	Release any additional resources used

; Must free Visual Info

DeInit		bsr		CloseDownScreen

		rts

***************	Close all open libraries

; Closes any libraries the program managed to open.

Closelibs	move.l		_DOSBase,d0		d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLEXEC	CloseLibrary		close lib

		move.l		_IntuitionBase,d0	d0=base ptr	
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

		move.l		_GfxBase,d0		d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

		move.l		_GadToolsBase,d0	d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

		move.l		_UtilityBase,d0		d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

.lib_error	rts


*****************************************************************************
*			Useful Subroutines Section					    *
*****************************************************************************

**************	OK requester

; Entry		a0->text string

; Exit		none

; Corrupt	d0

OKReq		PUSHALL

		lea		.TheEasy,a1		EasyStruct
		move.l		a0,es_TextFormat(a1)	set text
		
		move.l		win.ptr(a5),a0		Window
		suba.l		a2,a2			No IDCMP
		lea		OKDStream(pc),a3	Data stream
		CALLINT		EasyRequestArgs		display it

.done		PULLALL
		rts

.TheEasy	dc.l		es_SIZEOF
		dc.l		0			no flags
		dc.l		0			title
		dc.l		0			text
		dc.l		.Gadgets

.Gadgets	dc.b		'Ok',0
		even

OKDStream	dc.l		0

**************	True/False requester

; Entry		a0->text string

; Exit		d0=result 1=true( OK ), 0=false( Cancel )

; Corrupt	d0

TFReq		PUSHALL

		lea		.TheEasy,a1		EasyStruct
		move.l		a0,es_TextFormat(a1)	set text
		
		move.l		win.ptr(a5),a0		Window
		suba.l		a2,a2			No IDCMP
		suba.l		a3,a3
		CALLINT		EasyRequestArgs		display it

.done		PULLALL
		rts

.TheEasy	dc.l		es_SIZEOF
		dc.l		0			no flags
		dc.l		0			title
		dc.l		0			text
		dc.l		.Gadgets

.Gadgets	dc.b		'Ok|Cancel',0
		even

**************	General CLI printing routine

; Entry		a0 must hold address of 0 terminated message.
;		STD_OUT should hold handle of file to be written to.
;		DOS library must be open

DosMsg		movem.l		d0-d3/a0-a3,-(sp) 	save registers

		tst.l		STD_OUT(a5)		test for open console
		beq		.error			quit if not one

		move.l		a0,a1			get a working copy

;--------------	Determine length of message

		moveq.l		#-1,d3			reset counter
.loop		addq.l		#1,d3			bump counter
		tst.b		(a1)+			is this byte a 0
		bne.s		.loop			if not loop back

;--------------	Make sure there was a message

		tst.l		d3			was there a message ?
		beq.s		.error			no, graceful exit

;--------------	Get handle of output file

		move.l		STD_OUT(a5),d1		d1=file handle
		beq.s		.error			leave if no handle

;--------------	Now print the message
;		At this point, d3 already holds length of message
;		and d1 holds the file handle.

		move.l		a0,d2			d2=address of message
		CALLDOS		Write			and print it

;--------------	All done so finish

.error		movem.l		(sp)+,d0-d3/a0-a3	restore registers
		rts

*****************************************************************************
*			Data Section					    *
*****************************************************************************

; Program revision details. Can be viewed using 'version' command.

;		dc.b		'$VER: v'
;		REVISION
;		dc.b		', © M.Meany ('
;		REVDATE
;		dc.b		')',0
;		even


dosname		dc.b		'dos.library',0
		even
intname		dc.b		'intuition.library',0
		even
gfxname		dc.b		'graphics.library',0
		even
gadtoolsname	dc.b		'gadtools.library',0
		even
utilityname	dc.b		'utility.library',0
		even

; replace the usage text below with your own particulars

_UsageText	dc.b		$0a
		dc.b		'Program v'
;		REVISION
		dc.b		', © M.Meany ('
;		REVDATE
		dc.b		')',$0a
		dc.b		'Usage details go here!',$0a,$0a,0
		even

QuitMsg		dc.b		'Sure you want to quit?',0
		even

;***********************************************************
;	SECTION	Vars,BSS
;***********************************************************

		rsreset
_args		rs.l		1
_argslen	rs.l		1

win.ptr		rs.l		1		pointer to Window
win.rp		rs.l		1		pointer to Window.RastPort
win.up		rs.l		1		pointer to Window.UserPort

WinSigMask	rs.l		1		signal mask

IMsg		rs.b		im_SIZEOF	for copy of IntuiMessage

STD_OUT		rs.l		1

varsize		rs.b		0

		SECTION	Vars,BSS

_DOSBase	ds.l		1
_IntuitionBase	ds.l		1
_GfxBase	ds.l		1
_GadToolsBase	ds.l		1
_UtilityBase	ds.l		1

Variables	ds.b		varsize

*****************************************************************************
*		Include GadToolsBox Generated Source			    *
*****************************************************************************

		section		Skeleton,code

		include		Subs.i		gadget handling code

		include		Gui.s		GadToolsBox generated
