		

	;************************************
	;*     MINESWEEPER                  *
	;************************************
	;by Andry of PEGAS
	;$VER: Source code for MineSweeper V0.76 by PEGAS (15.6.97)

	;Feel free to use this source, but give me credits AT LEAST.

V='V'
E='0'
R='.'
S='7'
I='6'
	MACHINE MC68020
	;To do:
	;	+ MinWin_Left, MinWin_Top
	;	- scale sun and numbers

	;	+ all system calls: arguments to LONG, (+) base adr. to a6!!!
	;	+ Use semaphores instead of Forbid()/Permit()
	;	+ Be sure that comparsions on addresses are unsigned!!
	;	+ Check functions for ALL possible returncodes. If possible r-codes
	;	  are A, B or C, do not assume that C if not (A or B).
	;	- Try to understand and use memory pools.
	;	- first create AppIcon (AppMenu) before closing the window (if fails...)
	;	+ LOAD/SAVE  -  if read/writebytes != expected then FAIL
	;	+ check MEMF_PUBLIC
	;	+ check return of ItemAddress

	;	- adjust preferences
	;	- u preferenci (adjust) pridelat ke "screen size" GUESS

	;	- version (.doc, $VER: , title (win/scr), about, source)
	;	- udelat z .doc .guide

		INCLUDE	"SOURCES:mines/mines.i"

TRAPRMB		MACRO
		ori.l	#WFLG_RMBTRAP,([MyWindow],wd_Flags)
		ENDM
FREERMB		MACRO
		andi.l	#~WFLG_RMBTRAP,([MyWindow],wd_Flags)
		ENDM
;*********************************************************************************
		SECTION	MineSweeper,CODE

		jmp	_IconStart
_main
		lea	(EB,PC),a0
		move.l	4.w,(a0)

		bsr.w	CallOtherSweeper	;also inits semaphore structure

	;**clear the whole bss section
		lea	BssStart,a0
		lea	BssEnd,a1
.clrbss		clr.l	(a0)+
		cmpa.l	a0,a1
		bne.s	.clrbss
		move.l	#Allocated,AllocPos

	;**Open some libraries first
		bsr.w	OpenReqTools	;open this at first!!
		beq.w	noReqTools

	;processor check (68020+)
		movea.l	(EB,PC),a6
		btst.b	#AFB_68020,(AttnFlags+1,a6)	;MC_68020?
		bne.s	.mcok			;yes
		lea	oldproc_Text,a1
		lea	oldproc_Button,a2
		bsr.w	InformationReq
		bra.w	oldProcessor
	;kickstart 3.0+ check (V39+)
.mcok		cmpi.w	#39,(LIB_VERSION,a6)
		bhs.s	.ksok
		lea	oldks_Text,a1
		lea	oldks_Button,a2
		bsr.w	InformationReq
		bra.w	oldKickstart

.ksok
		bsr.w	OpenPublicPort
		tst.l	(MinesMsgPort,pc)
		bne.s	.ppok
		lea	nopubport_Text,a1
		lea	nopubport_Button,a2
		bsr.w	InformationReq
		bra.w	noPublicPort

.ppok	;**open "timer.device"
		movea.l	(EB,PC),a6
		jsr	(_LVOCreateMsgPort,a6)		;MsgPort
		move.l	d0,TimPort
		beq.w	error_NoTimerDevice

		movea.l	d0,a0		;replyport
		move.l	#IOTV_SIZE,d0	;size
		jsr	(_LVOCreateIORequest,a6)		;IORequest
		move.l	d0,TimIoReq
		bne.s	.ioreqok
.deletemsgport	movea.l	TimPort,a0	;delete MsgPort <=> IORequest=0
		jsr	(_LVODeleteMsgPort,a6)
		bra.w	error_NoTimerDevice

.ioreqok	movea.l	d0,a1	;IORequest
		move.l	#UNIT_VBLANK,d0
		moveq	#0,d1
		lea	TimDevName,a0
		jsr	(_LVOOpenDevice,a6)		;OpenDevice
		tst.l	d0
		beq.s	.timdevok
		movea.l	TimIoReq,a0
		jsr	(_LVODeleteIORequest,a6)
		bra.s	.deletemsgport

.timdevok	movea.l	TimIoReq,a0
		move.l	(IO_DEVICE,a0),TimDevBase

.devok		bsr.w	OpenIntuition	;some libraries
		beq.w	noIntuition
		bsr.w	OpenGraphics
		beq.w	noGraphics
		bsr.w	OpenDos
		beq.w	noDos
		bsr.w	OpenGadtools
		beq.w	noGadtools
		bsr.w	OpenUtility
		beq.w	noUtility

		bsr.w	GetOutput
	;**copy default palette to screen palette
		lea	DefaultPalette,a0
		lea	ScreenPalette,a1
		moveq	#PALENTRIES*3+2-1,d0
.loop		move.l	(a0)+,(a1)+
		dbra	d0,.loop

	;**Get preferences
		bsr.w	GetStartDirs	;get lock of start directory and go there
		bsr.w	LoadPreferences
		tst.l	MyPrefs		;this MUST be valid
		beq.w	exit_noprefs
		bsr.w	LoadHiScores
		bsr.w	OpenFont	;open prefered font
		bsr.w	FontToRT	;set font to reqtools tags
iconify_Return
	;**Open screen  (If set in prefs)
		bsr.w	OpenMyScreen
		bsr.w	LockScreen
		tst.l	MyScreen
		beq.w	error_NoScreen

		bsr.w	GetDRI	;get DrawInfo
		bsr.w	SetPalette	;set colors
		bsr.w	GetButtonSizes	;get size of buttons
	;-set mimum of fields per row
		move.l	#MINBARWIDTH,d0
		divu.w	ButtWidth,d0
		bfclr	d0{0:16}
		beq.s	.noadd
		addq.w	#1,d0
.noadd		move.w	d0,MinRowBut

		bsr.w	GetVisualInfo
		tst.l	VisualInfo
		beq.w	error_NoVI
	;**create buttons gfx
		bsr.w	CreateGfx
		tst.l	MGGfx
		beq.w	error_noGfx
	;**Set window parameters
		bsr.w	GetScreenCenter
		bsr.w	SetWinParams	;due to MyPrefs
		bsr.w	SetWinTagList
		bsr.w	SetZoomParams
		bsr.w	OpenMyWindow

		tst.l	MyWindow
		beq.w	noWindow
	;**SetMenu
		bsr.w	SetMenu	;completely sets menu strip

		move.l	#IDCMPFLAGS,d0
		tst.l	MenuStruct
		beq.s	.0		;No menu
		or.l	#IDCMP_MENUPICK,d0
.0		bsr.w	ChangeIDCMP
		tst.l	([MyWindow],wd_UserPort)	;IDCMP allocated?
		bne.s	.idcmpok
		lea	noidcmp_Text,a1
		lea	noidcmp_Button,a2
		bsr.w	InformationReq
		bra.w	noIDCMP

.idcmpok	tst.b	DisplayTooBig
		beq.s	.skip2
		lea	toobig_Text,a1
		lea	toobig_Button,a2
		bsr.w	InformationReq
		clr.b	DisplayTooBig
.skip2
		bsr.w	AddGadget	;add sun gadget

		move.l	GadtoolsBase,a6
		movea.l	MyWindow,a0
		suba.l	a1,a1
		jsr	(_LVOGT_RefreshWindow,a6)	;hmmm...they tell to do this..

		bsr.w	CheckShowXmas

	;uniconifying?
		tst.b	FromIconify
		beq.s	.notic

		clr.b	FromIconify
		bsr.w	PutAllToFront
		tst.b	Play		;were you playing?
		beq.s	.nottofront	;no
		move.b	#RW_ACTUAL,d0
		bsr.w	RedrawWindow
		bsr.w	StartTimer
		bra.s	.skipinit
.notic
		tst.b	([MyPrefs],mprf_WActivate)
		bne.s	.nottofront
		movea.l	IntuiBase,a6
		movea.l	MyScreen,a0
		jsr	(_LVOScreenToFront,a6)
.nottofront
	;**alloc and init PF
		bsr.w	InitBeforeStart
		tst.l	PFAdr
		beq.w	ExitSweeper
.skipinit
		clr.b	FromIconify
;***Main loop*******************************************************
;**Don't forget the Disable,Pause flags!!!!!!!!!!

;get signal bits of both ports
		movea.l	MyWindow,a0
		movea.l	(wd_UserPort,a0),a0
		move.b	(MP_SIGBIT,a0),d0
		move.b	d0,WinPortSigBit
		moveq	#0,d1
		bset	d0,d1
		movea.l	(MinesMsgPort,pc),a0
		move.b	(MP_SIGBIT,a0),d0
		move.b	d0,PubPortSigBit
		bset	d0,d1
		move.l	d1,SignalBits

MainLoop
	;wait for signals from both ports
		movea.l	(EB,PC),a6
		move.l	SignalBits,d0
		jsr	(_LVOWait,a6)

		move.b	WinPortSigBit,d1	;wd_UserPort?
		btst	d1,d0
		bne.s	CollectLoop		;yes

	;else MineSweeper public port
.collect	movea.l	(EB,PC),a6
		movea.l	(MinesMsgPort,pc),a0
		jsr	(_LVOGetMsg,a6)
		tst.l	d0
		beq.s	MainLoop	;no more messages
		movea.l	d0,a1
		move.l	(am_ID,a1),d2
		jsr	(_LVOReplyMsg,a6)
		cmpi.l	#'MINE',d2
		bne.s	.collect
	;ok a new MineSweeper was started. That means, bring my window to front
	;and activate.
		bsr.w	PutAllToFront
		bra.s	.collect

CollectLoop
		movea.l	MyWindow,a2
		movea.l	GadtoolsBase,a6
		movea.l	(wd_UserPort,a2),a0
		jsr	(_LVOGT_GetIMsg,a6)
		tst.l	d0	;just message for gadtools?
		beq.s	MainLoop
		movea.l	d0,a1
	;**copy message to my buffer
		movea.l	d0,a0
		lea	IntuiMessBuf,a2
		moveq	#(im_SIZEOF/2)-1,d0
.loop		move.w	(a0)+,(a2)+
		dbra	d0,.loop

		jsr	(_LVOGT_ReplyIMsg,a6)	;message in A1

		lea	IntuiMessBuf,a0
		move.l	(im_Class,a0),d0	;get message

	;**Handle message in d0
		cmpi.l	#IDCMP_CHANGEWINDOW,d0
		beq.w	HandleNewSize
		tst.b	IDidTheChange		;still waiting for the window to resize?
		bne.s	CollectLoop		;yes
		cmpi.l	#IDCMP_MOUSEMOVE,d0
		beq.w	HandleMouseMove
		cmpi.l	#IDCMP_ACTIVEWINDOW,d0
		beq.w	HandleTimer
		cmpi.l	#IDCMP_INTUITICKS,d0
		beq.w	HandleTimer
		cmpi.l	#IDCMP_MOUSEBUTTONS,d0
		beq.w	HandleButtons
		cmpi.l	#IDCMP_GADGETDOWN,d0
		beq.w	HandleGadgetDown
		cmpi.l	#IDCMP_GADGETUP,d0
		beq.w	HandleGadgetUP
		cmpi.l	#IDCMP_VANILLAKEY,d0
		beq.w	HandleVanillaKeys
		cmpi.l	#IDCMP_MENUPICK,d0
		beq.w	MenuPick
		cmpi.l	#IDCMP_CLOSEWINDOW,d0
		beq.s	ExitSweeper

		bra.w	CollectLoop
;*******************************************************************
ExitSweeper
noIDCMP
		bsr.w	ClearMenu
		bsr.w	CloseMyWindow
noWindow
error_noPF
		bsr.w	FreeGfx
error_noGfx
		bsr.w	FreeVisualInfo
error_NoVI
		bsr.w	CloseMyScreen

	;check if highscores are saved
		movea.l	MyPrefs,a0
		tst.b	(mprf_Warn,a0)
		bne.s	.dontsave
		tst.b	(mhs_NewHiscore,a0)
		beq.s	.dontsave
		tst.b	(mhs_Valid,a0)
		beq.s	.dontsave
		bsr.w	mh_HiScores
.dontsave
error_NoScreen
		bsr.w	CloseFont
exit_noprefs
		bsr.w	FreeStartDir

		movea.l	(EB,PC),a6
		movea.l	UtilityBase,a1
		jsr	(_LVOCloseLibrary,a6)
noUtility	movea.l	(EB,PC),a6
		movea.l	GadtoolsBase,a1
		jsr	(_LVOCloseLibrary,a6)
noGadtools
noDos		movea.l	(EB,PC),a6
		movea.l	_GfxBase,a1
		jsr	(_LVOCloseLibrary,a6)
noGraphics	movea.l	(EB,PC),a6
		movea.l	IntuiBase,a1
		jsr	(_LVOCloseLibrary,a6)

noIntuition	movea.l	(EB,PC),a6
		movea.l	TimIoReq,a1
		jsr	(_LVOCloseDevice,a6)
		movea.l	TimIoReq,a0
		jsr	(_LVODeleteIORequest,a6)
		movea.l	TimPort,a0
		jsr	(_LVODeleteMsgPort,a6)

noTimer		bsr.w	ClosePublicPort
noPublicPort
oldKickstart
oldProcessor	movea.l	(EB,PC),a6
		movea.l	_ReqToolsBase,a1
		jsr	(_LVOCloseLibrary,a6)

noReqTools
		move.l	DosBase,d2
		beq.s	.nodos
		move.l	(MyOut,pc),d1	;get my output file
		beq.s	.noout		;exist?
		movea.l	d2,a6
		jsr	(_LVOClose,a6)	;close it
		tst.l	d0
		bne.s	.noout		;closed succesfully
		lea	notclosed_Text,a0
		bsr.w	PrintText
.noout
		movea.l	(EB,PC),a6
		movea.l	d2,a1
		jsr	(_LVOCloseLibrary,a6)
.nodos
		bsr.w	FreeAllMemory
		bsr.w	FreeSemaphore

		moveq	#0,d0
		rts

error_NoTimerDevice
		lea	notimd_Text,a1
		lea	notimd_Button,a2
		bsr.w	InformationReq
		bra.s	noTimer

;*******************************************************************
MenuPick	move.w	(im_Code,a0),d2
	;**Search for matching code
MenuSearch	cmpi.w	#MENUNULL,d2
		beq.w	mp_Exit
		st	HandleNext	;flag

		lea	MyMenu,a2
.loop		cmpi.b	#NM_END,(mmi_Type,a2)
		beq.s	mp_Exit
		cmp.w	(mmi_Code,a2),d2
		beq.s	.match
		lea	(mmi_SIZEOF,a2),a2
		bra.s	.loop
.match		move.l	(mmi_Handler,a2),d0	;check for handler
		beq.s	mp_Skip		;no handler
		movea.l	d0,a0		;is there any?
		movem.l	d2/a2,-(sp)
		jsr	(a0)		;skip to a handler
		movem.l	(sp)+,d2/a2
mp_Skip		tst.b	HandleNext
		beq.s	mp_Exit

		movea.l	IntuiBase,a6
		movea.l	MenuStruct,a0
		move.l	d2,d0
		jsr	(_LVOItemAddress,a6)
		movea.l	d0,a0

		move.w	(mi_NextSelect,a0),d2
		bra.s	MenuSearch
mp_Exit		bra.w	CollectLoop


;******************************************************************
FLAG =2
QMARK=3
HandleButtons	clr.b	SunPressedOnce	;interrupt double clicking
		movea.l	a0,a2
		tst.b	Disable
		bne.w	CollectLoop
		tst.b	Ready
		beq.w	CollectLoop
		tst.b	Pause
		bne.w	CollectLoop

		move.w	(im_Code,a2),d3
		btst	#7,d3		;just an upstroke?
		bne.w	CollectLoop	;yes

		move.w	(im_MouseX,a2),d0
		move.w	(im_MouseY,a2),d1
		sub.w	MinPFX,d0	;check range
		bmi.w	CollectLoop
		sub.w	MinPFY,d1
		bmi.w	CollectLoop
		cmp.w	PFXPix,d0
		bhs.w	CollectLoop
		cmp.w	PFYPix,d1
		bhs.w	CollectLoop

		ext.l	d0
		ext.l	d1
		divu.w	ButtWidth,d0
		divu.w	ButtHeight,d1
		addq.w	#1,d0
		addq.w	#1,d1
		move.w	d0,LastX
		move.w	d1,LastY
		move.w	d1,d2
		mulu.w	PFWidth,d2
		add.w	d0,d2		;button's offset
		movea.l	PFAdr,a0
		adda.w	PFSize,a0

		cmpi.w	#IECODE_LBUTTON,d3
		beq.s	.lmb
		cmpi.w	#IECODE_RBUTTON,d3
		beq.s	.rmb
		bra.w	CollectLoop

.rmb		movea.l	MyPrefs,a5
		tst.b	(mprf_Question,a5)	;QUESTION_MARK=YES?
		beq.s	.2	;yes
.1		cmpi.b	#FLAG,(a0,d2.w)	;flag?
		beq.s	.removef	;just remove
		bra.s	.12skip
.2		cmpi.b	#FLAG,(a0,d2.w)	;flag?
		beq.s	.question	;set qmark
		cmpi.b	#QMARK,(a0,d2.w)
		beq.s	.removeq

	;neither flag nor qmark
.12skip		tst.b	(a0,d2.w)
		beq.s	.notpressed
		tst.b	(mprf_RMouseGame,a5)	;NORMOUSEGAME?
		bne.w	.ok		;yes
		movea.l	PFAdr,a1
		tst.b	(a1,d2.w)	;pressed-empty button?
		beq.w	.ok		;yes
	;check number of flags around this PRESSED button
		movem.w	d0/d1,-(sp)
		move.w	#FLAG,d1	;item to check
		move.w	d2,d4		;offset
		move.w	PFWidth,d2
		bsr.w	GetAround
		cmp.b	(a1,d4.w),d0	;is num. of flags around equal to the number?
		movem.w	(sp)+,d0/d1
		bne.w	.ok		;no

	;now uncover all buttons around
		bra.s	.skipsub
.Uncover	;d0-x  d1-y  d2-offset
		move.w	d1,d2
		mulu.w	PFWidth,d2
		add.w	d0,d2
		movem.w	d0-d2,-(sp)
		bsr.w	ShowButton
		cmpi.b	#mgg_Bomb/4,d0
		movem.w	(sp)+,d0-d2
		bne.s	.uncok
		movea.l	PFAdr,a0
		move.b	#mgg_Blowed/4,(a0,d2.w)
		move.w	#mgg_Blowed/4,d2
		movem.w	d0/d1,-(sp)
		bsr.w	PutButton	;show the blowed immediatly
		movem.w	(sp)+,d0/d1
		move.w	#-1,(4,sp)	;set loose flag
.uncok
		rts
.skipsub	clr.w	-(sp)		;room for loose-flag
		subq.w	#1,d0		;1st line
		subq.w	#1,d1
		bsr.s	.Uncover
		addq.w	#1,d0
		bsr.s	.Uncover
		addq.w	#1,d0
		bsr.s	.Uncover

		subq.w	#2,d0		;2nd line
		addq.w	#1,d1
		bsr.s	.Uncover
		addq.w	#2,d0
		bsr.s	.Uncover

		subq.w	#2,d0		;3rd line
		addq.w	#1,d1
		bsr.s	.Uncover
		addq.w	#1,d0
		bsr.s	.Uncover
		addq.w	#1,d0
		bsr.s	.Uncover
		tst.w	(sp)+		;loose?
		beq.w	.ok0
		clr.b	Win
		bra.w	.0

.notpressed	move.b	#FLAG,(a0,d2.w)	;set a Flag
		subq.w	#1,BCount
		move.w	#mgg_Flag/4,d2
		bsr.w	PutButton
		bra.w	.ok
.question	move.b	#QMARK,(a0,d2.w)	;set qmark
		addq.w	#1,BCount
		move.w	#mgg_Question/4,d2
		bsr.w	PutButton
		bra.s	.ok
.removef	addq.w	#1,BCount
.removeq	clr.b	(a0,d2.w)
		move.w	#mgg_Empty/4,d2
		bsr.w	PutButton	;put a single button
		bra.s	.ok

.lmb		tst.b	Play
		beq.w	.NotPlayingYet
.cont		tst.b	FirstTime
		beq.s	.cont1
		clr.b	FirstTime
		movea.l	PFAdr,a1
		cmpi.b	#mgg_Bomb/4,(a1,d2.w)
		bne.s	.cont1
		bsr.w	RemoveBomb

.cont1		move.w	d2,-(sp)
		bsr.w	ShowButton
		move.w	(sp)+,d2

		cmpi.b	#mgg_Bomb/4,d0	;found a bomb?
		bne.s	.ok0
		clr.b	Win		;you loose
		movea.l	PFAdr,a0
		move.b	#mgg_Blowed/4,(a0,d2.w)
		move.w	LastX,d0
		move.w	LastY,d1
		move.w	#mgg_Blowed/4,d2
		bsr.w	PutButton
		bra.s	.0
.ok0		tst.w	WinCount
		seq	Win
		bne.s	.ok
.0		bsr.w	EndPlaying
.ok		lea	(.OldBC,pc),a0	;redraw number of bombs (if changed)
		move.w	BCount,d2
		cmp.w	(a0),d2
		beq.s	.exit
		move.w	d2,(a0)
		move.w	BCountX,d0
		move.w	BCountY,d1
		bsr.w	DrawNumber
.exit		bra.w	CollectLoop

.OldBC		dc.w	0

.NotPlayingYet	st	Play	;now playing
		TRAPRMB
		movem.w	d0-d2,-(sp)
		move.l	a0,-(sp)
		bsr.w	StartTimer
		movea.l	(sp)+,a0
		movem.w	(sp)+,d0-d2
.not		bra.w	.cont

;******************************************************************
RemoveBomb
		movem.l	a0/d0-d2/d4,-(sp)

		movea.l	PFAdr,a0
		moveq	#-1,d7
		move.w	d2,d4
		move.w	PFWidth,d2
		bsr.w	AddAround	;IN: a0-PFAdr, d2-PFWidth, d4-offset, d7- value to add
		clr.b	(a0,d4.w)
		move.w	d4,-(sp)

		move.w	MaxRandRange,d0
		bsr.w	Rand
		movea.l	SeedFillStack,a0	;contains offsets of free buttons
		move.w	(a0,d0.w*2),d4
		move.w	PFWidth,d2
		movea.l	PFAdr,a0
		moveq	#1,d7
		bsr.w	AddAround
		move.b	#mgg_Bomb/4,(a0,d4.w)

		move.w	(sp)+,d4
		move.w	#mgg_Bomb/4,d1
		bsr.w	GetAround	;   ""    ,OUT: d0-number of bombs around
		move.b	d0,(a0,d4.w)

		movem.l	(sp)+,a0/d0-d2/d4
		rts
;******************************************************************
HandleMouseMove	tst.b	Play
		beq.s	.exit
		tst.b	Disable
		bne.s	.exit
		tst.b	Pause
		bne.s	.exit
		move.w	(im_MouseX,a0),d0
		move.w	(im_MouseY,a0),d1
		sub.w	MinPFX,d0	;check range
		bmi.w	.out
		sub.w	MinPFY,d1
		bmi.w	.out
		cmp.w	PFXPix,d0
		bhs.s	.out
		cmp.w	PFYPix,d1
		bhs.s	.out
	;in
		TRAPRMB
		bra.w	CollectLoop
.out		FREERMB
.exit		bra.w	CollectLoop
;******************************************************************
HandleGadgetDown	;double-clicking on the sun gadget means iconify
		lea	(.time,pc),a2
		tst.b	SunPressedOnce	;is this the first time?
		bne.s	.testdouble	;no
		st	SunPressedOnce
		move.l	(im_Seconds,a0),(a2)	;save time of this event
		move.l	(im_Micros,a0),4(a2)
		bra.w	CollectLoop

.testdouble	clr.b	SunPressedOnce
		move.l	(a2),d0		;start seconds
		move.l	4(a2),d1	;      micros
		move.l	(im_Seconds,a0),d2	;current secs.
		move.l	(im_Micros,a0),d3	;current micros
		movea.l	IntuiBase,a6
		jsr	(_LVODoubleClick,a6)	;double clicked?
		tst.l	d0
		beq.w	CollectLoop		;no

		subq.l	#8,a7	;to be compatible with MenuPick
		bsr.w	mh_Iconify
		addq.l	#8,a7
		bra.w	CollectLoop
.time		dc.l	0,0
;******************************************************************
HandleGadgetUP	bsr.w	InitBeforeStart
		tst.l	PFAdr
		beq.w	ExitSweeper
		bra.w	CollectLoop
;******************************************************************
ESC	=	27
HandleVanillaKeys
		move.w	(im_Code,a0),d2
		move.w	(im_Qualifier,a0),d3
		pea	(.exit,pc)	;!!!!!!!!!!!!!!!!!!!!!!!!!

		move.b	d2,d0
		bsr.w	uppercaseD0
		btst	#IEQUALIFIERB_LCOMMAND,d3
		bne.s	.lramiga
		btst	#IEQUALIFIERB_RCOMMAND,d3
		bne.s	.lramiga

		cmpi.b	#'H',d0
		beq.s	mh_HiScores
		cmpi.b	#ESC,d2
		beq.s	vk_Exit
		cmpi.b	#'*',d0
		beq.w	vk_Iconify

		cmpi.b	#'P',d0		;set/break pause
		beq.s	vk_Pause
		cmpi.b	#' ',d2		;SPACE=START
		beq.s	.start
		addq.l	#4,sp		;(.exit,pc)
.exit		bra.w	CollectLoop

.start		bsr.w	InitBeforeStart
		tst.l	PFAdr
		bne.s	.ok
		addq.l	#4,sp
		bra.w	ExitSweeper
.ok		rts

.lramiga
	;test level change
		cmpi.b	#'1',d0
		blo.s	.no
		cmpi.b	#'5',d0
		bhi.s	.no
		subi.b	#'0',d0
		bsr.w	NewLevelNoMenu
		rts

.no		cmpi.b	#'H',d0
		beq.w	mh_HiScores
		cmpi.b	#'Q',d0
		beq.s	vk_Exit
		cmpi.b	#'?',d0
		beq.s	vk_About
		cmpi.b	#'I',d0
		beq.w	vk_Iconify
		cmpi.b	#'A',d0
		beq.w	vk_AdjustPrefs
		cmpi.b	#'W',d0
		beq.w	mh_SavePrefs

		cmpi.b	#'S',d0
		beq.s	.start
		cmpi.b	#'P',d0
		beq.s	vk_Pause	;set/break pause
		rts

vk_Iconify	subq.l	#4,sp		;to be compatible (see "Menu handlers")
		bsr.w	mh_Iconify
		addq.l	#4,sp
		rts
vk_AdjustPrefs	subq.l	#4,sp		;to be compatible (see "Menu handlers")
		bsr.w	mh_AdjustPrefs
		addq.l	#4,sp
		rts


vk_Exit		addq.l	#4,sp
		bra.w	ExitSweeper
vk_About	bsr.w	mh_About
		rts
;-----------------------------------------------------
vk_Pause	movea.l	MyWindow,a0
		movea.l	IntuiBase,a6
		jsr	(_LVOZipWindow,a6)
		rts
;------------------------------------
pause_Make	FREERMB
		bsr.w	StopTimer
		st	Pause
		move.b	([MyPrefs],mprf_Level),PausedLevel
	;set titles
		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		move.w	(wd_LeftEdge,a0),([MyPrefs],mprf_ZoomLeft)	;set prefs.
		move.w	(wd_TopEdge,a0),([MyPrefs],mprf_ZoomTop)

		move.l	#-1,a1
		lea	(.pausetitle,pc),a2
		jsr	(_LVOSetWindowTitles,a6)

		rts
.pausetitle	dc.b	'MineSweeper - Paused',0
		cnop	0,4

pause_Cont	clr.b	Pause
	;set titles
		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		lea	MyWinTitle,a1
		lea	MyWinScrTitle,a2
		jsr	(_LVOSetWindowTitles,a6)

		move.b	([MyPrefs],mprf_Level),d0
		cmp.b	PausedLevel,d0
		beq.s	.nochange
		bra.w	NewLevel	;rts

.nochange	tst.b	Disable
		bne.s	.exit
		tst.b	Play
		bne.s	.playing
		bsr.w	InitBeforeStart
		tst.l	PFAdr
		bne.s	.ok
		addq.l	#4,sp
		bra.w	ExitSweeper
.ok		rts

.playing	TRAPRMB
		move.b	#RW_ACTUAL,d0
		bsr.w	RedrawWindow
		bsr.w	StartTimer
.exit		rts
;******************************************************************
PutAllToFront	movea.l	IntuiBase,a6
		movea.l	MyScreen,a0
		jsr	(_LVOScreenToFront,a6)
		movea.l	MyWindow,a2
		movea.l	a2,a0
		jsr	(_LVOWindowToFront,a6)
		movea.l	a2,a0
		jsr	(_LVOActivateWindow,a6)
		rts
;******************************************************************
StartTimer	tst.b	Pause
		bne.s	.exit
		movea.l	TimDevBase,a6
		lea	OldSysTime,a0
		jsr	(_LVOGetSysTime,a6)	;set start point
		st	TimerGo
.exit		rts


ClearTimer	clr.l	MyTime
		clr.l	EndTime
		clr.l	EndTime+4
		movea.l	MyPrefs,a0
		tst.b	(mprf_CountDown,a0)
		beq.s	.zero

		move.b	(mprf_Level,a0),d0
		subq.b	#1,d0
		ext.w	d0
		move.w	(mhs_BestTimes,a0,d0.w*4),d0
		move.w	d0,MyTime+2
.zero		clr.l	MyTime+4	;no rts here!
;--------
StopTimer	clr.b	TimerGo
		rts

HandleTimer	tst.b	TimerGo
		beq.s	.ht_exit
	;get current sys time
		movea.l	TimDevBase,a6
		lea	SysTime,a0
		jsr	(_LVOGetSysTime,a6)	;a0 is unchanged
		movem.l	(a0),d4/d5	;store
		lea	OldSysTime,a1
		jsr	(_LVOSubTime,a6)	;new-old => new
		movem.l	d4/d5,(a1)	;write to OldSysTime
		movea.l	a0,a1
		movea.l	a0,a3		;store
		lea	MyTime,a0

		tst.b	([MyPrefs],mprf_CountDown)
		beq.s	.up
		jsr	(_LVOSubTime,a6)
		bra.s	.skip
.up		jsr	(_LVOAddTime,a6)	;add diference to my timer
.skip
		movea.l	a3,a1
		lea	EndTime,a0
		jsr	(_LVOAddTime,a6)

		bsr.w	RedrawTime

		cmpi.l	#MAXTIME,EndTime	;do you play too long?
		blt.s	.no

		clr.b	Win
		bsr.w	EndPlaying
		lea	toolong_Text,a1
		lea	toolong_Button,a2
		bsr.w	InformationReq
.no
.ht_exit	bra.w	CollectLoop

;******************************************************************
RedrawTime	move.w	TimeX,d0
		move.w	TimeY,d1
		move.w	MyTime+TV_SECS+2,d2
		lea	(OldSec,pc),a0		;time changed?
		cmp.w	(a0),d2
		beq.s	.exit
		move.w	d2,(a0)
		bsr.s	DrawNumber
.exit		rts

OldSec		dc.w	0
;******************************************************************
DrawNumber	;IN: d2.w- number
		;    d0.w-x d1.w-y

MINUS	=	10
		ext.l	d0
		ext.l	d1
		movem.l	d0/d1,-(sp)
		bsr.s	Num2String04	;IN:d2-num;OUT:a2-string

		movea.l	MyWindow,a3
		movea.l	(wd_RPort,a3),a3
	;**draw bevelled box
		movea.l	GadtoolsBase,a6
		movem.l	(sp),d0/d1
		movea.l	a3,a0
		move.l	#NUMBBOXX,d2
		move.l	#NUMBBOXY,d3
		lea	dbb_TagList2,a1
		jsr	(_LVODrawBevelBoxA,a6)
	;**draw number
		movem.l	(sp)+,d0/d1
		movea.l	IntuiBase,a6
		movea.l	a2,a0
		addq.l	#NUMX,d0
		addq.l	#NUMY,d1
		moveq	#4-1,d7	;draw 4 digits
.digitloop	move.b	(a0)+,d6
		subi.b	#'0',d6		;get offset
		bpl.s	.ok
		move.b	#MINUS,d6
.ok		ext.w	d6
		mulu.w	#NUMPLANESIZE*2,d6
		addi.l	#rawNumbers,d6
		lea	img_Number,a1
		move.l	d6,(ig_ImageData,a1)	;img
		movem.l	d0/d1/a0,-(sp)
		movea.l	a3,a0			;rp
		jsr	(_LVODrawImage,a6)
		movem.l	(sp)+,d0/d1/a0
		addi.w	#NUMNEXT,d0
		dbra	d7,.digitloop
		rts

;******************************************************************
	;**convert number in d2 to a string
Num2String04	;IN:d2.w - number;OUT:a2 - ptr to string
		lea	(numfstring04,pc),a2
		bra.s	ns_Go	;rts
Num2String4	lea	(numfstring4,pc),a2

ns_Go		movem.l	d0/d1/a0/a1/a3/a6,-(sp)
		lea	(dstream,pc),a1 ;data stream
		move.w	d2,(a1)
		movea.l	a2,a0	;format string
		lea	(numostring,pc),a3	;output string
		lea	(hChar,pc),a2
		movea.l	(EB,PC),a6
		jsr	(_LVORawDoFmt,a6)	;returns ptr. to end of data stream
						;(which I don't need..)
		movem.l	(sp)+,d0/d1/a0/a1/a3/a6
		lea	(numostring,pc),a2
		rts

hChar		move.b	d0,(a3)+
		rts

dstream		dc.w	0
numfstring04	dc.b	'%04.d',0
numfstring4	dc.b	'%4.d',0
numostring	dcb.b	6,0

		cnop	0,4
Num2StringDec	;IN:d0-number.l
		;OUT:a0-ptr to string
		lea	(fstringdec,pc),a0
		bra.s	nsdh_Go
Num2StringHex	lea	(fstringhex,pc),a0

nsdh_Go		movem.l	d1-d7/a1-a6,-(sp)
		lea	(.dstream,pc),a1 ;data stream
		move.l	d0,(a1)
		lea	(.numostring,pc),a3	;output string
		clr.l	(a3)			;clear the string
		clr.l	4(a3)
		clr.l	8(a3)
		lea	(hChar,pc),a2
		movea.l	(EB,PC),a6
		jsr	(_LVORawDoFmt,a6)
		movem.l	(sp)+,d1-d7/a1-a6
		lea	(.numostring,pc),a0
		rts

.dstream	dc.l	0
.numostring	dcb.b	4*3,0
fstringdec	dc.b	'%lu',0	;long, unsigned decimal
fstringhex	dc.b	'0x%08.lx',0
		cnop	0,4
;******************************************************************
HandleNewSize	tst.b	DisplayTooBig
		beq.s	.skip
		lea	toobig_Text,a1
		lea	toobig_Button,a2
		bsr.w	InformationReq
		clr.b	DisplayTooBig
.skip
	;**Changed size or just moved?
		movea.l	MyWindow,a0	;check unexpected sizing
		move.w	WinWidth,d0
		cmp.w	(wd_Width,a0),d0
		bne.w	hns_unexp
		move.w	WinHeight,d0
		cmp.w	(wd_Height,a0),d0
		bne.w	hns_unexp

		tst.b	Pause	;was the window shrinked?
		beq.s	setWinPos	;no
		bsr.w	pause_Cont
		bra.w	CollectLoop

setWinPos	;**set new position to MyPrefs
		movea.l	MyWindow,a1
	;refresh values
		move.w	(wd_Width,a1),d0
		move.w	(wd_Height,a1),d1
		move.w	d0,WinWidth
		move.w	d1,WinHeight
		moveq	#0,d2
		move.b	(wd_BorderLeft,a1),d2
		sub.w	d2,d0
		move.b	(wd_BorderRight,a1),d2
		sub.w	d2,d0
		move.b	(wd_BorderTop,a1),d2
		sub.w	d2,d1
		move.b	(wd_BorderBottom,a1),d2
		sub.w	d2,d1
		move.w	d0,InnWidth
		move.w	d1,InnHeight

		move.w	(wd_LeftEdge,a1),d0
		move.w	(wd_TopEdge,a1),d1
		movea.l	MyPrefs,a0
		tst.b	(mprf_CenterWindow,a0)
		beq.s	.yes
		move.w	d0,(mprf_WinX,a0)
		move.w	d1,(mprf_WinY,a0)
.yes		move.w	d0,WinX
		move.w	d1,WinY
	;**now redraw and accept new level
		tst.b	IDidTheChange	;Me or user? (new level or moved?)
		bne.s	.newlevel

	;moved => set new center
		move.w	WinWidth,d0
		asr.w	#1,d0
		add.w	WinX,d0
		move.w	d0,CenterPointX
		move.w	WinHeight,d0
		asr.w	#1,d0
		add.w	WinY,d0
		move.w	d0,CenterPointY
		bra.s	.skip

.newlevel	bsr.w	InitBeforeStart
		tst.l	PFAdr
		beq.w	ExitSweeper

.skip		clr.b	IDidTheChange
		bra.w	CollectLoop

hns_unexp	;Size is not the same as requested by ChangeWindowBox
		tst.b	IDidTheChange	;just low memory (or something...)?
		bne.s	.ok
	;**check if the window was zoomed
		move.w	ZoomWidth,d0
		cmp.w	(wd_Width,a0),d0
		bne.s	.unexp
		move.w	ZoomHeight,d0
		cmp.w	(wd_Height,a0),d0
		bne.s	.unexp
	;yes, the window was just zoomed
		bsr.w	pause_Make
		bra.w	CollectLoop

.unexp		lea	changed_Text,a1	;or some stranger...?
		lea	changed_Button,a2
		bsr.w	InformationReq
		st	Disable
		bra.w	setWinPos

.ok		lea	unexp_Text,a1
		lea	unexp_Button,a2
		bsr.w	InformationReq
		move.b	LastLevel,d0
		bsr.w	NewLevelNoMenu
		clr.b	IDidTheChange
		bra.w	CollectLoop
;************************************************************************
CheckShowXmas
	;--get current year
		bsr.s	GetCurrDate
		lea	CurrDate,a0
		move.w	(year,a0),d0

		cmp.w	LastXmas,d0	;new year?
		shi	TestXmas
		rts
;************************************************************************
CheckXmas	;check for xmas
		tst.b	TestXmas
		beq.s	.no
		bsr.s	GetCurrDate
		lea	CurrDate,a0
		cmpi.w	#24,(mday,a0)
		bne.s	.no
		cmpi.w	#12,(month,a0)
		bne.s	.no

		move.w	(year,a0),LastXmas
		lea	xmas_Text,a1
		lea	xmas_Button,a2
		bsr.w	InformationReq
		clr.b	TestXmas	;don't show anymore
		st	([MyPrefs],mhs_NewHiscore)
.no		rts
;************************************************************************
GetCurrDate	movea.l	IntuiBase,a6
		lea	Ctime,a0	;secs
		lea	(4,a0),a1	;micros
		jsr	(_LVOCurrentTime,a6)

		movea.l	UtilityBase,a6
		move.l	(a0),d0		;get curr. secs.
		lea	CurrDate,a0	;structure to fill
		jsr	(_LVOAmiga2Date,a6)	;get current date
		rts
;************************************************************************
InitBeforeStart	tst.b	Pause
		bne.s	.exit
		FREERMB
		bsr.w	ClearTimer
		move.w	PFBombs,BCount
		move.l	#img_Sun,Gadget_Image
		move.b	#RW_START,d0
		bsr.w	RedrawWindow

		move.w	MyTime+2,StartTime	;save real start time
		tst.b	([MyPrefs],mprf_CountDown)
		beq.s	.ok
		addq.w	#1,MyTime+2
.ok
		st	Ready
		bsr.w	InitPF
		clr.b	Play
		clr.b	Win
		st	FirstTime

	;set num. of buttons to press to win
		move.w	PFSize,d0
		sub.w	PFBombs,d0
		sub.w	PFWidth,d0
		sub.w	PFWidth,d0
		sub.w	PFHeight,d0
		sub.w	PFHeight,d0
		addq.w	#4,d0
		move.w	d0,WinCount

		bsr.w	CheckXmas
.exit		rts

;-------------------------------------------
EndPlaying	bsr.w	StopTimer
		clr.b	Play
		clr.b	Ready
		FREERMB

	;fix a silly bug with timer
		tst.b	([MyPrefs],mprf_CountDown)
		beq.s	.nobug
		move.w	StartTime,d0
		cmp.w	MyTime+2,d0
		bge.s	.nobug
		move.w	d0,MyTime+2

.nobug		tst.b	Win
		beq.s	.00
		move.l	#img_SunWon,Gadget_Image
		bra.s	.11
.00		move.l	#img_SunLoose,Gadget_Image
.11
		move.b	#RW_END,d0
		bsr.w	RedrawWindow

		tst.b	Win
		beq.s	.0

		move.w	EndTime+2,d2
		bsr.s	CheckForScore	;IN:d2.w-time
.0		rts
;************************************************************************
CheckForScore	movea.l	MyPrefs,a0
		lea	(mhs_BestTimes,a0),a1
		lea	(mhs_BestNames,a0),a2
		move.b	(mprf_Level,a0),d0
		subq.b	#1,d0
		ext.w	d0
		pea	(.ret,pc)
		cmp.w	(a1,d0.w*4),d2
		blo.s	.setscore1
		cmp.w	(2,a1,d0.w*4),d2
		blo.s	.setscore2
		addq.l	#4,sp
.ret
		rts		;you were not good enough!

.setscore1
		cmpi.b	#LCUSTOM-1,d0
		bne.s	.cont0
		move.w	(mhs_CustomWidth1,a0),(mhs_CustomWidth2,a0)
		move.w	(mhs_CustomHeight1,a0),(mhs_CustomHeight2,a0)
		move.w	(mhs_CustomBombs1,a0),(mhs_CustomBombs2,a0)
		move.w	PFWidth,d3
		subq.w	#2,d3
		move.w	d3,(mhs_CustomWidth1,a0)
		move.w	PFHeight,d3
		subq.w	#2,d3
		move.w	d3,(mhs_CustomHeight1,a0)
		move.w	PFBombs,(mhs_CustomBombs1,a0)
.cont0		move.w	(a1,d0.w*4),d1	;shift scores
		move.w	d2,(a1,d0.w*4)
		move.w	d1,(2,a1,d0.w*4)

		mulu.w	#NAMELEN*2,d0	;shift names
		lea	(a2,d0.w),a2	;new1
		lea	(NAMELEN,a2),a0	;old2
		movea.l	a2,a1
.cp0		move.b	(a1)+,(a0)+
		bne.s	.cp0
		bra.s	.setname

.setscore2	cmpi.b	#LCUSTOM-1,d0
		bne.s	.cont1
		move.w	PFWidth,d3
		subq.w	#2,d3
		move.w	d3,(mhs_CustomWidth2,a0)
		move.w	PFHeight,d3
		subq.w	#2,d3
		move.w	d3,(mhs_CustomHeight2,a0)
		move.w	PFBombs,(mhs_CustomBombs2,a0)
.cont1		move.w	d2,(2,a1,d0.w*4)
		mulu.w	#NAMELEN*2,d0
		lea	(NAMELEN,a2,d0.w),a2

.setname	movea.l	a2,a5	;store
	;**get players name
		movea.l	_ReqToolsBase,a6
		moveq	#NAMELEN-1,d0	;max. name len
		lea	NameBuffer,a1
		lea	(entertext_Title,pc),a2
		suba.l	a3,a3
		lea	GSReqTags,a0	;tags
		jsr	(_LVOrtGetStringA,a6)
		tst.l	d0
		bne.s	.gotit
		lea	(AnonymousPlayer,pc),a0
		bra.s	.cp1
.gotit		lea	NameBuffer,a0
.cp1		move.b	(a0)+,(a5)+
		bne.s	.cp1
		st	([MyPrefs],mhs_NewHiscore)
		clr.b	ValidHSText
		bsr.w	mh_HiScores
		rts

AnonymousPlayer	dc.b	'anonym  :( ',0
entertext_Title	dc.b	'Hi-score',0
		cnop	0,4
;************************************************************************
;*******Menu handlers****************************************************
;************************************************************************
; warning: (sp) contains LONG,LONG,LONG -> 12 bytes  (see mh_quit)
; a2 contains MyMenuItem addr. , d2-im_Code

mh_Level	movea.l	IntuiBase,a6
		movea.l	MenuStruct,a0
		move.l	d2,d0
		ext.l	d0	;to be sure
		jsr	(_LVOItemAddress,a6)
		movea.l	d0,a0

		move.w	(mi_Flags,a0),d0	;get flags
		andi.w	#CHECKED,d0		;zero or CHECKED
		beq.s	mhl_exit

		lea	LevelItems,a1
		move.l	a2,d0
		sub.l	a1,d0
		divu.w	#mmi_SIZEOF,d0
		addq.b	#1,d0		;d0 contains level number

NewLevel	;IN:d0-mprf_Level
		movea.l	MyPrefs,a0
		move.b	(mprf_Level,a0),LastLevel
		move.b	d0,(mprf_Level,a0)
		tst.b	Pause
		bne.s	mhl_exit
		clr.b	Disable
		clr.b	HandleNext
		bsr.w	ResizeWindow
mhl_exit	rts

NewLevelNoMenu	;IN:d0-mprf_Level
		;changes checkmark in menu
		move.b	d0,d6	;store

	;clear old checkmark
		movea.l	MyPrefs,a2
		lea	LevelItems,a3
		move.b	(mprf_Level,a2),d0
		subq.b	#1,d0
		ext.w	d0
		mulu.w	#mmi_SIZEOF,d0
		move.w	(mmi_Code,a3,d0.w),d0

		movea.l	MenuStruct,a0
		ext.l	d0	;to be sure
		movea.l	IntuiBase,a6
		jsr	(_LVOItemAddress,a6)
		movea.l	d0,a0
		andi.w	#~CHECKED,(mi_Flags,a0)	;clear checkmark
	;set new checkmark
		move.b	d6,d0
		subq.b	#1,d0
		ext.w	d0
		mulu.w	#mmi_SIZEOF,d0
		move.w	(mmi_Code,a3,d0.w),d0

		movea.l	MenuStruct,a0
		ext.l	d0	;to be sure
		jsr	(_LVOItemAddress,a6)
		movea.l	d0,a0
		ori.w	#CHECKED,(mi_Flags,a0)	;set checkmark
		move.b	d6,d0
		bra.s	NewLevel

;************************************************************************
mh_About	lea	about_Text,a1
		lea	about_Button,a2
		lea	AboutTags,a0
		suba.l	a3,a3
		suba.l	a4,a4
		movea.l	_ReqToolsBase,a6
		jsr	(_LVOrtEZRequestA,a6)	;I don't care about the results
		rts
;************************************************************************
mh_Start	bsr.w	InitBeforeStart
		tst.l	PFAdr
		beq.s	mh_Quit
		rts
;************************************************************************
mh_Pause	bra.w	vk_Pause	;rts
;************************************************************************
mh_Quit		lea	(12,sp),sp	;rts,a2,d2
		bra.w	ExitSweeper
;*****************************************************************
mh_HiScores	tst.b	ValidHSText
		bne.s	.show
		bsr.w	MakeHighScores
		st	ValidHSText
.show
		movea.l	MyPrefs,a0
		tst.b	(mhs_NewHiscore,a0)
		beq.s	.dontsave
		tst.b	(mhs_Valid,a0)
		beq.s	.dontsave

		lea	HiScoresButtonSave,a2
		bsr.s	.disphsc
		tst.l	d0
		beq.s	.skipsaving
		bsr.w	SaveHiScores
.skipsaving	rts

.dontsave	lea	HiScoresButton,a2
.disphsc	lea	HiScoresText,a1
		lea	HiScoresTags,a0
		suba.l	a3,a3
		suba.l	a4,a4
		movea.l	_ReqToolsBase,a6
		jsr	(_LVOrtEZRequestA,a6)
		rts

;*****************************************************************
mh_SaveScores	bsr.w	SaveHiScores
		rts
;*****************************************************************
mh_ClearCustom
		lea	surec_Text,a1
		lea	surec_Button,a2
		bsr.w	InformationReq
		tst.l	d0
		beq.s	.exit
		clr.b	ValidHSText
		movea.l	MyPrefs,a0
		st	(mhs_NewHiscore,a0)
		clr.b	(mhs_CustomName1,a0)
		clr.b	(mhs_CustomName2,a0)
		move.w	#MAXTIME,(mhs_CustomTime1,a0)
		move.w	#MAXTIME,(mhs_CustomTime2,a0)
		lea	(mhs_CustomInfo,a0),a0
		moveq	#(mhs_CIEnd-mhs_CustomInfo)/2-1,d0
.clr		clr.w	(a0)+
		dbra	d0,.clr
		bsr.s	mh_HiScores
.exit		rts
;*****************************************************************
mh_ClearAll	lea	surea_Text,a1
		lea	surea_Button,a2
		bsr.w	InformationReq
		tst.l	d0
		beq.s	.exit
		clr.b	ValidHSText
		movea.l	MyPrefs,a0
		bsr.w	ClearHighScores
		bsr.w	mh_HiScores
.exit		rts
;*****************************************************************
mh_AdjustPrefs	rts
;*****************************************************************
newToolTypes	dc.l	0
nosavemem_Text	dc.b	'Not enough memory',0
nosavemem_Button dc.b	'I see..',0
notsaved_Text	dc.b	'Preferences couldn',39,'t be saved',0
notsaved_Button	dc.b	'I see..',0
		cnop	0,4
;-----------------------------------------
SEGMENTSIZE	= TOOLTYPEITEMS*40
mh_SavePrefs
	;alloc. mem for tool types array
		move.l	#SEGMENTSIZE,d7		;d7-allocated size

mhsp_TryAgain	;to this label jumps EndOfSpace
		move.l	d7,d6
		move.l	d7,d0			;d6-couter
		move.l	#MEMF_PUBLIC,d1
		bsr.w	ADDALLOC

		lea	(newToolTypes,pc),a0
		move.l	d0,(a0)
		beq.w	sp_nomem

		movea.l	(newToolTypes,pc),a2
		lea	((TOOLTYPEITEMS+1)*4,a2),a3	;skip pointers
		subi.l	#(TOOLTYPEITEMS+1)*4,d6
		movea.l	MyPrefs,a5
		lea	PrefItems,a0

.sp_loop	tst.l	(a0)	;end?
		beq.s	.done
		movea.l	(mpi_PItemName,a0),a4
		movea.l	(mpi_SaveHandler,a0),a1
		move.l	a3,(a2)+	;save text pointer

	;now create text of the tool type
		move.l	a0,-(sp)
		jsr	(a1)	;IN:a3-tt_text a4-prefitem text, a5-MyPrefs
		movea.l	(sp)+,a0

		lea	(mpi_SIZEOF,a0),a0
		bra.s	.sp_loop
.done
		clr.l	(a2)		;end of array of CHAR *
	;*get tool types
		movea.l	(EB,PC),a6
		lea	(IconName,pc),a1
		moveq	#MinIconVer,d0
		jsr	(_LVOOpenLibrary,a6)	;"icon.library" V36
		lea	(IconBase,pc),a0
		move.l	d0,(a0)
		beq.s	.noiconlib

		lea	ProgramName,a0
		movea.l	(IconBase,pc),a6
		jsr	(_LVOGetDiskObjectNew,a6)	;get "mines.info" or something
		lea	(diskObj,pc),a0
		move.l	d0,(a0)
		beq.s	.closelib		;shouldn't happen...
		movea.l	d0,a1
		movea.l	(newToolTypes,pc),(do_ToolTypes,a1)	;set ToolTypes array
		lea	ProgramName,a0
		jsr	(_LVOPutDiskObject,a6)		;and save it to icon
		tst.l	d0
		beq.s	.errorsaving

.freeobj	movea.l	(diskObj,pc),a0
		jsr	(_LVOFreeDiskObject,a6)
.closelib	move.l	(EB,PC),a6
		movea.l	(IconBase,pc),a1
		jsr	(_LVOCloseLibrary,a6)
.freemem	movea.l	(newToolTypes,pc),a1
		bsr.w	FreeMemBlock

		rts			;exit this section
;--------------------
.errorsaving	lea	(notsaved_Text,pc),a1
		lea	(notsaved_Button,pc),a2
		bsr.w	InformationReq
		bra.s	.freeobj

.noiconlib	lea	(noicon_Text,pc),a1	;see LoadPreferences
		lea	(noicon_Button,pc),a2
		bsr.w	InformationReq
		bra.s	.freemem

sp_nomem	lea	(nosavemem_Text,pc),a1
		lea	(nosavemem_Button,pc),a2
		bsr.w	InformationReq
		rts
;-------------------------------------------------------------
;this piece of code allocates new block of memory, when the old is too small
EndOfSpace
		movea.l	(newToolTypes,pc),a1
		bsr.w	FreeMemBlock	;free old buffer
	;try to allocate more space
		addi.l	#SEGMENTSIZE,d7
		lea	(12,a7),a7	;rts_tt_Write,rts_sp_Sub,movea.l (sp)+,a0
		bra.w	mhsp_TryAgain
;-------------------------------------------------------------
tt_Write	;Copies text from (a4) to (a3) without the zero byte.
		;Checks if there is enough free memory for this operation.

		;IN: a4-source text  a3-destination buffer (d6-counter)
.cp		subq.l	#1,d6
		bmi.w	EndOfSpace
		move.b	(a4)+,(a3)+
		bne.s	.cp
		subq.l	#1,a3	;delete the zero byte
		addq.l	#1,d6
		rts

tt_WriteEqual	;writes "=" to (a3)
		lea	(eqchar,pc),a4
		bra.s	tt_Write	;don't use "bsr"
					;tt_Write would be 3rd iteration (must be 2nd)!
eqchar		dc.b	'=',0
		cnop	0,4
tt_WriteZero	;writes zero byte and subcrements d6(counter).
		;Checking for memory was already done by tt_Write.
		;Only call this routine once after some tt_Write(s).
		clr.b	(a3)+
		subq.l	#1,d6
		rts
;-------------------------------------------------------------
;Save preferences handlers
;IN: a3-tt_text  a4-prefitem text  a5-MyPrefs
;OUT: d0 - 0=OK else ERROR
;   changes also a3
;in case of error is all memory free (I mean newToolTypes)

TOBRACKETS	MACRO	;closes switch to brackets (e.G.  (WBLIKE)  )
			;IN:a4-switch text
		movea.l	a4,a0		;store
		lea	(lbrack,pc),a4	;left bracket
		bsr.w	tt_Write
		movea.l	a0,a4		;restore
		bsr.w	tt_Write
		lea	(rbrack,pc),a4	;right bracket
		bsr.w	tt_Write
		ENDM
lbrack		dc.b	'(',0
rbrack		dc.b	')',0
		cnop	0,4

WRITESWITCH	MACRO	;IN:mprf_(Switch)
		tst.b	(\1,a5)	;switch specified?
		bne.s	.yes
		TOBRACKETS
		bra.s	.exit
.yes		bsr.w	tt_Write
.exit		bra.w	tt_WriteZero	;rts
		ENDM

WRITESTRUCTVAL	MACRO	;IN: e.G.  MyScreen, sc_Width, w  (word)
		bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		moveq	#0,d0
		move.\3	([\1],\2),d0
		bsr.w	Num2StringDec
		movea.l	a0,a4
		bsr.w	tt_Write
		bra.w	tt_WriteZero
		ENDM

sp_PubScreen	bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.l	(mprf_PubNameAdr,a5),d0	;any PubScreen name?
		bne.s	.nameok			;yes
		lea	(nopubname,pc),a4
		bra.s	.skp
.nameok		movea.l	d0,a4
.skp		bsr.w	tt_Write
		bra.w	tt_WriteZero	;rts
nopubname	dc.b	'<Name>',0
		cnop	0,4
;--------------------------------------
sp_CustomScreen	WRITESWITCH	mprf_CustomScreen
;--------------------------------------
sp_NotCenter	WRITESWITCH	mprf_CenterWindow
;--------------------------------------
sp_NotActiv	WRITESWITCH	mprf_WActivate
;--------------------------------------
sp_NoQuest	WRITESWITCH	mprf_Question
;--------------------------------------
sp_DeadQ	WRITESWITCH	mprf_DeadQ
;--------------------------------------
sp_CountD	WRITESWITCH	mprf_CountDown
;--------------------------------------
sp_NoRMouse	WRITESWITCH	mprf_RMouseGame
;--------------------------------------
sp_WBLike	WRITESWITCH	mprf_WBLike
;--------------------------------------
sp_Warn		WRITESWITCH	mprf_Warn
;--------------------------------------
sp_Scale	WRITESWITCH	mprf_ScaleGfx
;--------------------------------------
sp_ModeID	bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.l	(mprf_ModeID,a5),d0
		bsr.w	Num2StringHex	;IN:d0-number.l, OUT:a0-string
		movea.l	a0,a4
		bsr.w	tt_Write
		bra.w	tt_WriteZero
;--------------------------------------
sp_SizeX	WRITESTRUCTVAL	MyScreen,sc_Width,w
;--------------------------------------
sp_SizeY	WRITESTRUCTVAL	MyScreen,sc_Height,w
;--------------------------------------
sp_WinX		WRITESTRUCTVAL	MyPrefs,mprf_WinX,w
;--------------------------------------
sp_WinY		WRITESTRUCTVAL	MyPrefs,mprf_WinY,w
;--------------------------------------
sp_ZoomX	WRITESTRUCTVAL	MyPrefs,mprf_ZoomLeft,w
;--------------------------------------
sp_ZoomY	WRITESTRUCTVAL	MyPrefs,mprf_ZoomTop,w
;--------------------------------------
sp_Level	bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.b	(mprf_Level,a5),d0
		subq.b	#1,d0
		ext.w	d0
		movea.l	(.levTable,pc,d0.w*4),a4	;get level name
		bsr.w	tt_Write
		bra.w	tt_WriteZero

.levTable	dc.l	ttEASY,ttMEDIUM,ttHARD,ttPROFI,ttCUSTOM
;--------------------------------------
sp_Iconify	bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.b	(mprf_Iconify,a5),d0
		ext.w	d0
		movea.l	(.icTable,pc,d0.w*4),a4
		bsr.w	tt_Write
		bra.w	tt_WriteZero

.icTable	dc.l	iconIcon,iconMenu
;--------------------------------------
sp_CusWid	WRITESTRUCTVAL	MyPrefs,mprf_CustomWidth,w
;--------------------------------------
sp_CusHei	WRITESTRUCTVAL	MyPrefs,mprf_CustomHeight,w
;--------------------------------------
sp_CusBom	WRITESTRUCTVAL	MyPrefs,mprf_CustomBombs,w
;--------------------------------------
sp_Font		bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.l	(mprf_FontName,a5),d0
		beq.s	.default
		movea.l	d0,a4
		bra.s	.skp
.default	lea	(defaultText,pc),a4
.skp		bsr.w	tt_Write
		bra.w	tt_WriteZero
;--------------------------------------
sp_FontSize	bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.w	(mprf_FontSize,a5),d0
		bne.s	.ok
	;zero font size means DESIGNED font
		lea	(designedText,pc),a4
		bra.s	.skip
.ok		ext.l	d0
		bsr.w	Num2StringDec
		movea.l	a0,a4
.skip		bsr.w	tt_Write
		bra.w	tt_WriteZero

;--------------------------------------
sp_Palette	bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.b	(mprf_PaletteType,a5),d0
		beq.s	.colortable
		subq.b	#1,d0
		ext.w	d0
		movea.l	(.paltypes,pc,d0.w*4),a4
		bsr.w	tt_Write
.exit		bra.w	tt_WriteZero

.colortable	lea	ScreenPalette+4,a1
		move.b	#PALENTRIES,d2

.ctloop		moveq	#0,d0
		move.b	(3,a1),d1	;RED
		bfins	d1,d0{8:8}
		move.b	(7,a1),d1	;GREEN
		bfins	d1,d0{16:8}
		move.b	(11,a1),d1	;BLUE
		bfins	d1,d0{24:8}
		bsr.w	Num2StringHex
		movea.l	a0,a4
		bsr.w	tt_Write
		lea	(3*4,a1),a1
		subq.b	#1,d2
		beq.s	.exit
		lea	(.comma,pc),a4
		bsr.w	tt_Write
		bra.s	.ctloop

.paltypes	dc.l	ptStandard,ptMagicWB,ptWBLike
.comma		dc.b	',',0
		cnop	0,4

;--------------------------------------
sp_GfxType	bsr.w	tt_Write
		bsr.w	tt_WriteEqual
		move.b	(mprf_GfxType,a5),d0
		ext.w	d0
		movea.l	(.gtype,pc,d0.w*4),a4
		bsr.w	tt_Write
		bra.w	tt_WriteZero

.gtype		dc.l	gfxStandard,gfxMagicWB
;*****************************************************************
mh_JoinScores
		clr.w	LastXmas
	;alloc JoinPrefsBuf
		move.l	#prf_SIZEOF,d0
		moveq	#0,d1
		bsr.w	ADDALLOC
		move.l	d0,JoinPrefsBuf
		beq.w	fatalerror

	;alloc file requester
		movea.l	_ReqToolsBase,a6
		move.l	#RT_FILEREQ,d0
		suba.l	a0,a0	;no tags
		jsr	(_LVOrtAllocRequestA,a6)
		move.l	d0,JoinRequester
		beq.w	norequester

	;get files to join
		movea.l	d0,a1
		lea	JoinFilename,a2
		lea	JoinGetTitle,a3
		lea	JoinGetTags,a0
		jsr	(_LVOrtFileRequestA,a6)
		move.l	d0,JoinFileList
		beq.w	.nofilelist
	;change dir
		movea.l	JoinRequester,a0

		movea.l	DosBase,a6
		move.l	(rtfi_Dir,a0),d1
		move.l	#ACCESS_READ,d2
		jsr	(_LVOLock,a6)
		move.l	d0,JoinDirLock	;store the lock
		move.l	d0,d1
		jsr	(_LVOCurrentDir,a6)
		move.l	d0,JoinOldDir

;------------------------------------------------------
		movea.l	JoinFileList,a3	;filelist
		lea	(join_errors,pc),a0
		clr.b	(a0)
.ex
		move.l	(rtfl_Name,a3),d0
		bsr.w	LOAD_FILE	;IN:d0-filename  ;OUT: d0-adr. or 0 ;d1- len
		tst.l	d0
		beq.s	.nosuchfile
		lea	(fb,pc),a0	;store buffer
		move.l	d0,(a0)

		bfclr	d1{0:16}
		bne.s	.nohiscores	;too big to be hiscore file
		subq.w	#1,d1		;file lenght
		bmi.s	.nohiscores	;empty file
		movea.l	d0,a5
		movea.l	JoinPrefsBuf,a4
		bsr.w	GetMHS		;extract the data
		tst.l	d0
		bne.s	.nohiscores
		bsr.w	Join2Scores
		st	([MyPrefs],mhs_NewHiscore)
		clr.b	ValidHSText
	;free file buffer
.freefile	movea.l	(fb,pc),a1
		bsr.w	FreeMemBlock

.next		tst.l	(a3)		;rtfl_Next
		beq.s	.done		;all examined?
		movea.l	(a3),a3		;Next
		bra.s	.ex

.nosuchfile	lea	(join_errors,pc),a0
		st	(a0)
		lea	(examine_Text,pc),a0
		bsr.w	PrintText
		move.l	(rtfl_Name,a3),a0
		bsr.w	PrintText
		lea	(ERRNOFILE,pc),a0
		bsr.w	PrintText
		bra.s	.next
.nohiscores	lea	(join_errors,pc),a0
		st	(a0)
		lea	(examine_Text,pc),a0
		bsr.w	PrintText
		move.l	(rtfl_Name,a3),a0
		bsr.w	PrintText
		lea	(ERRNOSCORES,pc),a0
		bsr.w	PrintText
		bra.s	.freefile
;-------------------------------------------
.done		movea.l	_ReqToolsBase,a6
		movea.l	JoinFileList,a0
		jsr	(_LVOrtFreeFileList,a6)

		movea.l	DosBase,a6
		move.l	JoinDirLock,d1
		jsr	(_LVOUnLock,a6)

		move.l	JoinOldDir,d1
		jsr	(_LVOCurrentDir,a6)

.nofilelist	movea.l	_ReqToolsBase,a6
		movea.l	JoinRequester,a1
		jsr	(_LVOrtFreeRequest,a6)

		movea.l	JoinPrefsBuf,a1
		bsr.w	FreeMemBlock

		tst.b	(join_errors,pc)
		beq.s	.noerr
		lea	(joinerr_Text,pc),a1
		lea	(joinerr_Button,pc),a2
		bsr.w	InformationReq
.noerr		bsr.w	mh_HiScores
		rts

norequester
fatalerror	lea	(jnm_Text,pc),a1
		lea	(jnm_Button,pc),a2
		bsr.w	InformationReq
		rts

ERRNOFILE	dc.b	9,'   ** no such file.',10,0
ERRNOSCORES	dc.b	9,'   ** not a Hi-Score file.',10,0

examine_Text	dc.b	'File: ',0
jnm_Text	dc.b	'Not enough memory.',0
jnm_Button	dc.b	'Continue',0
joinerr_Text	dc.b	'Some errors occured.',10
		dc.b	'See MineSweeper output window.',0
joinerr_Button	dc.b	'OK',0
join_errors	dc.b	0		;BOOL
		cnop	0,4

;----------------------------------------------------------------
COMPARE		MACRO
		move.w	(mhs_\1Time1,a0),d0	;loaded time
		lea	(mhs_\1Name1,a0),a2
		bsr.s	.check\@
		move.w	(mhs_\1Time2,a0),d0
		lea	(mhs_\1Name2,a0),a2
		pea	(.exit\@,pc)
.check\@	cmp.w	(mhs_\1Time1,a1),d0	;destination hiscores
		bhs.s	.try2nd\@
	;insert d0,a2 to first place
		movem.l	d0/a2,-(sp)
		move.w	(mhs_\1Time1,a1),d0
		lea	(mhs_\1Name1,a1),a2
		bsr.s	.set2nd\@
		movem.l	(sp)+,d0/a2
		move.w	d0,(mhs_\1Time1,a1)
		lea	(mhs_\1Name1,a1),a3
		bra.s	.cpname\@

.try2nd\@	cmp.w	(mhs_\1Time2,a1),d0
		bhs.s	.trynext\@
	;set d0,a2 to second place
.set2nd\@	move.w	d0,(mhs_\1Time2,a1)
		lea	(mhs_\1Name2,a1),a3
.cpname\@	moveq	#NAMELEN-1,d0
.cp\@		move.b	(a2)+,(a3)+		;set new name
		dbra	d0,.cp\@

.trynext\@	rts
.exit\@
		ENDM

Join2Scores	movem.l	a0-a3,-(sp)
		movea.l	JoinPrefsBuf,a0
		movea.l	MyPrefs,a1
		COMPARE	Easy
		COMPARE	Normal
		COMPARE	Hard
		COMPARE	Profi
	;now handle custom levels

	;check 1st sour match 1st dest
	;  yes
	;    better 1st sour 1st dest
	;         yes
	;            copy 1st dest to 2nd dest
	;            copy 1st sour to 1st dest
	;            exit
	;         no
	;  no

	; check2nd

	;    check 1st sour match 2nd dest
	;      yes
	;         better 1st sour 2nd dest
	;           yes
	;              copy 1st sour to 2nd dest
	;              exit
	;           no
	;      no
	;  repeat all for 2nd sour
	; exit

;--------------------------------------------------
CHECKBETTER	MACRO	;IN: sour pos., dest pos.
			;OUT: Zero<=>True else false
	;check \1 sour match \2 dest
		move.w	(mhs_CustomWidth\2,a1),d0
		beq.s	.matched\@	;no custom defined yet
		cmp.w	(mhs_CustomWidth\1,a0),d0
		bne.s	.nomatchcb\@
		move.w	(mhs_CustomHeight\1,a0),d0
		cmp.w	(mhs_CustomHeight\2,a1),d0
		bne.s	.nomatchcb\@
		move.w	(mhs_CustomBombs\1,a0),d0
		cmp.w	(mhs_CustomBombs\2,a1),d0
		bne.s	.nomatchcb\@
.matched\@
	;    better \1 sour than \2 dest?
		move.w	(mhs_CustomTime\1,a0),d0
		cmp.w	(mhs_CustomTime\2,a1),d0
		bhs.s	.nomatchcb\@
		moveq	#0,d0
		bra.s	.exit\@
.nomatchcb\@	moveq	#-1,d0
.exit\@
		ENDM
;--------------------------------------------------
COPY		MACRO	;IN: 1|2, sour data , 1|2, dest data
		move.w	mhs_CustomTime\1(\2),mhs_CustomTime\3(\4)
		move.w	mhs_CustomWidth\1(\2),mhs_CustomWidth\3(\4)
		move.w	mhs_CustomHeight\1(\2),mhs_CustomHeight\3(\4)
		move.w	mhs_CustomBombs\1(\2),mhs_CustomBombs\3(\4)
		movea.l	\2,a2	;store regs
		movea.l	\4,a3
	;copy the name
		lea	(mhs_CustomName\1,a2),a2
		lea	(mhs_CustomName\3,a3),a3
.cp\@		move.b	(a2)+,(a3)+
		bne.s	.cp\@
		ENDM
;--------------------------------------------------
DOCUSTOM	MACRO	;IN:  1|2 for 1st|2nd
		CHECKBETTER	\1,1
		bne.s	.check2nd\@
	;matched		
		COPY	\1,a1,2,a1	;works also with 2nd to 2nd
		COPY	\1,a0,\1,a1	;        - "" -
		bra.w	.exitcust
.check2nd\@	CHECKBETTER	\1,2
		bne.s	.nomatch\@
		COPY	\1,a0,2,a1
		bra.w	.exitcust
.nomatch\@
		ENDM
;--------------------------------------------------
		DOCUSTOM 1
		DOCUSTOM 2	;bra.s	.exitcust
		moveq	#0,d0	;just bytes
.exitcust
		movem.l	(sp)+,a0-a3
		rts

;*****************************************************************
noWBLib_text	dc.b	'"workbench.library" V36+ required to iconify.',0
noWBLib_button	dc.b	'I see..',0
cantic_Text	dc.b	'Couldn',39,'t iconify.',0
cantic_Button	dc.b	'Continue',0
WBLibName	dc.b	'workbench.library',0
errunic_Text	dc.b	'Couldn',39,'t uniconify correctly.',10
		dc.b	'Some memory may be wasted.',0
errunic_Button	dc.b	'I see.',0

MinesMenuName
MinesPortName	dc.b	'MineSweeper',0

		cnop	0,4
WBLibBase	dc.l	0
MinesMsgPort	dc.l	0
MinesAppMenuItem dc.l	0

mh_Iconify
	;open "workbench.library"
		movea.l	(EB,PC),a6
		lea	(WBLibName,pc),a1
		moveq	#MinWBVer,d0
		jsr	(_LVOOpenLibrary,a6)
		lea	(WBLibBase,pc),a0
		move.l	d0,(a0)
		bne.s	.ok
		lea	(noWBLib_text,pc),a1
		lea	(noWBLib_button,pc),a2
		bsr.w	InformationReq
		rts
.ok
		bsr.w	StopTimer
	;set actual window size and position to tag list
	;close the window
		bsr.w	ClearMenu
		bsr.w	CloseMyWindow
		clr.l	OldIDCMP
	;close the screen
		bsr.w	FreeGfx
		bsr.w	FreeVisualInfo
		bsr.w	CloseMyScreen	;also frees draw info

		pea	(.ret,pc)
		movea.l	MyPrefs,a0
		cmpi.b	#ICON_ICON,(mprf_Iconify,a0)
		beq.w	ic_AppIcon
		bra.w	ic_AppMenu
.ret		tst.l	d0
		bne.s	.iccont
		lea	(cantic_Text,pc),a1
		lea	(cantic_Button,pc),a2
		bsr.w	InformationReq
		bra.s	.skipwaitport
;-----------------------------------
;Now wait for a message either from another MineSweeper (that's why it
;must be a public port)
;or from AppMenu
;-----------------------------------
.iccont
		movea.l	(EB,PC),a6
		movea.l	(MinesMsgPort,pc),a3	;msgport
.waitloop	movea.l	a3,a0
		jsr	(_LVOWaitPort,a6)
.collectall	movea.l	a3,a0
		jsr	(_LVOGetMsg,a6)
		tst.l	d0
		beq.s	.waitloop	;no more messages

		movea.l	d0,a1
		move.l	(am_ID,a1),d6
.notmine	jsr	(_LVOReplyMsg,a6)
		cmpi.l	#'MINE',d6	;message from another MineSweeper,
					;or from appmenu-window-icon?
		bne.s	.collectall	;unknown

		movea.l	Semaphore,a0
		jsr	(_LVOObtainSemaphore,a6)
	;collect rest of possible messages
.getall		movea.l	a3,a0
		jsr	(_LVOGetMsg,a6)
		tst.l	d0
		bne.s	.getall

		pea	(.ret2,pc)
		movea.l	MyPrefs,a0
		cmpi.b	#ICON_ICON,(mprf_Iconify,a0)
		beq.w	ic_RemAppIcon
		bra.w	ic_RemAppMenu
.ret2
		tst.l	d0	;ret. code from ic_RemApp....
		bne.s	.ok1	;currently always TRUE (V39)
		lea	(errunic_Text,pc),a1
		lea	(errunic_Button,pc),a2
		bsr.w	InformationReq

.ok1		movea.l	(EB,PC),a6
		movea.l	Semaphore,a0
		jsr	(_LVOReleaseSemaphore,a6)
.skipwaitport

ic_ret		movea.l	(EB,PC),a6
		movea.l	(WBLibBase,pc),a1
		jsr	(_LVOCloseLibrary,a6)

		st	FromIconify
		lea	(12,sp),sp	;rts,a2,d2
		clr.b	Pause
		bra.w	iconify_Return

;----------------------------------------------------------
ic_AppIcon	;*get icon
		movea.l	(EB,PC),a6
		lea	(IconName,pc),a1
		moveq	#MinIconVer,d0
		jsr	(_LVOOpenLibrary,a6)	;"icon.library" V36
		lea	(IconBase,pc),a0
		move.l	d0,(a0)
		beq.s	.noiconlib

		lea	ProgramName,a0
		movea.l	(IconBase,pc),a6
		jsr	(_LVOGetDiskObjectNew,a6)	;get "mines.info" or something
		lea	(diskObj,pc),a0
		move.l	d0,(a0)
		beq.s	.closelib		;shouldn't happen...

		movea.l	(WBLibBase,pc),a6
		move.l	#'MINE',d0	;id
		moveq	#0,d1		;userdata
		lea	(ic_Name,pc),a0
		movea.l	(MinesMsgPort,pc),a1	;msgport
		suba.l	a2,a2		;lock
		movea.l	(diskObj,pc),a3	;object
		suba.l	a4,a4		;taglist
		jsr	(_LVOAddAppIconA,a6)
		lea	(AppIconPtr,pc),a0
		move.l	d0,(a0)

		move.l	d0,d2		;store ret. code (0=fail)
		movea.l	(IconBase,pc),a6
		movea.l	(diskObj,pc),a0
		jsr	(_LVOFreeDiskObject,a6)
		move.l	d2,d0
.closelib	move.l	d0,-(sp)	;store return code
		movea.l	(EB,PC),a6
		movea.l	(IconBase,pc),a1
		jsr	(_LVOCloseLibrary,a6)
		move.l	(sp)+,d0
		rts
.noiconlib	moveq	#0,d0
		rts

AppIconPtr	dc.l	0
ic_Name		dc.b	'MineSweeper',0
		cnop	0,4
;-----------------------------------------------
ic_RemAppIcon	movea.l	(WBLibBase,pc),a6
		movea.l	(AppIconPtr,pc),a0
		jsr	(_LVORemoveAppIcon,a6)
		rts
;----------------------------------------------------------
ic_AppMenu	;OUT: d0 - 0=fail
;Add MineSweeper to AppMenu******
		movea.l	(WBLibBase,pc),a6
		move.l	#'MINE',d0	;id
		moveq	#0,d1		;userdata
		lea	(MinesMenuName,pc),a0	;menu text
		movea.l	(MinesMsgPort,pc),a1	;msgport
		suba.l	a2,a2			;taglist
		jsr	(_LVOAddAppMenuItemA,a6)
		lea	(MinesAppMenuItem,pc),a0
		move.l	d0,(a0)
		rts
;-----------------------------------------------
ic_RemAppMenu	;now remove me from AppMenu
		movea.l	(WBLibBase,pc),a6
		movea.l	(MinesAppMenuItem,pc),a0
		jsr	(_LVORemoveAppMenuItem,a6)	;as far as I know,
		rts					;the result is always TRUE
;*****************************************************************
OpenPublicPort
	;create msg port
		movea.l	(EB,PC),a6
		jsr	(_LVOCreateMsgPort,a6)
		lea	(MinesMsgPort,pc),a0
		move.l	d0,(a0)
		beq.s	.ret
		movea.l	d0,a1
		move.b	#1,(LN_PRI,a1)	;priority=1
		lea	(MinesPortName,pc),a0
		move.l	a0,(LN_NAME,a1)
		jsr	(_LVOAddPort,a6) ;make it public (IN: a1-port OUT: NIL)
.ret		rts
ClosePublicPort
	;remove port from public list
		movea.l	(EB,PC),a6
		movea.l	(MinesMsgPort,pc),a3	;msgport
		movea.l	a3,a1
		jsr	(_LVORemPort,a6)	;IN: a1-port OUT:NIL
		movea.l	a3,a0
		jsr	(_LVODeleteMsgPort,a6)	;IN:a0-port OUT:NIL
		rts
;*****************************************************************
;**Open libraries and/or display errors.
OpenReqTools	movea.l	(EB,PC),a6		;This must be called at first!
		moveq	#MinReqToolsVer,d0
		lea	ReqToolsName,a1	;"reqtools.library"
		jsr	(_LVOOpenLibrary,a6)
		move.l	d0,_ReqToolsBase
		bne.s	.exit
		bsr.s	OpenDos
		beq.s	.exit		;no dos.library (!?)
		lea	noreq_Text,a0
		bsr.w	PrintText
		moveq	#0,d0		;set zero flag
.exit		rts

OpenIntuition	movea.l	(EB,PC),a6		;open "intuition.library"
		moveq	#MinIntuiVer,d0
		lea	IntuiName,a1
		jsr	(_LVOOpenLibrary,a6)
		move.l	d0,IntuiBase
		bne.s	.exit
		lea	nointui_Text,a1
		lea	nointui_Button,a2
		bsr.w	InformationReq
		moveq	#0,d0
.exit		rts

OpenGraphics	movea.l	(EB,PC),a6		;open "graphics.library"
		moveq	#MinGfxVer,d0
		lea	GfxName,a1
		jsr	(_LVOOpenLibrary,a6)
		move.l	d0,_GfxBase
		bne.s	.exit
		lea	nogfx_Text,a1
		lea	nogfx_Button,a2
		bsr.w	InformationReq
		moveq	#0,d0
.exit		rts

OpenDos		movea.l	(EB,PC),a6		;"dos.library"
		moveq	#MinDosVer,d0
		lea	DosName,a1
		jsr	(_LVOOpenLibrary,a6)
		move.l	d0,DosBase
		bne.s	.exit
		lea	nodos_Text,a1
		lea	nodos_Button,a2
		bsr.w	InformationReq
		moveq	#0,d0
.exit		rts

OpenGadtools	movea.l	(EB,PC),a6		;"gadtools.library"
		moveq	#MinGadToolsVer,d0
		lea	GadtoolsName,a1
		jsr	(_LVOOpenLibrary,a6)
		move.l	d0,GadtoolsBase
		bne.s	.exit
		lea	nogad_Text,a1
		lea	nogad_Button,a2
		bsr.w	InformationReq
		moveq	#0,d0
.exit		rts

OpenUtility	movea.l	(EB,PC),a6		;open "utility.library"
		moveq	#MinUtilityVer,d0
		lea	UtilityName,a1
		jsr	(_LVOOpenLibrary,a6)
		move.l	d0,UtilityBase
		bne.s	.exit
		lea	noutility_Text,a1
		lea	noutility_Button,a2
		bsr.w	InformationReq
		moveq	#0,d0
.exit		rts

;**********************************************************
GetStartDirs	clr.l	OldDirectory
		movea.l	DosBase,a6
		move.l	WBmessage,d0	;from WB?
		beq.s	.cli
	;WB version
		movea.l	d0,a0
		movea.l	(sm_ArgList,a0),a0
		movea.l	(wa_Name,a0),a1
		lea	ProgramName,a2
.cp		move.b	(a1)+,(a2)+
		bne.s	.cp
		move.l	(wa_Lock,a0),d1
		move.l	d1,ProgDir
.cd		jsr	(_LVOCurrentDir,a6)
		move.l	d0,OldDirectory
		rts

	;*cli version
.cli		move.l	#ProgramName,d1
		move.l	#PROGNAMELEN,d2
		jsr	(_LVOGetProgramName,a6)
		tst.l	d0
		beq.s	.setmyname
.getdir		jsr	(_LVOGetProgramDir,a6)
		move.l	d0,ProgDir
		rts

.setmyname	lea	(defaultName,pc),a0
		lea	ProgramName,a1
.cp1		move.b	(a0)+,(a1)+
		bne.s	.cp1
		bra.s	.getdir

defaultName	dc.b	'Mines',0
		cnop	0,4
;------------------------------------------------------
FreeStartDir	move.l	OldDirectory,d1
		beq.s	.exit
		movea.l	DosBase,a6
		jsr	(_LVOCurrentDir,a6)
.exit		rts
;**********************************************************
GetOutput	;IN:DosBase
		;out: d0=output
		movem.l	d1/d2/a0/a1/a6,-(sp)
		lea	(myOutput,pc),a6
		move.l	a6,d1
		move.l	#MODE_NEWFILE,d2
		movea.l	DosBase,a6
		jsr	(_LVOOpen,a6)
		lea	(MyOut,pc),a0
		move.l	d0,(a0)
		movem.l	(sp)+,d1/d2/a0/a1/a6
		rts
myOutput	dc.b	'CON://600/150/MineSweeper output window/CLOSE/AUTO/SIMPLE/INACTIVE/WAIT',0
		cnop	0,4
MyOut		dc.l	0
;**********************************************************
PrintText	;IN: a0-null terminated string
		movem.l	d0-d3/a0/a1/a6,-(sp)
		movea.l	DosBase,a6
		move.l	(MyOut,pc),d1		;identif. vystupu
		bne.s	.ok
		bsr.s	GetOutput
		move.l	d0,d1
		beq.s	.exit
.ok		moveq	#0,d3		;lenght
		move.l	a0,d2
.1		tst.b	(a0)+
		beq.s	.endtext
		addq.l	#1,d3
		bra.s	.1
.endtext	jsr	(_LVOWrite,a6)	;I don't care about the result
.exit		movem.l	(sp)+,d0-d3/a0/a1/a6
		rts
;*****************************************************************
InitPF		;Two fields are allocated:
		;1. numbers, bombs, empty gadgets, noflags
		;2. 0 - empty gadget
		;   1 - pressed gadgets
		;   2 - flag

		move.l	PFAdr,d1
		beq.s	.nopf
		move.w	PFWidth,d0
		mulu.w	PFHeight,d0
		cmp.w	PFSize,d0
		beq.s	.allocated
	;first free last PF
		movea.l	d1,a1
		bsr.w	FreeMemBlock
.nopf
	;alloc new
		move.w	PFWidth,d0
		mulu.w	PFHeight,d0
		move.l	d0,d1		;check the size (max 65535)
		andi.l	#$ffff0000,d1
		bne.w	.ipf_toobig

		move.w	d0,PFSize
		ext.l	d0
		move.l	d0,d2		;store
		add.l	d0,d0		;allocate 2 fields
		moveq	#0,d1
		bsr.w	ADDALLOC
		move.l	d0,PFAdr
		beq.w	.ipf_error

	;alloc buffer for seedfill
		move.l	SeedFillStack,d0
		beq.s	.noyet
		movea.l	d0,a1
		bsr.w	FreeMemBlock
.noyet		move.w	PFWidth,d0
		mulu.w	PFHeight,d0
		mulu.w	#12,d0		;12 bytes per button
		addi.l	#24,d0		;to be sure
		move.l	d0,d6	;store
		moveq	#0,d1
		bsr.w	ADDALLOC
		move.l	d0,SeedFillStack
		beq.w	.ipf_error
		add.l	d6,d0	;end of the area
		move.l	d0,SeedFillSP	;ptr to the stack

	;**fill it with values
.allocated	;first clear both fields
		movea.l	PFAdr,a0
		move.w	PFSize,d0
		add.w	d0,d0		;both
		subq.w	#1,d0
.clr		clr.b	(a0)+
		dbra	d0,.clr
	;**bombs
		movea.l	IntuiBase,a0
		move.l	(ib_Micros,a0),RndSeed

	;use SeedFillStack to generate random values
		movea.l	SeedFillStack,a0

		move.w	PFWidth,d3
		move.w	PFHeight,d4
		subq.w	#1,d3
		subq.w	#1,d4
		moveq	#1,d1		;start for y
.yloop		moveq	#1,d0		;start for x
.xloop		move.w	d1,d2		;position in the PF
		mulu.w	PFWidth,d2
		add.w	d0,d2
		move.w	d2,(a0)+
		addq.w	#1,d0		;next x
		cmp.w	d3,d0		;PFWidth-1
		bne.s	.xloop
		addq.w	#1,d1		;next y
		cmp.w	d4,d1		;PFHeight-1
		bne.s	.yloop

		movea.l	PFAdr,a0
		movea.l	SeedFillStack,a1
		move.w	PFBombs,d7
		subq.w	#1,d7
		move.w	PFWidth,d0
		move.w	PFHeight,d3
		subq.w	#2,d0
		subq.w	#2,d3
		mulu.w	d0,d3		;range for Rand
		subq.w	#1,d3

.next
		move.w	d3,d0		;range
		addq.w	#1,d0
		bsr.w	Rand
		move.w	(a1,d0.w*2),d1	;get PF pos. of the bomb
		move.w	(a1,d3.w*2),(a1,d0.w*2)	;and move last item to current
		move.b	#mgg_Bomb/4,(a0,d1.w)
		subq.w	#1,d3		;decrease range
		dbra	d7,.next
		addq.w	#1,d3
		move.w	d3,MaxRandRange
	;**numbers
		movea.l	PFAdr,a0
		moveq	#1,d1		;ypos
		move.w	PFWidth,d2	;maxx
		move.w	PFHeight,d3	;maxy
.looplines	moveq	#1,d0		;xpos
.loopcolumns	move.w	d1,d4
		mulu.w	d2,d4
		add.w	d0,d4
		cmpi.b	#mgg_Bomb/4,(a0,d4.w)
		bne.s	.no
		moveq	#1,d7
		bsr.w	AddAround

.no		addq.w	#1,d0		;next column
		cmp.w	d2,d0
		bne.s	.loopcolumns
		addq.w	#1,d1		;next line
		cmp.w	d3,d1
		bne.w	.looplines
	;fill the border to range an area for seedfill
		movea.l	PFAdr,a0
		adda.w	PFSize,a0
		movea.l	a0,a1
		move.w	PFWidth,d0
		move.w	d0,d1
		mulu.w	PFHeight,d1
		adda.w	d1,a1
		suba.w	d0,a1
		subq.w	#1,d0
.fb1		move.b	#1,(a0)+
		move.b	#1,(a1)+
		dbra	d0,.fb1
		movea.l	PFAdr,a0
		adda.w	PFSize,a0
		move.b	#1,(a0)	;first line, first col.
		move.w	PFWidth,d0
		subq.w	#1,d0
		adda.w	d0,a0
		addq.w	#1,d0
		move.w	PFHeight,d1
		subq.w	#2,d1
.fb2		move.b	#1,(a0)	;prev. line, last col.
		move.b	#1,(1,a0)	;next line, first col.
		adda.w	d0,a0
		dbra	d1,.fb2
		move.b	#1,(a0)		;last line, last col.
		rts

.ipf_error	lea	nopf_Text,a1
		lea	nopf_Button,a2
		bsr.w	InformationReq
		rts
.ipf_toobig	lea	pfbig_Text,a1
		lea	pfbig_Button,a2
		bsr.w	InformationReq
		clr.l	PFAdr
		rts
;*****************************************************************
	;increase all free items next to this
AddAround	;IN: a0-PFAdr, d2-PFWidth, d4-offset, d7- value to add
		move.w	d4,-(sp)
		cmpi.b	#mgg_Bomb/4,(-1,a0,d4.w)
		beq.s	.0
		add.b	d7,(-1,a0,d4.w)	;l

.0		cmpi.b	#mgg_Bomb/4,(1,a0,d4.w)
		beq.s	.1
		add.b	d7,(1,a0,d4.w)	;r

.1		sub.w	d2,d4

		cmpi.b	#mgg_Bomb/4,(a0,d4.w)
		beq.s	.2
		add.b	d7,(a0,d4.w)	;u
.2		cmpi.b	#mgg_Bomb/4,(-1,a0,d4.w)
		beq.s	.3
		add.b	d7,(-1,a0,d4.w)	;ul
.3		cmpi.b	#mgg_Bomb/4,(1,a0,d4.w)
		beq.s	.4
		add.b	d7,(1,a0,d4.w)	;ur

.4		add.w	d2,d4
		add.w	d2,d4

		cmpi.b	#mgg_Bomb/4,(a0,d4.w)
		beq.s	.5
		add.b	d7,(a0,d4.w)	;d
.5		cmpi.b	#mgg_Bomb/4,(-1,a0,d4.w)
		beq.s	.6
		add.b	d7,(-1,a0,d4.w)	;dl
.6		cmpi.b	#mgg_Bomb/4,(1,a0,d4.w)
		beq.s	.7
		add.b	d7,(1,a0,d4.w)	;dr
.7		move.w	(sp)+,d4
		rts
;*****************************************************************
	;get num. of items around
GetAround	;IN: a0-PFAdr, d1-num. to check, d2-PFWidth, d4-offset
		;OUT: d0-num.
		move.w	d4,-(sp)
		clr.b	d0
		cmp.b	(-1,a0,d4.w),d1
		bne.s	.0
		addq.b	#1,d0	;l

.0		cmp.b	(1,a0,d4.w),d1
		bne.s	.1
		addq.b	#1,d0	;r

.1		sub.w	d2,d4

		cmp.b	(a0,d4.w),d1
		bne.s	.2
		addq.b	#1,d0	;u
.2		cmp.b	(-1,a0,d4.w),d1
		bne.s	.3
		addq.b	#1,d0	;ul
.3		cmp.b	(1,a0,d4.w),d1
		bne.s	.4
		addq.b	#1,d0	;ur

.4		add.w	d2,d4
		add.w	d2,d4

		cmp.b	(a0,d4.w),d1
		bne.s	.5
		addq.b	#1,d0	;d
.5		cmp.b	(-1,a0,d4.w),d1
		bne.s	.6
		addq.b	#1,d0	;dl
.6		cmp.b	(1,a0,d4.w),d1
		bne.s	.7
		addq.b	#1,d0	;dr
.7		move.w	(sp)+,d4
		rts
;*****************************************************************
	;IN: d0.w = range
Rand		movem.l	d4/d5,-(sp)
		move.w  d0,d5
		beq.s	.exit
		move.w  d5,d4
		subq.w  #1,d4
		move.l  RndSeed,d0
.loop		add.l	d0,d0
		bhi.s	.2
		eor.l	#$1d872b41,d0
.2		lsr.w	#1,d4
		bne.s	.loop

		move.l	d0,RndSeed
		tst.w	d5
		bne.s	.3
		swap	d0
		bra.s	.4
.3		mulu	d5,d0
.4		clr.w	d0
		swap	d0
.exit		movem.l	(sp)+,d4/d5
		rts
;*****************************************************************
GetButtonSizes
	;get rast. font size first
		move.l	WinFont,d0
		bne.s	.setsize
		moveq	#12,d0
		moveq	#12,d1
		bra.s	.skip
.setsize	movea.l	d0,a0
		move.w	(tf_XSize,a0),d0
		move.w	(tf_YSize,a0),d1
		addq.w	#4,d0
		addq.w	#4,d1
.skip
		cmpi.w	#BUTMINX+4,d0
		bge.s	.ok1
		move.w	#BUTMINX+4,d0
.ok1		cmpi.w	#BUTMINY+2,d1
		bge.s	.ok2
		move.w	#BUTMINY+2,d1
.ok2
	;**get resolution and make buttons square
		movea.l	MyDrawInfo,a0
		move.w	(dri_ResolutionX,a0),d2
		move.w	(dri_ResolutionY,a0),d3
		muls.w	d2,d0
		muls.w	d3,d1
		cmp.l	d0,d1
		blt.s	.d1less
		move.l	d1,d0
.d1less		move.l	d0,d1

		divs.w	d2,d0
		divs.w	d3,d1
		move.w	d0,ButtWidth
		move.w	d1,ButtHeight
		rts
;**************************************************************************
GetVisualInfo	movea.l	GadtoolsBase,a6
		movea.l	MyScreen,a0
		suba.l	a1,a1		;no tags
		jsr	(_LVOGetVisualInfoA,a6)
		move.l	d0,VisualInfo		;check this result!
		move.l	d0,dbb_TagList1+4
		move.l	d0,dbb_TagList2+4
		rts
FreeVisualInfo	movea.l	GadtoolsBase,a6
		movea.l	VisualInfo,a0		;may be NULL
		jsr	(_LVOFreeVisualInfo,a6)
		rts
;**************************************************************************
WritePlanes	;IN:a0- ptr to bm_Planes, a1-rawgfx ptr.
		moveq	#3,d0
.write		move.l	a1,(a0)+
		lea	(BUTNEXTPLANE,a1),a1
		dbra	d0,.write
		rts
;----------------------------------------------
SETGFX		MACRO
		lea	bm_Planes+bmap\1,a0
		lea	raw\1,a1
		bsr.w	WritePlanes
		ENDM
SETMGFX		MACRO
		lea	bm_Planes+bmap\1,a0
		lea	rawMagic\1,a1
		bsr.w	WritePlanes
		ENDM
;----------------------------------------------
CreateGfx	;create button-bitmaps
	;first set type of gfx (Standard/MagicWB)
		tst.b	([MyPrefs],mprf_GfxType)
		beq.s	.standard
		SETMGFX	Flag
		SETMGFX	NoFlag
		SETMGFX	Bomb
		SETMGFX	Blowed
	;set planepick/onoff for numbers
		move.b	#%11,img_Number+ig_PlanePick
		bra.s	.skipset

.standard	SETGFX	Flag
		SETGFX	NoFlag
		SETGFX	Bomb
		SETGFX	Blowed
.skipset

	;**allocate MGG struct. and a RastPort structure
		move.l	#mgg_SIZEOF+rp_SIZEOF,d0
		moveq	#0,d1
		bsr.w	ADDALLOC
		move.l	d0,MGGfx
		beq.w	creategfx_error

	;**allocate bitmaps
		movea.l	MGGfx,a3

		movea.l	MyScreen,a2
		movea.l	(sc_RastPort+rp_BitMap,a2),a2	;friend bitmap

		movea.l	_GfxBase,a6
		moveq	#GADBPLNUM-1,d7

.loop		move.w	ButtWidth,d0
		ext.l	d0
		move.w	ButtHeight,d1
		ext.l	d1
		moveq	#BUTMAXBPL,d2
		moveq	#BMF_CLEAR,d3
		movea.l	a2,a0		;friend bitmap
		jsr	(_LVOAllocBitMap,a6)	;V39
		move.l	d0,(a3)+
		dbeq	d7,.loop
		beq.w	creategfx_error

		movea.l	MGGfx,a2
		lea	(mgg_SIZEOF,a2),a3	;my rast port

		movea.l	_GfxBase,a6
		movea.l	a3,a1
		jsr	(_LVOInitRastPort,a6)	;initialize my rastport
		move.l	WinFont,d0
		beq.s	.nofont
		movea.l	a3,a1		;rp
		movea.l	d0,a0		;TextFont
		jsr	(_LVOSetFont,a6)
.nofont
	;**now comes the main part
	;*I'll set each bitmap to MyRP and draw the gfx to it
	;a3:my rp

	;1. draw bevelled boxes (empty gadget etc.)
		movea.l	MGGfx,a5
		movea.l	a3,a0	;rp
		moveq	#0,d0	;x
		move.l	d0,d1	;y
		move.w	ButtWidth,d2
		ext.l	d2
		move.w	ButtHeight,d3
		ext.l	d3
		lea	dbb_TagList1,a1
		movea.l	GadtoolsBase,a6

		movem.l	d0/d1/a0/a1,-(sp)	;(-)
		move.w	#mgg_NumOfNormal-1,d7
		moveq	#0,d6
.loopn		movem.l	(sp),d0/d1/a0/a1	;restore damaged regs.
		move.l	(mgg_Empty,a5,d6.w),(rp_BitMap,a3)	;set bitmap
		jsr	(_LVODrawBevelBoxA,a6)	;draw to my bitmap
		addq.w	#4,d6	;next bmap
		dbra	d7,.loopn
		movem.l	(sp)+,d0/d1/a0/a1	;(+)

	;2. recessed bevelled boxes
		movea.l	MGGfx,a5
		move.l	(mgg_EmptyRecessed,a5),(rp_BitMap,a3)	;set bitmap
		movea.l	a3,a0	;rp
		moveq	#0,d0	;x
		move.l	d0,d1	;y
		move.w	ButtWidth,d2
		ext.l	d2
		move.w	ButtHeight,d3
		ext.l	d3
		lea	dbb_TagList2,a1
		movea.l	GadtoolsBase,a6

		movem.l	d0/d1/a0/a1,-(sp)	;(-)
		move.w	#mgg_NumOfRecessed-1,d7
		moveq	#0,d6
.loopr		movem.l	(sp),d0/d1/a0/a1	;restore damaged regs.
		move.l	(mgg_EmptyRecessed,a5,d6.w),(rp_BitMap,a3)	;set bitmap
		jsr	(_LVODrawBevelBoxA,a6)	;draw to my bitmap
		addq.w	#4,d6	;next bmap
		dbra	d7,.loopr
		movem.l	(sp)+,d0/d1/a0/a1	;(+)

	;3. 4. 5.  Flag, NoFlag, Bomb,Blowed bomb
	;*Copy each gfx from it's bmap to "(mgg_xxxx,a5) bmap"
	;first fill the background with EXTRABACKCOLOR
		movea.l	MGGfx,a5
		movea.l	_GfxBase,a6

		movea.l	a3,a1		;rp
		moveq	#EXTRABACKCOLOR,d0
		jsr	(_LVOSetAPen,a6)
		moveq	#2,d0
		moveq	#1,d1
		move.w	ButtWidth,d2
		subq.w	#3,d2
		ext.l	d2
		move.w	ButtHeight,d3
		subq.w	#2,d3
		ext.l	d3
		movem.l	d0/d1,-(sp)	;(-)
		move.l	(mgg_Flag,a5),(rp_BitMap,a3)
		movea.l	a3,a1
		jsr	(_LVORectFill,a6)
		movem.l	(sp),d0/d1
		move.l	(mgg_NoFlag,a5),(rp_BitMap,a3)
		movea.l	a3,a1
		jsr	(_LVORectFill,a6)
		movem.l	(sp),d0/d1
		move.l	(mgg_Bomb,a5),(rp_BitMap,a3)
		movea.l	a3,a1
		jsr	(_LVORectFill,a6)

		tst.b	([MyPrefs],mprf_GfxType)
		beq.s	.std
		moveq	#BLOWEDBACKMAG,d0
		bra.s	.000
.std		moveq	#BLOWEDBACKSTD,d0
.000		movea.l	a3,a1		;rp
		jsr	(_LVOSetAPen,a6)
		movem.l	(sp),d0/d1
		move.l	(mgg_Blowed,a5),(rp_BitMap,a3)
		movea.l	a3,a1
		jsr	(_LVORectFill,a6)
		movem.l	(sp)+,d0/d1	;(+)

		tst.b	([MyPrefs],mprf_ScaleGfx)
		beq.s	.notscale
	;*****scale bitmaps
		lea	bitScaleArgs,a0
		clr.w	(bsa_SrcX,a0)
		clr.w	(bsa_SrcY,a0)
		move.w	#2,(bsa_DestX,a0)
		move.w	#1,(bsa_DestY,a0)
		move.w	#BUTMINX,(bsa_SrcWidth,a0)
		move.w	#BUTMINY,(bsa_SrcHeight,a0)
		clr.l	(bsa_Flags,a0)
	;get denominators and numerators
	;WIDTH
		move.w	ButtWidth,d0
		move.w	#BUTMINX,d1
		subq.w	#4,d0		;dest. width
		move.l	#16383,d2
		divu.w	d0,d2
		mulu.w	d2,d0		;x-numerator
		mulu.w	d2,d1		;x-denominator
		move.w	d0,(bsa_XDestFactor,a0)
		move.w	d1,(bsa_XSrcFactor,a0)
	;HEIGHT
		move.w	ButtHeight,d0
		move.w	#BUTMINY,d1
		subq.w	#2,d0		;dest. height
		move.l	#16383,d2
		divu.w	d0,d2
		mulu.w	d2,d0		;y-numerator
		mulu.w	d2,d1		;y-denominator
		move.w	d0,(bsa_YDestFactor,a0)
		move.w	d1,(bsa_YSrcFactor,a0)

	;--Flag
	;	lea	bitScaleArgs,a0
		move.l	#bmapFlag,(bsa_SrcBitMap,a0)	;SrcBitMap
		movea.l	(mgg_Flag,a5),(bsa_DestBitMap,a0)	;DstBitBap
		jsr	(_LVOBitMapScale,a6)
	;--NoFlag
		lea	bitScaleArgs,a0
		move.l	#bmapNoFlag,(bsa_SrcBitMap,a0)	;SrcBitMap
		movea.l	(mgg_NoFlag,a5),(bsa_DestBitMap,a0)	;DstBitBap
		jsr	(_LVOBitMapScale,a6)
	;--Bomb
		lea	bitScaleArgs,a0
		move.l	#bmapBomb,(bsa_SrcBitMap,a0)	;SrcBitMap
		movea.l	(mgg_Bomb,a5),(bsa_DestBitMap,a0)	;DstBitBap
		jsr	(_LVOBitMapScale,a6)
	;--Blowed
		lea	bitScaleArgs,a0
		move.l	#bmapBlowed,(bsa_SrcBitMap,a0)	;SrcBitMap
		movea.l	(mgg_Blowed,a5),(bsa_DestBitMap,a0)	;DstBitBap
		jsr	(_LVOBitMapScale,a6)

		bra.s	.skipnotscale
.notscale	;center gfx in dest bitmap
		move.w	ButtWidth,d2
		asr.w	#1,d2		;/2
		move.w	#BUTMINX,d0
		move.w	d0,d4		;size x
		asr.w	#1,d0
		sub.w	d0,d2		;dest x
		move.w	ButtHeight,d3
		asr.w	#1,d3
		move.w	#BUTMINY,d0
		move.w	d0,d5		;size y
		asr.w	#1,d0
		sub.w	d0,d3		;dest y
		ext.l	d2		;to follow recommendations
		ext.l	d3
		ext.l	d4
		ext.l	d5
		moveq	#0,d0		;sour x
		move.l	d0,d1		;sour y
		move.l	#$c0,d6		;miniterm
		moveq	#-1,d7		;mask
		suba.l	a2,a2		;TempA

		movem.l	d0/d1,-(sp)	;store (-)
		lea	bmapFlag,a0	;SrcBitMap
		movea.l	(mgg_Flag,a5),a1	;DstBitBap
		jsr	(_LVOBltBitMap,a6)
		movem.l	(sp),d0/d1	;restore damaged regs.
		lea	bmapNoFlag,a0	;SrcBitMap
		movea.l	(mgg_NoFlag,a5),a1	;DstBitBap
		jsr	(_LVOBltBitMap,a6)
		movem.l	(sp),d0/d1	;restore damaged regs.
		lea	bmapBomb,a0	;SrcBitMap
		movea.l	(mgg_Bomb,a5),a1	;DstBitBap
		jsr	(_LVOBltBitMap,a6)
		movem.l	(sp),d0/d1	;restore damaged regs.
		lea	bmapBlowed,a0	;SrcBitMap
		movea.l	(mgg_Blowed,a5),a1	;DstBitBap
		jsr	(_LVOBltBitMap,a6)
		movem.l	(sp)+,d0/d1	;restore damaged regs. (+)

.skipnotscale
	;**Now create number buttons
	;get fonts baseline and xy-sizes

		movea.l	a3,a1	;rp	;set pens
		moveq	#1,d0	;pen
		jsr	(_LVOSetAPen,a6)
		movea.l	a3,a1	;rp
		moveq	#0,d0
		jsr	(_LVOSetBPen,a6)

		movea.l	WinFont,a0
		move.w	(tf_XSize,a0),d0
		asr.w	#1,d0
		move.w	ButtWidth,d2
		asr.w	#1,d2
		sub.w	d0,d2		;xpos

		move.w	(tf_YSize,a0),d0
		asr.w	#1,d0
		move.w	ButtHeight,d3
		asr.w	#1,d3
		sub.w	d0,d3
		add.w	(tf_Baseline,a0),d3	;ypos

		movea.l	MGGfx,a5
		movea.l	_GfxBase,a6
		moveq	#8-1,d7		;numbers 1-8
		moveq	#0,d6		;offset
		move.b	#'1',d5		;char

		clr.w	Storage
.loopt		move.l	(mgg_Num1,a5,d6.w),(rp_BitMap,a3)
		movea.l	a3,a1		;rp
		move.w	d2,d0		;x
		move.w	d3,d1		;y
		ext.l	d0
		ext.l	d1
		jsr	(_LVOMove,a6)
		moveq	#1,d0		;len
		movea.l	a3,a1		;rp
		lea	Storage,a0	;string
		move.b	d5,(a0)		;put char
		jsr	(_LVOText,a6)
		addq.w	#4,d6		;next bitmap
		addq.b	#1,d5		;next number
		dbra	d7,.loopt
	;create questionmark
		move.w	d2,d4		;store
		move.w	d3,d5
		movea.l	a3,a1		;rp
		moveq	#QUESTBACKCOLOR,d0
		jsr	(_LVOSetAPen,a6)
		moveq	#2,d0
		moveq	#1,d1
		move.w	ButtWidth,d2
		subq.w	#3,d2
		ext.l	d2
		move.w	ButtHeight,d3
		subq.w	#2,d3
		ext.l	d3
		move.l	(mgg_Question,a5),(rp_BitMap,a3)
		movea.l	a3,a1
		jsr	(_LVORectFill,a6)	;fill the background

		movea.l	a3,a1	;rp	;set pens
		moveq	#1,d0	;pen
		jsr	(_LVOSetAPen,a6)
		movea.l	a3,a1	;rp
		moveq	#QUESTBACKCOLOR,d0
		jsr	(_LVOSetBPen,a6)
		move.l	(mgg_Question,a5),(rp_BitMap,a3)
		movea.l	a3,a1	;rp
		move.w	d4,d0	;x
		move.w	d5,d1	;y
		ext.l	d0
		ext.l	d1
		jsr	(_LVOMove,a6)
		moveq	#1,d0	;len
		movea.l	a3,a1	;rp
		lea	Storage,a0
		clr.w	(a0)
		move.b	#'?',(a0) ;string
		jsr	(_LVOText,a6)
		rts

creategfx_error	lea	nomygfx_Text,a1
		lea	nomygfx_Button,a2
		bsr.w	InformationReq
		clr.l	MGGfx
		rts
;*****************************************************************
FreeGfx		movea.l	_GfxBase,a6
		jsr	(_LVOWaitBlit,a6)
		movea.l	MGGfx,a2
		moveq	#GADBPLNUM-1,d2
.loop		move.l	(a2)+,d0	;bitmaps
		beq.s	.exit
		movea.l	d0,a0
		jsr	(_LVOFreeBitMap,a6)
		dbra	d2,.loop
.exit		rts
;*****************************************************************
PutButton	;puts a single button on x,y (d0.w/d1.w)
		;d2.w = button number (e.G. mgg_Empty/4)

		movea.l	MGGfx,a3	;src bitmaps
		movea.l	_GfxBase,a6

	;check range 1..PFw/h-1
		cmpi.w	#1,d0
		blt.w	.exit
		cmpi.w	#1,d1
		blt.w	.exit
		move.w	d0,d4
		addq.w	#1,d4
		cmp.w	PFWidth,d4
		bge.w	.exit
		move.w	d1,d5
		addq.w	#1,d5
		cmp.w	PFHeight,d5
		bge.w	.exit

		movea.l	(a3,d2.w*4),a0		;SrcBitMap

		move.w	ButtWidth,d4	;SizeX
		ext.l	d4
		move.w	ButtHeight,d5	;SizeY
		ext.l	d5

		move.w	d0,d2
		move.w	d1,d3
		subq.w	#1,d2
		subq.w	#1,d3
		mulu.w	d4,d2
		mulu.w	d5,d3
		add.w	MinPFX,d2	;DstX
		ext.l	d2
		add.w	MinPFY,d3	;DstY
		ext.l	d3

		movea.l	MyWindow,a1
		movea.l	(wd_RPort,a1),a1	;DstRPort

		moveq	#0,d0		;SrcX
		move.l	d0,d1		;SrcY
		move.l	#$c0,d6		;Minterm

		jsr	(_LVOBltBitMapRastPort,a6)

.exit		rts
;*****************************************************************
ShowButton	;IN: d0.w = x ,  d1.w = y, d2.w = PF position
		;NOTE: x,y,d2.w is a real position in the PF <1.. *-1>
		;displays contens of first field at pos. x,y
		;and if empty, seedfills whole empty area
		;RETURN: d0.b - num. of button pressed (e.G. bomb)

		movea.l	sp,a2
		move.l	SeedFillSP,sp
		move.l	a2,-(sp)
		bsr.s	.go
		movea.l	(sp)+,sp
		rts

.go		movea.l	MyWindow,a2
		movea.l	MGGfx,a3	;src bitmaps
		movea.l	PFAdr,a4	;1st field
		movea.l	a4,a5
		adda.w	PFSize,a5	;2nd field
		movea.l	_GfxBase,a6

		clr.b	d7
.seedfill
	;check range 1..PFw/h-1
		cmpi.w	#1,d0
		blo.w	.exit
		cmpi.w	#1,d1
		blo.w	.exit
		move.w	d0,d4
		addq.w	#1,d4
		cmp.w	PFWidth,d4
		bhs.w	.exit
		move.w	d1,d5
		addq.w	#1,d5
		cmp.w	PFHeight,d5
		bhs.w	.exit

		cmpi.b	#QMARK,(a5,d2.w)
		bne.s	.0
		tst.b	([MyPrefs],mprf_DeadQ)
		beq.w	.exit
		bra.s	.deadq

.0		tst.b	(a5,d2.w)	;pressed or flag?
		bne.w	.exit		;yes

.deadq		move.b	#1,(a5,d2.w)	;pressed
		move.b	(a4,d2.w),d7
		bne.w	.cont

		movem.w	d0/d1/d2/d7,-(sp)
		sub.w	PFWidth,d2		;u
		subq.w	#1,d1
		bsr.s	.seedfill
		movem.w	(sp),d0/d1/d2/d7
		sub.w	PFWidth,d2
		subq.w	#1,d2			;ul
		subq.w	#1,d0
		subq.w	#1,d1
		bsr.s	.seedfill
		movem.w	(sp),d0/d1/d2/d7
		sub.w	PFWidth,d2
		addq.w	#1,d2			;ur
		addq.w	#1,d0
		subq.w	#1,d1
		bsr.w	.seedfill
		movem.w	(sp),d0/d1/d2/d7
		subq.w	#1,d2			;l
		subq.w	#1,d0
		bsr.w	.seedfill
		movem.w	(sp),d0/d1/d2/d7
		addq.w	#1,d2			;r
		addq.w	#1,d0
		bsr.w	.seedfill
		movem.w	(sp),d0/d1/d2/d7
		add.w	PFWidth,d2		;d
		addq.w	#1,d1
		bsr.w	.seedfill
		movem.w	(sp),d0/d1/d2/d7
		add.w	PFWidth,d2
		subq.w	#1,d2			;dl
		addq.w	#1,d1
		subq.w	#1,d0
		bsr.w	.seedfill
		movem.w	(sp),d0/d1/d2/d7
		add.w	PFWidth,d2
		addq.w	#1,d2			;dr
		addq.w	#1,d1
		addq.w	#1,d0
		bsr.w	.seedfill
		movem.w	(sp)+,d0/d1/d2/d7

.cont		subq.w	#1,WinCount
		ext.w	d7
		movea.l	(a3,d7.w*4),a0		;SrcBitMap

		move.w	ButtWidth,d4	;SizeX
		ext.l	d4
		move.w	ButtHeight,d5	;SizeY
		ext.l	d5

		move.w	d0,d2
		move.w	d1,d3
		subq.w	#1,d2
		subq.w	#1,d3
		mulu.w	d4,d2
		mulu.w	d5,d3
		add.w	MinPFX,d2	;DstX
		ext.l	d2
		add.w	MinPFY,d3	;DstY
		ext.l	d3

		movea.l	(wd_RPort,a2),a1	;DstRPort

		moveq	#0,d0		;SrcX
		move.l	d0,d1		;SrcY
		move.l	#$c0,d6		;Minterm

		jsr	(_LVOBltBitMapRastPort,a6)
.exit
		move.b	d7,d0
		rts
;*****************************************************************
ClearWin	movea.l	_GfxBase,a6

		movea.l	MyWindow,a0
		movea.l	(wd_RPort,a0),a1

		move.w	MinX,d0
		ext.l	d0
		move.w	MinY,d1
		ext.l	d1

		move.w	d0,d2
		add.w	InnWidth,d2
		subq.w	#1,d2
		ext.l	d2
		move.w	d1,d3
		add.w	InnHeight,d3
		subq.w	#1,d3
		ext.l	d3
		jsr	(_LVOEraseRect,a6)	;clear

		rts
;*****************************************************************
RedrawMainBar	bsr.w	RedrawGadget
	;**get new Time and BCount display positions
		move.w	MinX,d0
		add.w	InnWidth,d0
		subi.w	#NUMBBOXX+NUMDISTANCE,d0
		move.w	d0,TimeX
		move.w	MyBarHeight,d0
		asr.w	#1,d0		;/2
		add.w	MinY,d0
		subi.w	#NUMBBOXY/2,d0
		move.w	d0,TimeY
		move.w	d0,BCountY
		move.w	MinX,d0
		addq.w	#NUMDISTANCE,d0
		move.w	d0,BCountX

	;**redraw time and bombs (0)
		move.w	TimeX,d0
		move.w	TimeY,d1
		move.w	MyTime+2,d2
		bsr.w	DrawNumber
		move.w	BCountX,d0
		move.w	BCountY,d1
		move.w	BCount,d2
		bsr.w	DrawNumber
		rts
;*****************************************************************
RedrawWindow	;IN: d0-type of redrawing (BYTE)
		tst.b	Disable		;is window o.k.?
		bne.w	ClearWin

		move.w	d0,-(sp)
		bsr.w	RedrawMainBar
		move.w	(sp)+,d0

		tst.b	Pause
		bne.s	.ret

		pea	(.ret,pc)
		cmpi.b	#RW_START,d0
		beq.s	redrStart
		cmpi.b	#RW_END,d0
		beq.w	redrEnd
		cmpi.b	#RW_ACTUAL,d0
		beq.w	redrActual
		addq.w	#4,a7
.ret
		rts
;------------------------------------------------------------------
redrStart
	;get window position first
		move.w	MinPFX,d0
		ext.l	d0
		move.w	MinPFY,d1
		ext.l	d1
		movem.l	d0/d1,-(sp)	;store x and y

		moveq	#1,d0
		move.l	d0,d1
		moveq	#mgg_Empty/4,d2
		bsr.w	PutButton	;put the first button

		movea.l	_GfxBase,a6
		movea.l	MyWindow,a0
		movea.l	(wd_RPort,a0),a3
		suba.l	a2,a2		;TempA

	;fill the first line (x steps)
		movea.w	PFWidth,a4	;required buttons to complete x
		subq.w	#2,a4
		movea.w	#2,a5		;already completed

		movem.l	(sp),d2/d3	;destx/desty
		add.w	ButtWidth,d2	;destx
		ext.l	d2

		move.w	ButtWidth,d4	;sizex
		ext.l	d4
		move.w	ButtHeight,d5	;sizey
		ext.l	d5
		move.l	#$c0,d6	;miniterm

.nextx		movem.l	(sp),d0/d1	;start position
				;(always upper left corner of the window)
		movea.l	a3,a0		;source and dest. bmap
		movea.l	a3,a1
		jsr	(_LVOClipBlit,a6)
		add.l	d4,d4		;sizex*2
		move.l	d4,d2		;destx
		add.l	(sp),d2		;(+win. offset)
		adda.w	a5,a5
		cmpa.w	a5,a4
		bhs.s	.nextx

		move.w	a5,d4
		asr.w	#1,d4
		move.w	d4,d2
		ext.l	d4
		mulu.w	ButtWidth,d2	;destx
		add.l	(sp),d2
		neg.l	d4
		add.l	a4,d4		;get the rest of buttons
		beq.s	.xcomplete
		mulu.w	ButtWidth,d4	;sizex

		movem.l	(sp),d0/d1
		movea.l	a3,a0
		movea.l	a3,a1
		jsr	(_LVOClipBlit,a6)

.xcomplete	;**now do similar with y blocks
		movea.w	PFHeight,a4	;required lines to complete y
		subq.w	#2,a4
		movea.w	#2,a5		;already completed

		movem.l	(sp),d2/d3	;destx/desty
		add.w	ButtHeight,d3	;desty
		ext.l	d3
		move.w	PFWidth,d4	;sizex
		subq.w	#2,d4
		mulu.w	ButtWidth,d4	;&

		move.w	ButtHeight,d5	;sizey
		ext.l	d5

.nexty		movem.l	(sp),d0/d1	;start position
				;(always upper left corner of the window)
		movea.l	a3,a0		;source and dest. bmap
		movea.l	a3,a1
		jsr	(_LVOClipBlit,a6)
		add.l	d5,d5		;sizey*2
		move.l	d5,d3		;desty
		add.l	(4,sp),d3
		adda.w	a5,a5
		cmpa.w	a5,a4
		bhs.s	.nexty

		move.w	a5,d5
		asr.w	#1,d5
		move.w	d5,d3
		ext.l	d5
		mulu.w	ButtHeight,d3	;desty
		add.l	(4,sp),d3
		neg.l	d5
		add.l	a4,d5		;get the rest of lines
		beq.s	.ycomplete
		mulu.w	ButtHeight,d5	;sizey

		movem.l	(sp),d0/d1
		movea.l	a3,a0
		movea.l	a3,a1
		jsr	(_LVOClipBlit,a6)
.ycomplete
		addq.l	#8,sp		;restore stack
		rts
;----------------------------------------------------------------
redrEnd	;**draw contens of the PlayField
		move.w	MinPFX,d2	;DstX
		ext.l	d2
		move.w	MinPFY,d3	;DstY
		ext.l	d3
		move.w	ButtWidth,d4	;SizeX
		ext.l	d4
		move.w	ButtHeight,d5	;SizeY
		ext.l	d5

		movea.l	MGGfx,a3	;src bitmaps
		movea.l	MyWindow,a4
		movea.l	(wd_RPort,a4),a4		;dst
		movea.l	PFAdr,a5	;PF contens
		adda.w	PFWidth,a5	;pos 1,1
		addq.w	#1,a5		;&

		movea.l	_GfxBase,a6
		move.w	PFHeight,d7
		subq.w	#2+1,d7
.heightloop	move.w	PFWidth,d6
		subq.w	#2+1,d6
.widthloop
		movem.w	d6/d7,-(sp)
	;copy bitmap
		move.w	PFSize,d7
		move.b	(a5,d7.w),d7
		move.b	(a5)+,d6
		cmpi.b	#mgg_Blowed/4,d6
		beq.s	.next
		cmpi.b	#mgg_Bomb/4,d6
		bne.s	.flag
		cmpi.b	#FLAG,d7
		beq.s	.next
		tst.b	Win
		beq.s	.flok
		move.b	#mgg_Flag/4,d6
		bra.s	.flok

.flag		cmpi.b	#FLAG,d7
		bne.s	.next
		move.b	#mgg_NoFlag/4,d6
.flok
		ext.w	d6
		movea.l	(a3,d6.w*4),a0		;SrcBitMap
		moveq	#0,d0		;SrcX
		move.l	d0,d1		;SrcY
		movea.l	a4,a1		;DstRPort
		move.l	#$c0,d6		;Minterm

		jsr	(_LVOBltBitMapRastPort,a6)

.next		add.l	d4,d2
		movem.w	(sp)+,d6/d7
		dbra	d6,.widthloop
		add.l	d5,d3
		addq.w	#2,a5
		move.w	MinPFX,d2
		ext.l	d2
		dbra	d7,.heightloop

		rts
;---------------------------------------------------------------
redrActual
		move.w	MinPFX,d2	;DstX
		ext.l	d2
		move.w	MinPFY,d3	;DstY
		ext.l	d3
		move.w	ButtWidth,d4	;SizeX
		ext.l	d4
		move.w	ButtHeight,d5	;SizeY
		ext.l	d5

		movea.l	MGGfx,a3	;src bitmaps
		movea.l	MyWindow,a4
		movea.l	(wd_RPort,a4),a4		;dst
		movea.l	PFAdr,a5	;PF contens
		movea.l	a5,a2
		adda.w	PFSize,a2
		adda.w	PFWidth,a5	;pos 1,1
		addq.w	#1,a5		;&
		adda.w	PFWidth,a2	;pos 1,1
		addq.w	#1,a2		;&


		movea.l	_GfxBase,a6
		move.w	PFHeight,d7
		subq.w	#2+1,d7
.heightloop	move.w	PFWidth,d6
		subq.w	#2+1,d6
.widthloop
		move.w	d6,-(sp)
	;copy bitmap
		cmpi.b	#FLAG,(a2)
		bne.s	.noflag
		movea.l	(mgg_Flag,a3),a0
		bra.s	.draw
.noflag		cmpi.b	#QMARK,(a2)
		bne.s	.noqmark
		movea.l	(mgg_Question,a3),a0
		bra.s	.draw
.noqmark	tst.b	(a2)	;pressed?
		bne.s	.yes	;yes
		movea.l	(mgg_Empty,a3),a0
		bra.s	.draw
.yes		move.b	(a5),d6
		ext.w	d6
		movea.l	(a3,d6.w*4),a0		;SrcBitMap
.draw		addq.w	#1,a2
		addq.w	#1,a5
		moveq	#0,d0		;SrcX
		move.l	d0,d1		;SrcY
		movea.l	a4,a1		;DstRPort
		move.l	#$c0,d6		;Minterm

		jsr	(_LVOBltBitMapRastPort,a6)

		add.l	d4,d2
		move.w	(sp)+,d6
		dbra	d6,.widthloop
		add.l	d5,d3
		addq.w	#2,a5
		addq.w	#2,a2
		move.w	MinPFX,d2
		ext.l	d2
		dbra	d7,.heightloop

		rts
;*****************************************************************
ResizeWindow	;**change box
		bsr.w	SetWinParams

		bsr.w	RemSunG
		lea	SunGadget,a0
		move.l	#0,(gg_GadgetRender,a0)
		move.l	#0,(gg_SelectRender,a0)
		bsr.w	AddSunG

		bsr.w	ClearWin
	;**Change the window box
		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		move.w	WinX,d0
		ext.l	d0
		move.w	WinY,d1
		ext.l	d1
		move.w	WinWidth,d2
		ext.l	d2
		move.w	WinHeight,d3
		ext.l	d3
		jsr	(_LVOChangeWindowBox,a6)
		st	IDidTheChange
rw_exit		rts
;*****************************************************************
RedrawGadget	bsr.s	RemSunG
		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		jsr	(_LVORefreshWindowFrame,a6)
		; no rts !!
AddGadget
	;IN:Gadget_Image.l	gadget image
		lea	SunGadget,a0	;set new position of the gadget
		move.w	InnWidth,d0
		subi.w	#SUNMINX,d0
		asr.w	#1,d0
		add.w	MinX,d0
		move.w	d0,(gg_LeftEdge,a0)
		move.w	MyBarHeight,d0
		subi.w	#SUNMINY,d0
		asr.w	#1,d0
		add.w	MinY,d0
		move.w	d0,(gg_TopEdge,a0)

	;set appropriate gadget image
		tst.b	Disable
		beq.s	.norm
		clr.l	(gg_GadgetRender,a0)
		clr.l	(gg_SelectRender,a0)
		bra.s	.dis
.norm		move.l	Gadget_Image,(gg_GadgetRender,a0)
		move.l	#img_SunPressed,(gg_SelectRender,a0)
.dis		bsr.s	AddSunG

		movea.l	IntuiBase,a6
		lea	SunGadget,a0
		movea.l	MyWindow,a1
		suba.l	a2,a2
		jsr	(_LVORefreshGadgets,a6)
		rts
;---------------------------
RemSunG		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		lea	SunGadget,a1
		jsr	(_LVORemoveGadget,a6)	;I'm not able to handle errors
		rts
AddSunG		movea.l	IntuiBase,a6
		moveq	#0,d0
		movea.l	MyWindow,a0
		lea	SunGadget,a1
		jsr	(_LVOAddGadget,a6)
		rts
;*****************************************************************
ChangeIDCMP	;IN: d0 - idcmp flags
		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		move.l	OldIDCMP,d2
		eor.l	d2,d0
		move.l	d0,d2
		jsr	(_LVOModifyIDCMP,a6)
		tst.l	d0
		beq.s	.fail
		move.l	d2,OldIDCMP
.fail		rts
;*****************************************************************
OpenMyWindow
	;**Open MyWindow
		movea.l	IntuiBase,a6
		suba.l	a0,a0	;NewWindow=0
		lea	MyWinTags,a1	;TagList
		jsr	(_LVOOpenWindowTagList,a6)
		move.l	d0,MyWindow
		bne.s	.cont
		lea	nowin_Text,a1
		lea	nowin_Button,a2
		bsr.w	InformationReq
		bra.s	.nowindow
.cont
	;*set new window pointer for ReqTools requesters
		move.l	MyWindow,d0
		move.l	d0,IReqTags+12
		move.l	d0,JoinGetTags+4
		move.l	d0,GSReqTags+4
		move.l	d0,HiScoresTags+4
	;**set font
		move.l	WinFont,d0
		beq.s	.skip
		movea.l	_GfxBase,a6
		movea.l	d0,a0		;font
		movea.l	MyWindow,a1
		movea.l	(wd_RPort,a1),a1		;rp
		jsr	(_LVOSetFont,a6)
.skip
.nowindow	rts
;----------------------------------------------------------
CloseMyWindow	movea.l	(EB,PC),a6
		movea.l	Semaphore,a0
		jsr	(_LVOObtainSemaphore,a6)
	;**collect all possible pending messages
		movea.l	MyWindow,a2
		move.l	(wd_UserPort,a2),d2
		beq.s	.noport
.cl		movea.l	d2,a0
		jsr	(_LVOGetMsg,a6)
		tst.l	d0
		bne.s	.cl

		moveq	#0,d0
		clr.l	OldIDCMP
		bsr.w	ChangeIDCMP	;close IDCMP ports
.noport
		movea.l	(EB,PC),a6
		movea.l	Semaphore,a0
		jsr	(_LVOReleaseSemaphore,a6)

		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		jsr	(_LVOCloseWindow,a6)

	;*set zero pointer for ReqTools requesters
		moveq	#0,d0
		move.l	d0,IReqTags+12
		move.l	d0,JoinGetTags+4
		move.l	d0,GSReqTags+4
		move.l	d0,HiScoresTags+4
		rts
;**********************************************************************
OpenMyScreen
	;**Check settings
		movea.l	MyPrefs,a0
		tst.b	(mprf_CustomScreen,a0)	;customscreen=yes?
		beq.w	noscreen

	;set tags
		lea	MyScreenTags,a1
tagloop		move.l	(a1)+,d0
		cmpi.l	#TAG_DONE,d0
		beq.w	tags_done
		cmpi.l	#SA_Width,d0
		beq.s	.setWidth
		cmpi.l	#SA_Height,d0
		beq.s	.setHeight
		cmpi.l	#SA_DisplayID,d0
		beq.s	.setModeID
		cmpi.l	#SA_LikeWorkbench,d0
		beq.s	.wblike

		addq.w	#4,a1		;just other tag
		bra.s	tagloop
.setWidth	move.w	(mprf_ScrWidth,a0),d0
		ext.l	d0
		bne.s	.0
		move.l	#STDSCREENWIDTH,d0
.0		move.l	d0,(a1)+
		bra.s	tagloop
.setHeight	move.w	(mprf_ScrHeight,a0),d0
		ext.l	d0
		bne.s	.1
		move.l	#STDSCREENHEIGHT,d0
.1		move.l	d0,(a1)+
		bra.s	tagloop
.setModeID	move.l	(mprf_ModeID,a0),d0
		bne.s	.2
		move.l	#PAL_MONITOR_ID!HIRES_KEY,d0
		move.l	d0,(mprf_ModeID,a0)
.2		move.l	d0,(a1)+
		bra.w	tagloop
.wblike		tst.b	(mprf_WBLike,a0)
		bne.s	.wbl
		move.l	#FALSE,(a1)+
		bra.s	tagloop
.wbl		move.l	#TRUE,(a1)+
		move.l	#TAG_DONE,(a1)
tags_done
	;**Open screen
		movea.l	IntuiBase,a6
		suba.l	a0,a0	;NewScreen
		lea	MyScreenTags,a1
		jsr	(_LVOOpenScreenTagList,a6)

		move.l	d0,MyScreen
		bne.s	.ok
		lea	NoScr_Text,a1
		lea	NoScr_Button,a2
		bsr.w	InformationReq
		clr.b	([MyPrefs],mprf_CustomScreen)
.ok
noscreen	rts

;*******
CloseMyScreen	movea.l	IntuiBase,a6
		movea.l	MyScreen,a0
		movea.l	MyDrawInfo,a1
		jsr	(_LVOFreeScreenDrawInfo,a6)

		tst.b	([MyPrefs],mprf_CustomScreen)
		bne.s	.cust
		suba.l	a0,a0
		movea.l	MyScreen,a1
		jsr	(_LVOUnlockPubScreen,a6)
		bra.s	.exit
.cust
		movea.l	MyScreen,a0
		jsr	(_LVOCloseScreen,a6)
.exit		rts
;*****************************************************************
SetPalette
		tst.b	([MyPrefs],mprf_CustomScreen)
		beq.s	.exit
		movea.l	MyScreen,a0
	;**Set palette here
		movea.l	_GfxBase,a6
		lea	(sc_ViewPort,a0),a0
		lea	ScreenPalette,a1	;palette
		jsr	(_LVOLoadRGB32,a6)	;load 8-bit palette
.exit		rts
;*****************************************************************
OpenFont	movea.l	MyPrefs,a2
		lea	MyTextAttr,a3
		move.l	(mprf_FontName,a2),(ta_Name,a3)	;font name
		beq.s	.setdefault
		move.w	(mprf_FontSize,a2),(ta_YSize,a3)	;font size
		bne.s	.sizeok	;if Size=0 then set other size
	;**use the designed font
		move.b	#FPF_DESIGNED,(ta_Flags,a3)
.sizeok
	;**try diskfont
		movea.l	(EB,PC),a6
		moveq	#0,d0
		lea	DiskFontName,a1
		jsr	(_LVOOpenLibrary,a6)
		move.l	d0,Storage
		beq.s	.rom

		movea.l	d0,a6	;library base
		movea.l	a3,a0	;TTextAttr
		jsr	(_LVOOpenDiskFont,a6)
		move.l	d0,WinFont

		movea.l	(EB,PC),a6
		movea.l	Storage,a1	;diskfont.library base
		jsr	(_LVOCloseLibrary,a6)

		tst.l	WinFont
		bne.s	.exit

.rom		movea.l	_GfxBase,a6
		movea.l	a3,a0		;TextAttr
		jsr	(_LVOOpenFont,a6)
		move.l	d0,WinFont
		bne.s	.exit

		lea	nofont_Text,a1
		lea	nofont_Button,a2
		bsr.w	InformationReq
.setdefault	movea.l	_GfxBase,a0
		move.l	(gb_DefaultFont,a0),WinFont
		clr.l	([MyPrefs],mprf_FontName)
		rts
.exit
		move.l	([WinFont],LN_NAME),([MyPrefs],mprf_FontName)
		rts

CloseFont	move.l	WinFont,d0
		beq.s	.exit
		movea.l	_GfxBase,a6
		movea.l	d0,a1
		jsr	(_LVOCloseFont,a6)
.exit		rts
;*****************************************************************
FontToRT	movea.l	_GfxBase,a6
		movea.l	(gb_DefaultFont,a6),a0
		lea	MyTextAttr,a1
		move.l	(LN_NAME,a0),(a1)	;LN_NAME -> ta_Name
		move.w	(tf_YSize,a0),(ta_YSize,a1)
		move.b	(tf_Style,a0),(ta_Style,a1)
		move.b	(tf_Flags,a0),(ta_Flags,a1)
		rts
;*****************************************************************
GetDRI	;**get screen draw info
		movea.l	IntuiBase,a6
		movea.l	MyScreen,a0
		jsr	(_LVOGetScreenDrawInfo,a6)
		move.l	d0,MyDrawInfo
		rts
;*****************************************************************
LockScreen	movea.l	IntuiBase,a6
		tst.l	MyScreen
		bne.s	nolock

		move.l	([MyPrefs],mprf_PubNameAdr),d0	;any public screen specified?
		beq.s	.wb			;no
		movea.l	d0,a0			;$ check if it's open
		jsr	(_LVOLockPubScreen,a6)
		tst.l	d0
		bne.s	.gotone			;$ yes it is
		clr.l	([MyPrefs],mprf_PubNameAdr)

.wb		suba.l	a0,a0	;Workbench or default public screen
		jsr	(_LVOLockPubScreen,a6)
.gotone		move.l	d0,MyScreen
nolock		rts

;*****************************************************************
SetMenu
	;Create NewMenu structure for gadtools.library
		lea	MyMenu,a0
		lea	GTNewMenu,a1

.copy		move.b	(mmi_Type,a0),d0
		beq.w	.copied
		move.b	d0,(gnm_Type,a1)
		move.w	(mmi_Flags,a0),(gnm_Flags,a1)
		move.l	(mmi_CommKey,a0),(gnm_CommKey,a1)
		move.l	(mmi_Mutual,a0),(gnm_MutualExclude,a1)
		move.l	(mmi_Name,a0),(gnm_Label,a1)

		lea	(mmi_SIZEOF,a0),a0
		lea	(gnm_SIZEOF,a1),a1
		bra.s	.copy
.copied
		movea.l	GadtoolsBase,a6
		lea	GTNewMenu,a0
		lea	NewMenuTags,a1
		jsr	(_LVOCreateMenusA,a6)
		move.l	d0,MenuStruct
		beq.s	NoMenu

		movea.l	MenuStruct,a0
		movea.l	VisualInfo,a1
		lea	LayoutTags,a2
		jsr	(_LVOLayoutMenusA,a6)
		tst.l	d0
		beq.s	NoMenu2

	;Hey! set it finally!
		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		movea.l	MenuStruct,a1
		jsr	(_LVOSetMenuStrip,a6)

	;set checkmark due to level
		move.b	([MyPrefs],mprf_Level),d0
		subq.b	#1,d0
		ext.w	d0
		mulu.w	#mmi_SIZEOF,d0
		lea	LevelItems,a0
		move.w	(mmi_Code,a0,d0.w),d0

		ext.l	d0	;to be sure
		movea.l	IntuiBase,a6
		movea.l	MenuStruct,a0
		jsr	(_LVOItemAddress,a6)
		movea.l	d0,a0
		ori.w	#CHECKED,(mi_Flags,a0)	;set checkmark
		rts

NoMenu2		movea.l	MenuStruct,a0
		jsr	(_LVOFreeMenus,a6)
NoMenu		clr.l	MenuStruct
		lea	nomenu_Text,a1
		lea	nomenu_Button,a2
		bsr.w	InformationReq
		rts
;-------------------------------------------------------
ClearMenu	tst.l	MenuStruct
		beq.s	.nomenu
		movea.l	IntuiBase,a6
		movea.l	MyWindow,a0
		jsr	(_LVOClearMenuStrip,a6)

		movea.l	GadtoolsBase,a6
		movea.l	MenuStruct,a0
		jsr	(_LVOFreeMenus,a6)
.nomenu		rts
;*****************************************************************
InformationReq	;IN: a1 - text  a2 - button text
		movem.l	d1-d7/a0-a6,-(sp)
		movea.l	_ReqToolsBase,a6
		suba.l	a3,a3
		suba.l	a4,a4
		lea	IReqTags,a0
		jsr	(_LVOrtEZRequestA,a6)
		movem.l	(sp)+,d1-d7/a0-a6
		rts
;*****************************************************************
CDProggy	movea.l	DosBase,a6
		move.l	ProgDir,d1
		jsr	(_LVOCurrentDir,a6)
		lea	(olddir,pc),a0
		move.l	d0,(a0)
		rts
CDBack		movea.l	DosBase,a6
		move.l	(olddir,pc),d1
		jsr	(_LVOCurrentDir,a6)
		rts
olddir		dc.l	0

;*****************************************************************

;---------------------------------------------------
HEADSIZE	= 25
LINESIZE	= 12+NAMELEN+9
LEVELSIZE	= LINESIZE*2
CUSTOMSIZE	= LEVELSIZE+6*28
HS_TEXTMEM	= HEADSIZE+LEVELSIZE*4+LINESIZE+CUSTOMSIZE+1

MakeHighScores	;IN: nothing
		;Makes a text string for ReqTools

		movea.l	MyPrefs,a5
		lea	HiScoresText,a0
		move.w	#HS_TEXTMEM-2,d7
		lea	(hs_ScoresText,pc),a1
		lea	(hs_DataTable,pc),a3
cploop		move.b	(a1)+,d0
		cmpi.b	#'$',d0
		beq.s	.writename
		cmpi.b	#'%',d0
		beq.s	.writenumber
		move.b	d0,(a0)+
		dbeq	d7,cploop
		bra.s	hs_AllDone

.writename	move.b	(a1)+,d0	;get offset in table
		ext.w	d0
		move.w	(a3,d0.w*2),d0	;get real offset
		movea.l	a5,a4		;MyPrefs
		moveq	#0,d1		;pocet pismen
.wnloop0	move.b	(a4,d0.w),(a0)+
		beq.s	.wndone0
		addq.l	#1,a4
		addq.w	#1,d1
		subq.w	#1,d7
		bmi.s	hs_AllDone
		bra.s	.wnloop0
.wndone0	subq.l	#1,a0
		move.w	#NAMELEN+4,d2
		sub.w	d1,d2
		subq.w	#1,d2
.wnloop1	move.b	#'.',(a0)+
		subq.w	#1,d7
		bmi.s	hs_AllDone
		dbra	d2,.wnloop1
		bra.s	cploop

.writenumber	move.b	(a1)+,d0
		ext.w	d0
		move.w	(a3,d0.w*2),d0
		move.w	(a5,d0.w),d2	;time from hiscores
		bsr.w	Num2String4
		moveq	#4-1,d2
.nloop		move.b	(a2)+,(a0)+
		subq.w	#1,d7
		bmi.s	hs_AllDone
		dbra	d2,.nloop
		bra.s	cploop

hs_AllDone	clr.b	(a0)+
		rts

hs_DataTable	dc.w	mhs_EasyName1,mhs_EasyTime1,mhs_EasyName2,mhs_EasyTime2
		dc.w	mhs_NormalName1,mhs_NormalTime1,mhs_NormalName2,mhs_NormalTime2
		dc.w	mhs_HardName1,mhs_HardTime1,mhs_HardName2,mhs_HardTime2
		dc.w	mhs_ProfiName1,mhs_ProfiTime1,mhs_ProfiName2,mhs_ProfiTime2
		dc.w	mhs_CustomName1,mhs_CustomTime1,mhs_CustomWidth1,mhs_CustomHeight1,mhs_CustomBombs1
		dc.w	mhs_CustomName2,mhs_CustomTime2,mhs_CustomWidth2,mhs_CustomHeight2,mhs_CustomBombs2

hs_ScoresText	dc.b	'**** Best sweepers ****',10
		dc.b	'Easy :   1. $',0,'%',1,10
		dc.b	'         2. $',2,'%',3,10
		dc.b	'Medium : 1. $',4,'%',5,10
		dc.b	'         2. $',6,'%',7,10
		dc.b	'Hard :   1. $',8,'%',9,10
		dc.b	'         2. $',10,'%',11,10
		dc.b	'Profi :  1. $',12,'%',13,10
		dc.b	'         2. $',14,'%',15,10
		dcb.b	LINESIZE-1,'-'
		dc.b	10
		dc.b	'Custom : 1. $',16,'%',17,10
		dc.b	'               Width : %',18,10
		dc.b	'               Height: %',19,10
		dc.b	'               Mines : %',20,10
		dc.b	'         2. $',21,'%',22,10
		dc.b	'               Width : %',23,10
		dc.b	'               Height: %',24,10
		dc.b	'               Mines : %',25
		dc.b	0


		cnop	0,4
;*****************************************************************
ClearHighScores	;IN: a0-MyPrefs
		; MinesHiScores structure
		;   will be filled with defaults (Nobody 9999)

		st	(mhs_Valid,a0)
		st	(mhs_NewHiscore,a0)
	;**set best times to default
		lea	(mhs_BestTimes,a0),a1
		move.w	#(mhs_BTEnd-mhs_BestTimes)/2-1,d0
.time		move.w	#MAXTIME,(a1)+
		dbra	d0,.time

	;**clear all names
		lea	(mhs_BestNames,a0),a1
		move.w	#(mhs_BNEnd-mhs_BestNames)/NAMELEN-1,d0
.cp0		clr.b	(a1)
		lea	(NAMELEN,a1),a1
		dbra	d0,.cp0		;next

		clr.l	(mhs_CustomWidth1,a0)	;1.w,2.w
		clr.l	(mhs_CustomHeight1,a0)
		clr.l	(mhs_CustomBombs1,a0)
		rts

;*****************************************************************
DSIZEW	=	(mhs_SIZEOF-mhs_Data)/2

GETC		MACRO	;CHAR,ADD
		cmpi.b	#\1,d0
		bne.s	.0\@
		move.b	(a0)+,d0
		subq.w	#1,d1
		addi.b	#\2,d0
		bra.s	.ok
.0\@
		ENDM

GetMHS		;decode file and extract MinesHiScores structure

		;IN: d1 = (FileLenght - 1) , a5 = filebuffer
		;    a4 = MyPrefs
	;convert text->zmatky
		movea.l	a5,a0		;src
		movea.l	a5,a1		;dest
		moveq	#0,d2		;lenght

	;kill LF
		move.w	d1,d3
.lfloop		move.b	(a0)+,d0
		cmpi.b	#10,d0
		bne.s	.nolf
		subq.w	#1,d1
		bra.s	.lfok
.nolf		move.b	d0,(a1)+
.lfok		dbra	d3,.lfloop

		tst.w	d1
		bmi.s	.empty
		movea.l	a5,a0		;src
		movea.l	a5,a1		;dest
.loop		move.b	(a0)+,d0
		subq.w	#1,d1
		bmi.s	.ok

		GETC	LOWC,-32
		GETC	MEDC,127-32
		GETC	HIGHC,222-32
		move.l	d0,d0
.ok		move.b	d0,(a1)+
		addq.w	#1,d2
		tst.w	d1
		bpl.s	.loop
.empty
		cmpi.l	#hsf_SIZEOF,d2	;lenght ok?
		bne.s	.error

		movea.l	a5,a0		;file addr
	;check coded checksum
		move.w	#DSIZEW-1,d3
		moveq	#0,d0
		lea	(hsf_Data,a0),a0
.chck		add.w	(a0)+,d0
		dbra	d3,.chck
		cmp.w	(hsf_CodedChecksum,a5),d0
		bne.s	.error
	;encode
		move.l	(a5),d2	;RndSeed
		lea	(hsf_Data,a5),a0
		move.w	#DSIZEW*2,d1
		bsr.w	Decrypt	;IN: a0-data, d1-length, d2-RndSeed
	;check encoded checksum
		move.w	#DSIZEW-1,d3
		moveq	#0,d0
		lea	(hsf_Data,a5),a0
.chck2		add.w	(a0)+,d0
		dbra	d3,.chck2
		cmp.w	(hsf_DecodedChecksum,a5),d0
		bne.s	.error
	;O.K. the file seems to be correct so fill it to MinesHiScores struct.
		move.w	#DSIZEW-1,d3
		lea	(hsf_Data,a5),a0
		movea.l	a4,a1		;MyPrefs
		st	(mhs_Valid,a1)	;hi-scores are valid
		lea	(mhs_Data,a1),a1
.cp		move.w	(a0)+,(a1)+
		dbra	d3,.cp
		moveq	#0,d0
		rts
.error		moveq	#-1,d0
		rts
;-----------------------------------------------------------
LoadHiScores
		bsr.w	CDProggy	;change directory to program
		move.l	#HsFileName,d0
		bsr.w	LOAD_FILE	;IN:d0-filename  ;OUT: d0-adr. or 0 ;d1- len
		tst.l	d0		;store
		beq.s	.skip
		lea	(fb,pc),a0	;store buffer
		move.l	d0,(a0)

		bfclr	d1{0:16}
		bne.s	.empty	;well, too big
		subq.w	#1,d1		;file lenght
		bmi.s	.empty		;empty file
		movea.l	d0,a5
		movea.l	MyPrefs,a4

		bsr.w	GetMHS

		tst.b	d0		;error?
		bne.s	.hsc_CrapFile

		move.w	(hsf_LastXmasYear,a5),LastXmas	;get last xmas

.empty
.crapret	movea.l	(fb,pc),a1		;file buffer
		bsr.w	FreeMemBlock

.skip		movea.l	MyPrefs,a0
		clr.b	(mhs_NewHiscore,a0)
		tst.b	(mhs_Valid,a0)	;hi-scores loaded correctly?
		bne.s	.hsok
		bsr.w	ClearHighScores	;no
.hsok
		bsr.w	CDBack
		rts


.hsc_CrapFile	lea	(crap_Text,pc),a1
		lea	(crap_Button,pc),a2
		bsr.w	InformationReq
		bra.s	.crapret

fb		dc.l	0
crap_Text	dc.b	'"Mines.hiscores" is crap.',10
		dc.b	'Will be overwritten on exit!',0
crap_Button	dc.b	'I see..',0
		cnop	0,4
;*****************************************************************
CPL	= 80	;chars per line
LOWC	= '¤'
MEDC	= 'ò'
HIGHC	= 'Ô'
PUTCH		MACRO
		move.b	\1,(a1)+
		addq.w	#1,d3
		subq.w	#1,d2
		bne.s	.cont\@
		addq.w	#1,d3
		move.w	#CPL,d2
		move.b	#10,(a1)+
.cont\@
		ENDM
;------------------------------------------------------
SaveScore	;IN: a3 - filename ;a4 - MyPrefs
		;OUT: d0 - 0=OK
	;alloc buffer
		move.l	#hsf_SIZEOF,d0
		moveq	#0,d1
		bsr.w	ADDALLOC
		tst.l	d0
		beq.w	ss_fail
		movea.l	d0,a5
	;copy structure to buffer
		movea.l	a4,a0
		lea	(mhs_Data,a0),a0
		movea.l	a5,a1
		lea	(hsf_Data,a1),a1
		move.w	#DSIZEW-1,d0
.cp		move.w	(a0)+,(a1)+
		dbra	d0,.cp
	;set EncodedChecksum
		movea.l	a5,a0
		lea	(hsf_Data,a0),a0
		moveq	#0,d0
		move.w	#DSIZEW-1,d1
.chck		add.w	(a0)+,d0
		dbra	d1,.chck
		move.w	d0,(hsf_DecodedChecksum,a5)
	;set rndseed
		movea.l	IntuiBase,a0
		move.l	(ib_Micros,a0),d2
	;code
		movea.l	a5,a0
		move.l	d2,(a0)	;set rndseed to file
		lea	(hsf_Data,a0),a0		;data
		move.w	#DSIZEW*2,d1	;len
		bsr.w	Encrypt
	;set coded checksum
		movea.l	a5,a0
		lea	(hsf_Data,a0),a0
		moveq	#0,d0
		move.w	#DSIZEW-1,d1
.chck2		add.w	(a0)+,d0
		dbra	d1,.chck2
		move.w	d0,(hsf_CodedChecksum,a5)

		move.w	LastXmas,(hsf_LastXmasYear,a5)
	;save
	;convert zmatky->txt
	;low - <0-31>    med - <127-221>  high - <222-255>
	;chr(10) is ignored (LF)
		move.l	#hsf_SIZEOF,d0	;get max. size of hi-scores file
		add.l	d0,d0	;*2 for e.G. '.A'
		move.l	d0,d1
		divu.l	#CPL,d1	;LF's
		add.l	d1,d0
		moveq	#MEMF_PUBLIC,d1
		bsr.w	ADDALLOC
		move.l	d0,d7	;store
		beq.w	ss_fail

		movea.l	d0,a0
		movea.l	a0,a1
		move.w	#hsf_SIZEOF-1,d1
		movea.l	a5,a0
		moveq	#0,d3		;final size
.make0		moveq	#CPL,d2
.make		move.b	(a0)+,d0

		cmpi.b	#31,d0		;check range
		bhi.s	.0
		PUTCH	#LOWC
		addi.b	#32,d0
.0		cmpi.b	#127,d0
		blo.s	.1
		cmpi.b	#221,d0
		bhi.s	.10
		PUTCH	#MEDC
		subi.b	#127-32,d0
		bra.s	.1
.10		PUTCH	#HIGHC
		subi.b	#222-32,d0
.1
		PUTCH	d0
		dbra	d1,.make


		move.l	a3,d0
		move.l	d7,d1
		move.l	d3,d2
		bsr.w	SAVE_FILE	;IN: d0-filename;d1-data;d2-lenght;OUT: d0=0 => O.K.
		rts
ss_fail		moveq	#-1,d0
		rts
;------------------------------------------
SaveHiScores	movem.l	d0-d7/a0-a6,-(sp)
		bsr.w	CDProggy
		movea.l	MyPrefs,a0
		lea	HsFileName,a3
		movea.l	MyPrefs,a4
		bsr.w	SaveScore
		tst.l	d0
		bne.s	save_fail
		clr.b	([MyPrefs],mhs_NewHiscore)
shsc_exit
		bsr.w	CDBack
		movem.l	(sp)+,d0-d7/a0-a6
		rts

save_fail	lea	(.sf_Text,pc),a1
		lea	(.sf_Button,pc),a2
		bsr.w	InformationReq
		bra.s	shsc_exit

.sf_Text	dc.b	'Sorry. "Mines.hiscores" could not be saved.',0
.sf_Button	dc.b	'Oh, damned!',0
		cnop	0,4
;-----------------------------------------
Decrypt	;IN: a0-data, d1- length, d2-RndSeed
		movem.l	d0-d2/a0,-(sp)
		move.l	d2,RndSeed
		subq.w	#1,d1
.loop		move.b	(a0),d2
		moveq	#-1,d0
		bsr.w	Rand
		add.b	d0,d2
		move.b	d2,(a0)+
		dbra	d1,.loop
		movem.l	(sp)+,d0-d2/a0
		rts
Encrypt	;IN: a0-data, d1-length, d2-RndSeed
		movem.l	d0-d2/a0,-(sp)
		move.l	d2,RndSeed
		subq.w	#1,d1
.loop		move.b	(a0),d2
		moveq	#-1,d0
		bsr.w	Rand
		sub.b	d0,d2
		move.b	d2,(a0)+
		dbra	d1,.loop
		movem.l	(sp)+,d0-d2/a0
		rts
*****************************************************************
DefaultPrefs	;IN: a0-MyPrefs
		movem.l	d0/a0,-(sp)
		move.w	#prf_SIZEOF-1,d0
.clr		clr.b	(a0)+
		dbra	d0,.clr
		movem.l	(sp)+,d0/a0
		rts
;-------------------------------------------------------------
LoadPreferences	;Loads preferences from disk to memory.
		;MyPrefs == ptr to PrefsBlock

		move.l	MyPrefs,d0
		bne.s	.ready
	;**alloc memory for pref. structures
		move.l	#prf_SIZEOF,d0
		move.l	#0,d1
		bsr.w	ADDALLOC
		move.l	d0,MyPrefs
		beq.w	noprefs.fatal
.ready
	;**set preferences to default
		movea.l	d0,a0
		bsr.w	DefaultPrefs
		lea	(error,pc),a0
		clr.b	(a0)
		lea	(diskObj,pc),a0
		clr.l	(a0)
	;*get tool types
		movea.l	(EB,PC),a6
		lea	(IconName,pc),a1
		moveq	#MinIconVer,d0
		jsr	(_LVOOpenLibrary,a6)	;"icon.library" V36
		lea	(IconBase,pc),a0
		move.l	d0,(a0)
		beq.s	noiconlib

		lea	ProgramName,a0
		movea.l	(IconBase,pc),a6
		jsr	(_LVOGetDiskObjectNew,a6)	;get "mines.info" or something
		lea	(diskObj,pc),a0
		move.l	d0,(a0)
		beq.s	noobj		;shouldn't happen...
		movea.l	d0,a0
		movea.l	(do_ToolTypes,a0),a4		;get ToolTypes array

		lea	PrefItems,a3
.itloop		movea.l	a4,a0			;tooltypes array
		move.l	(mpi_PItemName,a3),d0	;tooltype name
		beq.s	.done
		movea.l	d0,a1
		movea.l	d0,a5		;parameter for handlers
		jsr	(_LVOFindToolType,a6)
		tst.l	d0
		beq.s	.nextitem		;not present
	;call the mpi_PItemHandler
		movea.l	MyPrefs,a0	;param
		movea.l	d0,a1
		movea.l	(mpi_PItemHandler,a3),a2
		movem.l	a3-a6,-(sp)
		jsr	(a2)
		movem.l	(sp)+,a3-a6

.nextitem	lea	(mpi_SIZEOF,a3),a3
		bra.s	.itloop
.done

	;check mprf_Custom(s)
TESTCUSTOM	MACRO
		tst.w	(mprf_Custom\1,a0)
		bne.s	.ok\@
		move.w	(cpf_\1,a1),(mprf_Custom\1,a0)
.ok\@
		ENDM

		movea.l	MyPrefs,a0
		lea	CusPFSizes,a1
		TESTCUSTOM	Width
		TESTCUSTOM	Height
		TESTCUSTOM	Bombs

		movea.l	(diskObj,pc),a0
		jsr	(_LVOFreeDiskObject,a6)
noobj		move.l	(EB,PC),a6
		movea.l	(IconBase,pc),a1
		jsr	(_LVOCloseLibrary,a6)

exitprefs
		rts

;-------------------------------------------
noprefs.fatal	lea	noprefs_Text,a1
		lea	noprefs_Button,a2
		bsr.w	InformationReq
		bra.s	exitprefs
noiconlib	lea	(noicon_Text,pc),a1
		lea	(noicon_Button,pc),a2
		bsr.w	InformationReq
		bra.s	exitprefs

errBuf		dc.l	0
diskObj		dc.l	0
IconBase	dc.l	0
IconName	dc.b	'icon.library',0
noicon_Text	dc.b	'"icon.library" V36+ required to load preferences',0
noicon_Button	dc.b	'Continue',0
error		dc.b	0
		even

;****Some small subroutines-------------------------------
uppercaseD0	cmpi.b	#'a',d0
		blo.s	.noup
		cmpi.b	#'z',d0
		bhi.s	.noup
		subi.b	#'a'-'A',d0
.noup		rts

;*******Preference items handlers**************************************
;They're called with MyPrefs pointer in A0
;A1 contains address of next char to read (the parameter)
;a4-tooltypes array, a5-tooltype name, a6-IconBase

;---------------------------------------------
Pref_PubScreen	move.l	a1,a3
		moveq	#0,d0

.count		tst.b	(a1)+
		beq.s	.end
		addq.w	#1,d0
		bra.s	.count
.end		tst.l	d0		;no name after PUBSCREEN
		beq.s	.skip0
		addq.w	#1,d0
		moveq	#MEMF_PUBLIC,d1
		bsr.w	ADDALLOC
.skip0		movea.l	a3,a1
		move.l	d0,(mprf_PubNameAdr,a0)
		beq.s	.skip
		movea.l	d0,a2
.cp		move.b	(a1)+,(a2)+
		bne.s	.cp
.skip
		rts
;---------------------------------------------
Pref_ModeID	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	d0,(mprf_ModeID,a0)
		rts
;---------------------------------------------
Pref_SizeX	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD!NUMF_PLUS!NUMF_NONZERO,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,(mprf_ScrWidth,a0)
		rts
;---------------------------------------------
Pref_SizeY	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD!NUMF_PLUS!NUMF_NONZERO,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,(mprf_ScrHeight,a0)
		rts
;---------------------------------------------
Pref_CustomScreen
		move.b	#TRUE,(mprf_CustomScreen,a0)
		rts
;---------------------------------------------
Pref_WBLike	move.b	#TRUE,(mprf_WBLike,a0)
		rts
;---------------------------------------------
Pref_NotCenter	move.b	#TRUE,(mprf_CenterWindow,a0)	;CenterWindow=no
		rts
;---------------------------------------------
Pref_NotActiv	move.b	#TRUE,(mprf_WActivate,a0)
		rts
;---------------------------------------------
Pref_NoQuest	move.b	#TRUE,(mprf_Question,a0)
		rts
;---------------------------------------------
Pref_DeadQ	move.b	#TRUE,(mprf_DeadQ,a0)
		rts
;---------------------------------------------
Pref_NoRMouse	move.b	#TRUE,(mprf_RMouseGame,a0)
		rts
;---------------------------------------------------------
Pref_Warn	move.b	#TRUE,(mprf_Warn,a0)	;TRUE=DONOTWARN
		rts
;---------------------------------------------
Pref_CountD	move.b	#TRUE,(mprf_CountDown,a0)
		rts
;---------------------------------------------
Pref_Scale	move.b	#TRUE,(mprf_ScaleGfx,a0)
		rts
;---------------------------------------------
Pref_WinX	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD,d1	;check the number type
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,(mprf_WinX,a0)
		rts
;---------------------------------------------
Pref_WinY	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,(mprf_WinY,a0)
		rts
;---------------------------------------------
Pref_ZoomX	movea.l	a1,a2
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,(mprf_ZoomLeft,a0)
		move.w	d0,ZoomParams
		rts
;---------------------------------------------
Pref_ZoomY	movea.l	a1,a2
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,(mprf_ZoomTop,a0)
		move.w	d0,ZoomParams+2
		rts
;---------------------------------------------
	;**Set level
CHECKLEV	MACRO
		movea.l	a2,a0		;tooltype value
		lea	(tt\1,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		beq.s	.no\@
		movea.l	(sp)+,a0
		move.b	#L\1,(mprf_Level,a0)
		bra.s	.exit
.no\@
		ENDM

Pref_Level	move.l	a0,-(sp)
		movea.l	a1,a2		;store

		CHECKLEV EASY
		CHECKLEV MEDIUM
		CHECKLEV HARD
		CHECKLEV PROFI
		CHECKLEV CUSTOM
		lea	(errlev_Text,pc),a1
		bsr.w	ToolTypesError
		addq.l	#4,sp
.exit		rts

ttEASY	dc.b	'EASY',0
ttMEDIUM dc.b	'MEDIUM',0
ttHARD	dc.b	'HARD',0
ttPROFI	dc.b	'PROFI',0
ttCUSTOM dc.b	'CUSTOM',0
errlev_Text	dc.b	'Unknown level definition.',10
		dc.b	'Medium level used.',0
		cnop	0,4

;---------------------------------------------
Pref_CusWid	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD!NUMF_NONZERO!NUMF_PLUS,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,CusPFSizes+cpf_Width
		move.w	d0,(mprf_CustomWidth,a0)
		rts
;---------------------------------------------
Pref_CusHei	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD!NUMF_NONZERO!NUMF_PLUS,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,CusPFSizes+cpf_Height
		move.w	d0,(mprf_CustomHeight,a0)
		rts
;---------------------------------------------
Pref_CusBom	movea.l	a1,a2		;store
		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD!NUMF_NONZERO!NUMF_PLUS,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,CusPFSizes+cpf_Bombs
		move.w	d0,(mprf_CustomBombs,a0)
		rts
;---------------------------------------------
Pref_Font
	;**check if font=DEFAULT
		movem.l	a0/a1,-(sp)	;store
		movea.l	a1,a0	;returned by FindToolType
		lea	(defaultText,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		movem.l	(sp)+,a0/a1

		tst.l	d0
		bne.s	.default
	;**copy font name to a buffer
		lea	MyFontName,a2	;buffer (30 chars)
		move.l	a2,d0
		moveq	#30-1,d1	;max 30 chars
.loop		move.b	(a1)+,(a2)+	;copy font name
		dbeq	d1,.loop
		tst.b	MyFontName	;no name specified in tool types
		beq.w	.exit
		move.l	d0,(mprf_FontName,a0)
.exit		rts
.default	clr.l	(mprf_FontName,a0)
		rts

defaultText	dc.b	'DEFAULT',0
		cnop	0,4
;---------------------------------------------
Pref_FontSize
		movea.l	a1,a2		;store
	;**check if Fontsize=DESIGNED
		movem.l	a0/a1,-(sp)	;store
		movea.l	a1,a0	;returned by FindToolType
		lea	(designedText,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		movem.l	(sp)+,a0/a1	;restore

		tst.l	d0
		bne.s	.designed

		bsr.w	NumConvert
		tst.l	d1
		bne.w	errNum
		move.l	#NUMF_WORD!NUMF_NONZERO!NUMF_PLUS,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.w	errVal
		move.w	d0,(mprf_FontSize,a0)
		rts
.designed	clr.w	(mprf_FontSize,a0)	;font size of zero means DESIGNED
		rts

designedText	dc.b	'DESIGNED',0
		cnop	0,4
;---------------------------------------------
Pref_Iconify	;check for ICON,MENU
		movea.l	a1,a2
		movea.l	a0,a3
		movea.l	a2,a0
		lea	(iconIcon,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		bne.s	.icon

		movea.l	a2,a0
		lea	(iconMenu,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		bne.s	.menu

		lea	(badicon_Text,pc),a1
		bsr.w	ToolTypesError
.icon		move.b	#ICON_ICON,(mprf_Iconify,a3)
		rts
.menu		move.b	#ICON_MENU,(mprf_Iconify,a3)
		rts

badicon_Text	dc.b	'Only MENU or ICON allowed.',10
		dc.b	'Now ICON used.',0
iconMenu	dc.b	'MENU',0
iconIcon	dc.b	'ICON',0
		cnop	0,4
;---------------------------------------------
Pref_GfxType
	;check for STANDARD/MagicWB
		movea.l	a1,a2
		movea.l	a0,a3
		movea.l	a2,a0
		lea	(gfxStandard,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		bne.s	.stdgfx
		movea.l	a2,a0
		lea	(gfxMagicWB,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		bne.s	.magwbgfx

		lea	(badgfx_Text,pc),a1
		bsr.w	ToolTypesError

.stdgfx		move.b	#GFX_STANDARD,(mprf_GfxType,a3)
		rts

.magwbgfx	move.b	#GFX_MAGICWB,(mprf_GfxType,a3)
		rts

gfxStandard	dc.b	'STANDARD',0
gfxMagicWB	dc.b	'MAGICWB',0
badgfx_Text	dc.b	'Type of requested gfx not supported.',10
		dc.b	'Standard gfx used.',0
		cnop	0,4
;---------------------------------------------
Pref_Palette
	;check for STANDARD/MAGICWB/WBLIKE
		movea.l	a1,a2
		movea.l	a2,a0
		lea	(ptStandard,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		bne.w	Pref_PaletteStd

		movea.l	a2,a0
		lea	(ptMagicWB,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		bne.w	Pref_PaletteMag

		movea.l	a2,a0
		lea	(ptWBLike,pc),a1
		jsr	(_LVOMatchToolValue,a6)
		tst.l	d0
		bne.w	Pref_PaletteWB
	;else colortable defined palette
		move.b	#PAL_COLORTABLE,([MyPrefs],mprf_PaletteType)
		movea.l	a2,a1
		lea	ScreenPalette+4,a3	;skip first 2 words
		moveq	#PALENTRIES-1,d6
.go		bsr.w	NumConvert	;convert next palette entry
		tst.l	d1
		bne.s	errPalette
		move.l	#NUMF_LONG!NUMF_PLUS,d1
		bsr.w	CheckNum
		tst.l	d1
		bne.s	errPalette

	;convert to LoadRGB32 format
EXTANDSAVE	MACRO
		bfins	d1,d1{16:8}
		bfins	d1,d1{8:8}
		bfins	d1,d1{0:8}
		move.l	d1,(a3)+	;save entry
		ENDM

		bfextu	d0{8:8},d1	;RED
		EXTANDSAVE
		bfextu	d0{16:8},d1	;GREEN
		EXTANDSAVE
		bfextu	d0{24:8},d1	;BLUE
		EXTANDSAVE

.seek		move.b	(a1)+,d0	;seek to next entry (",")
		beq.s	.ready		;zero=eol
		cmpi.b	#',',d0
		bne.s	.seek
		dbra	d6,.go
.ready
		rts

errPalette
		lea	(errpal_Text,pc),a1
		lea	(errpal_Button,pc),a2
		bsr.w	InformationReq
		;no rts!

;----------
Pref_PaletteStd	move.b	#PAL_STANDARD,([MyPrefs],mprf_PaletteType)
		lea	DefaultPalette,a2	;copy once again
CopyPalette	lea	ScreenPalette,a3
		moveq	#PALENTRIES*3+2-1,d0
.loop		move.l	(a2)+,(a3)+
		dbra	d0,.loop
		rts

;----------
Pref_PaletteMag	move.b	#PAL_MAGICWB,([MyPrefs],mprf_PaletteType)
		lea	MagicPalette,a2
		bra.s	CopyPalette

;----------
Pref_PaletteWB	move.b	#PAL_WBLIKE,([MyPrefs],mprf_PaletteType)
		movea.l	IntuiBase,a6
		lea	wbName,a0
		jsr	(_LVOLockPubScreen,a6)	;lock Workbench
		lea	(lockedWB,pc),a0
		move.l	d0,(a0)
		beq.s	Pref_PaletteStd		;couldn't lock WB
		movea.l	d0,a0

		movea.l	(sc_ViewPort+vp_ColorMap,a0),a0	;cm
		moveq	#0,d0				;first colors
		moveq	#PALENTRIES,d1			;n-colors
		lea	ScreenPalette+4,a1		;table
		movea.l	_GfxBase,a6
		jsr	(_LVOGetRGB32,a6)

		movea.l	IntuiBase,a6
		suba.l	a0,a0
		movea.l	(lockedWB,pc),a1
		jsr	(_LVOUnlockPubScreen,a6)	;unlock WB
		rts

lockedWB	dc.l	0
ptStream	dc.l	0,0
ptStandard	dc.b	'STANDARD',0
ptMagicWB	dc.b	'MAGICWB',0
ptWBLike	dc.b	'WBLIKE',0
errpal_Text	dc.b	'Error in palette definition.',10
		dc.b	'(See Tool Types)',10
		dc.b	'Standard palette used.',0
errpal_Button	dc.b	'I',39,'ll have a look.',0

		cnop	0,4
;---------------------------------------------------------
errNum		;number expected
		;IN:a5-tooltype name  a2-tooltype value
		lea	(noval_Text,pc),a1
		bsr.w	ToolTypesError
		rts
errVal		;invalid value found
		;IN:a5-tool type name  a2-tooltype val.
		lea	(badval_Text,pc),a1
		bsr.w	ToolTypesError
		rts

noval_Text	dc.b	'Number expected.',0
badval_Text	dc.b	'Invalid value defined.',0
		cnop	0,4
;----------------------------------------------------------------
ToolTypesError	;IN:a1-explain text  a5-tooltype name  a2-tooltype param.
		movem.l	d1-d7/a0-a6,-(sp)
		lea	(tte_argarray,pc),a4
		move.l	a5,(a4)
		move.l	a2,(4,a4)
		move.l	a1,(8,a4)
		lea	(tte_Text,pc),a1
		lea	(tte_Button,pc),a2
		movea.l	_ReqToolsBase,a6
		suba.l	a3,a3
		lea	IReqTags,a0
		jsr	(_LVOrtEZRequestA,a6)
		movem.l	(sp)+,d1-d7/a0-a6
		rts

tte_argarray	dc.l	0,0,0
tte_Text	dc.b	'Error in Tool Types.',10
		dc.b	'"%s=%s"',10,'%s',0
tte_Button	dc.b	'I',39,'ll have a look.',0
		cnop	0,4
;----------------------------------------------------------------
CheckNum	;checkes the LONG number in d0 if it matches
		;the flags in d1
		;RESULTS: d1.l=0 => O.K. else error
;NUMF_BYTE	= 1	;not implemented
NUMF_LONG	= 0	;this is default
NUMF_WORD	= 1<<2

NUMF_NONZERO	= 1<<6	;values != 0
NUMF_PLUS	= 1<<7	;values >= 0
NUMF_MINUS	= 1<<8	;<0

		move.l	d1,d2
		andi.l	#NUMF_WORD,d2
		beq.s	.next
		move.w	d0,d3		;do not touch d0
		ext.l	d3
		cmp.l	d0,d3
		bne.s	cn_NotMatch

		move.l	d1,d2
		andi.l	#NUMF_NONZERO,d2	;test for non zero?
		beq.s	.nextw2			;no
		tst.l	d0
		beq.s	cn_NotMatch
.nextw2		move.l	d1,d2
		andi.l	#NUMF_PLUS,d2
		beq.s	.nextw3
		tst.w	d0
		bmi.s	cn_NotMatch
.nextw3		move.l	d1,d2
		andi.l	#NUMF_MINUS,d2
		beq.s	.Matched
		tst.w	d0
		bpl.s	cn_NotMatch
		bra.s	.Matched

	;next is for LONG
.next		move.l	d1,d2
		andi.l	#NUMF_NONZERO,d2	;test for non zero?
		beq.s	.next2			;no
		tst.l	d0
		beq.s	cn_NotMatch
.next2		move.l	d1,d2
		andi.l	#NUMF_PLUS,d2
		beq.s	.next3
		tst.l	d0
		bmi.s	cn_NotMatch
.next3		move.l	d1,d2
		andi.l	#NUMF_MINUS,d2
		beq.s	.Matched
		tst.l	d0
		bpl.s	cn_NotMatch
.Matched
		moveq	#0,d1		;matched
		rts
cn_NotMatch	moveq	#-1,d1
		rts
;***********************************************************
NumConvert	;in a1-pointer to an ASCII number terminated by zero byte
		;or by a ","
		;examples: -246, 3467, 0xfc3A, $D34e, -&H1, &h23F
		;Octal and binar numbers are not handled
		;results in d0.l, if d1.l=0 then succes else error

		move.l	a2,-(sp)	;store
	;**find out sign
		clr.b	Sign	;plus
		cmpi.b	#'-',(a1)
		bne.s	.plus
		st	Sign
		bra.s	.skip
.plus		cmpi.b	#'+',(a1)
		bne.s	mpok
.skip		addq.w	#1,a1	;skip sign
mpok
	;**find out about the type  (DEC/HEX available at the moment...)
		movea.l	a1,a2		;seek to end and uppercase
.loop		move.b	(a2),d0
		bsr.w	uppercaseD0
		move.b	d0,(a2)+
		cmpi.b	#',',d0
		beq.s	.1
		tst.b	d0
		bne.s	.loop
.1		subq.w	#1,a2		;points to the end byte

		cmpa.l	a1,a2
		beq.w	nc_invalid	;just no number there

		move.b	(a1),d1
		move.w	(a1),d2

		cmpi.b	#'$',d1
		beq.s	nc_hex1
		cmpi.w	#'&H',d2
		beq.s	nc_hex2
		cmpi.w	#'0X',d2
		beq.s	nc_hex2
	;else decimal
nc_dec		moveq	#1,d2	;10^0 .. 10^1 .. 10^2 ..
		moveq	#0,d0	;result
.decLoop	move.b	-(a2),d1
		cmpi.b	#'0',d1		;is the char in range 0-9
		blo.s	nc_invalid	;no
		cmpi.b	#'9',d1
		bhi.s	nc_invalid	;no
		subi.b	#'0',d1
		extb	d1
		mulu.l	d2,d1		;d1:=d1*10^x
		add.l	d1,d0
		bvs.s	nc_invalid	;overflow?
		mulu.l	#10,d2
		bvs.s	nc_invalid
		cmpa.l	a2,a1
		bne.s	.decLoop
		moveq	#0,d1		;succes
		bra.s	SignTest

nc_hex2		addq.w	#1,a1	;skip '&H' '0X'
nc_hex1		addq.w	#1,a1	;skip '$'
		moveq	#0,d0
		moveq	#31-3,d2
.hexLoop	move.b	-(a2),d1
		cmpi.b	#'0',d1		;test range (0..9)
		blo.s	nc_invalid
		cmpi.b	#'9',d1
		bls.s	.ok

		cmpi.b	#'A',d1		;test (A..F)
		blo.s	nc_invalid
		cmpi.b	#'F',d1
		bhi.s	nc_invalid
		subi.b	#'A'-'9'-1,d1
.ok		subi.b	#'0',d1
		bfins	d1,d0{d2:4}
		cmpa.l	a1,a2
		beq.s	nc_HexReady
		subq.w	#4,d2		;next nibble
		bpl.s	.hexLoop	;exit if out of longword
nc_HexReady	moveq	#0,d1		;succes

SignTest	tst.b	Sign
		beq.s	.ok
		neg.l	d0
.ok		movea.l	(sp)+,a2
		rts

nc_invalid	moveq	#-1,d1	;error
		moveq	#0,d0
		movea.l	(sp)+,a2
		rts
;*****************************************************************
GetScreenCenter	;gets center of the visible part of screen
		movea.l	MyScreen,a5
	;get screen and window sizes
		movea.l	(sc_ViewPort+vp_ColorMap,a5),a4
		movea.l	(cm_vpe,a4),a4	;ViewPortExtra
	;Winx=(ScrWidth-WinWidth)/2
		move.w	(vpe_DisplayClip+ra_MaxX,a4),d1
		sub.w	(vpe_DisplayClip+ra_MinX,a4),d1
		move.w	(sc_Width,a5),d0
		cmp.w	d0,d1		;if screen width < display clip
		bls.s	.dc1
		move.w	d0,d1
.dc1		asr.w	#1,d1	;/2
		sub.w	(sc_ViewPort+vp_DxOffset,a5),d1	;offset
		move.w	d1,CenterPointX

	;WinY=(ScrHeight-WinHeight)/2
		move.w	(vpe_DisplayClip+ra_MaxY,a4),d1
		sub.w	(vpe_DisplayClip+ra_MinY,a4),d1
		move.w	(sc_Height,a5),d0
		cmp.w	d0,d1
		bls.s	.dc2
		move.w	d0,d1
.dc2		asr.w	#1,d1	;/2
		sub.w	(sc_ViewPort+vp_DyOffset,a5),d1
		move.w	d1,CenterPointY
		rts

;*****************************************************************
SetWinParams	;sets the required window size and placement

	;**Get the PlayField size
.prefs		movea.l	MyPrefs,a0
		move.b	(mprf_Level,a0),d0
		bne.s	.cont
		move.b	#LMEDIUM,d0
		move.b	d0,(mprf_Level,a0)
.cont		lea	DefPFSizes,a0
		ext.w	d0
		move.w	(a0,d0.w*8),PFWidth
		move.w	(2,a0,d0.w*8),PFHeight
		move.w	(4,a0,d0.w*8),PFBombs

		clr.b	d5
	;check for minimal height
		cmpi.w	#MINPFHEIGHT,PFHeight
		bhs.s	.cw
		move.w	#MINPFHEIGHT,PFHeight
		move.w	#MINPFHEIGHT,(2,a0,d0.w*8)
		move.w	#MINPFHEIGHT,([MyPrefs],mprf_CustomHeight)
		move.w	d0,-(sp)		;store
		lea	toosmall_Text,a1
		lea	toosmall_Button,a2
		bsr.w	InformationReq
		move.w	(sp)+,d0
		st	d5			;set flag
	;check for minimal width
.cw		move.w	MinRowBut,d1
		cmp.w	PFWidth,d1
		bls.s	.well
		move.w	d1,(a0,d0.w*8)
		move.w	d1,([MyPrefs],mprf_CustomWidth)
		move.w	d1,PFWidth
		tst.b	d5
		bne.s	.well		;don't bother with messages anymore
		move.w	d0,-(sp)		;store
		lea	toosmall_Text,a1
		lea	toosmall_Button,a2
		bsr.w	InformationReq
		move.w	(sp)+,d0
.well
		move.w	PFWidth,d1		;check for maximum mines
		mulu.w	PFHeight,d1
		subq.w	#1,d1
		cmp.w	PFBombs,d1
		bhs.s	.tmok
		move.w	d1,(4,a0,d0.w*8)
		move.w	d1,([MyPrefs],mprf_CustomBombs)
		move.w	d1,PFBombs
		lea	toomuch_Text,a1
		lea	toomuch_Button,a2
		bsr.w	InformationReq
.tmok

		addq.w	#2,PFWidth
		addq.w	#2,PFHeight


	;**Set window size
		move.w	ButtHeight,d0	;my bar size
		add.w	d0,d0
		move.w	d0,MyBarHeight

		move.w	PFWidth,d0	;Inner sizes
		subq.w	#2,d0
		mulu.w	ButtWidth,d0
		move.w	d0,InnWidth
		move.w	PFHeight,d0
		subq.w	#2,d0
		mulu.w	ButtHeight,d0
		add.w	MyBarHeight,d0
		move.w	d0,InnHeight

setWsize	movea.l	MyScreen,a0
		moveq	#0,d2
		move.w	d2,d3
		move.w	d2,d4
		move.w	d2,d5
		move.b	(sc_WBorLeft,a0),d2
		move.b	(sc_WBorRight,a0),d3
		move.b	(sc_WBorTop,a0),d4
		add.w	([sc_Font,a0],ta_YSize),d4
		addq.w	#1,d4
		move.w	d4,winBarH
		move.b	(sc_WBorBottom,a0),d5

		move.w	InnWidth,d0	;width
		add.w	d2,d0		;BorderLeft
		add.w	d3,d0		;      Right
		move.w	d0,WinWidth

		move.w	InnHeight,d0	;height
		add.w	d4,d0		;BorderTop
		add.w	d5,d0		;      Bottom
		move.w	d0,WinHeight

		move.w	d2,MinX
		move.w	d2,MinPFX	;(for future?)
		move.w	d4,MinY
		add.w	MyBarHeight,d4
		move.w	d4,MinPFY

	;**Check if window is bigger than screen
		movea.l	MyScreen,a5
		move.w	WinWidth,d0
		cmp.w	(sc_Width,a5),d0	;d0<=sc_Width?
		bls.s	.skip
		move.w	(sc_Width,a5),WinWidth	;validate
		st	Disable
		st	DisplayTooBig	;inform the user
	;  set new InnWidth
		movea.l	MyScreen,a0
		move.b	(sc_WBorLeft,a0),d0
		add.b	(sc_WBorRight,a0),d0
		ext.w	d0
		sub.w	WinWidth,d0
		neg.w	d0
		move.w	d0,InnWidth

.skip		move.w	WinHeight,d0
		cmp.w	(sc_Height,a5),d0 ;d0<=sc_Height?
		bls.s	.skip2
		move.w	(sc_Height,a5),WinHeight
		st	Disable
		st	DisplayTooBig	;inform the user
	;  set new InnHeight
		movea.l	MyScreen,a0
		move.b	(sc_WBorBottom,a0),d0
		ext.w	d0
		add.w	winBarH,d0
		sub.w	WinHeight,d0
		neg.w	d0
		move.w	d0,InnHeight

.skip2
	;**Set placement for the window
		movea.l	MyPrefs,a0
	;  Get type of placement from prefs
		tst.b	(mprf_CenterWindow,a0)
		beq.s	InTheCenter	;default
	;  1. Abs position
		tst.b	CPointSet
		bne.s	InTheCenter
		st	CPointSet
		move.w	(mprf_WinX,a0),d0	;set new center point
		move.w	d0,WinX
		move.w	WinWidth,d1
		asr.w	#1,d1
		add.w	d1,d0
		move.w	d0,CenterPointX
		move.w	(mprf_WinY,a0),d0
		move.w	d0,WinY
		move.w	WinHeight,d1
		asr.w	#1,d1
		add.w	d1,d0
		move.w	d0,CenterPointY
		bra.s	itc_skip
	;  2. in the center of default screen
InTheCenter	move.w	WinWidth,d1
		asr.w	#1,d1		;/2
		sub.w	CenterPointX,d1
		neg.w	d1
		move.w	d1,WinX
		move.w	WinHeight,d1
		asr.w	#1,d1
		sub.w	CenterPointY,d1
		neg.w	d1
		move.w	d1,WinY
itc_skip
		move.w	PFWidth,d0
		subq.w	#2,d0
		mulu.w	ButtWidth,d0
		move.w	d0,PFXPix
		move.w	PFHeight,d0
		subq.w	#2,d0
		mulu.w	ButtHeight,d0
		move.w	d0,PFYPix
		rts
;-----------------------------------------------------------
SetZoomParams
	;set zoom parameters
		move.w	DefPFSizes+(LEASY*8),d0	;PFWidth for EASY level
		mulu.w	ButtWidth,d0
		move.b	([MyScreen],sc_WBorLeft),d1
		add.b	([MyScreen],sc_WBorRight),d1
		ext.w	d1
		add.w	d1,d0
		lea	ZoomParams,a0
		tst.w	(a0)		;ZoomLeft already set by LoadPreferences?
		bpl.s	.yes1
		move.w	WinX,(a0)	;left
		move.w	WinX,([MyPrefs],mprf_ZoomLeft)
.yes1		tst.w	(2,a0)		;ZoomTop already set by LoadPreferences?
		bpl.s	.yes2
		move.w	WinY,(2,a0)	;top
		move.w	WinY,([MyPrefs],mprf_ZoomTop)

.yes2		move.w	d0,(4,a0)	;width
		move.w	winBarH,(6,a0)	;height
		move.w	d0,ZoomWidth
		move.w	winBarH,ZoomHeight
		rts
;-----------------------------------------------------------
SetWinTagList	;Set values got from SetWinParams to MyWinTags
		lea	MyWinTags,a0
SetTagsLoop	move.l	(a0)+,d0
		beq.s	.done		;TAG_DONE
		cmpi.l	#WA_InnerWidth,d0
		beq.s	.innwidth
		cmpi.l	#WA_InnerHeight,d0
		beq.s	.innheight
		cmpi.l	#WA_Left,d0	;set WinX?
		beq.s	.left
		cmpi.l	#WA_Top,d0	;set WinY?
		beq.s	.top
		cmpi.l	#WA_Activate,d0
		beq.s	.activate
		cmpi.l	#WA_CustomScreen,d0
		beq.s	.custom
		cmpi.l	#WA_PubScreenName,d0
		beq.s	.pubscreen

.nexttag	addq.w	#4,a0	;skip ti_Data
		bra.s	SetTagsLoop

.done		rts		;SetWinTags EXIT

.innwidth	move.w	InnWidth,(2,a0)
		bra.s	.nexttag
.innheight	move.w	InnHeight,(2,a0)
		bra.s	.nexttag
.left		move.w	WinX,(2,a0)
		bra.s	.nexttag
.top		move.w	WinY,(2,a0)
		bra.s	.nexttag

.activate	move.b	([MyPrefs],mprf_WActivate),d0
		not.b	d0	;inversed logic
		extb	d0
		move.l	d0,(a0)		;WA_Activate flag
		bra.s	.nexttag

.custom		move.l	MyScreen,(a0)
		tst.b	([MyPrefs],mprf_CustomScreen)
		bne.s	.nexttag
		move.l	#TAG_IGNORE,(-4,a0)
		bra.s	.nexttag

.pubscreen	move.l	([MyPrefs],mprf_PubNameAdr),(a0)
		bra.s	.nexttag
;*************************************************************************
;*********LOAD FILE************

LOAD_FILE	;IN: d0-filename
		;OUT:d0-address of loaded data	ERROR=0
		;    d1-lenght  of ^

		movem.l	d2-d7/a0-a6,-(sp)
		movea.l	DosBase,a6
		clr.l	lf_buffer
		clr.l	lf_fileLen
	;***get lenght of the source file
		move.l	d0,lf_filename

		move.l	lf_filename,d1		;filename
		move.l	#ACCESS_READ,d2	;acces mode
		jsr	(_LVOLock,a6)	;lock the file
		tst.l	d0
		beq.w	lf_nolock
		move.l	d0,lf_fileLock	;store pointer

		move.l	lf_fileLock,d1
		move.l	#lf_fib,d2		;file info block
		jsr	(_LVOExamine,a6)	;fill the FIB structure
		tst.l	d0
		beq.s	lf_unlock
		move.l	lf_fib+$7c,lf_fileLen

	;***Allocate memory buffer
		move.l	lf_fileLen,d0	;file lenght=size of buffer
		moveq	#MEMF_PUBLIC,d1
		bsr	ADDALLOC
		move.l	d0,lf_buffer
		beq.s	lf_no_mem

	;***open file to be loaded
		move.l	lf_filename,d1	;source filename
		move.l	#MODE_OLDFILE,d2 ;acces mode
		jsr	(_LVOOpen,a6)	;open file
		move.l	d0,lf_fhandle
		beq.s	lf_erroropen

	;***load file to buffer
		move.l	lf_fhandle,d1	;file
		move.l	lf_buffer,d2
		move.l	lf_fileLen,d3
		jsr	(_LVORead,a6)	;read from file
		cmp.l	d0,d3
		bne.s	lf_Error

EndOfFile ;***file loaded->close and unlock
lf_close	move.l	lf_fhandle,d1
		jsr	(_LVOClose,a6)
lf_unlock	move.l	lf_fileLock,d1
		jsr	(_LVOUnLock,a6)

lf_nolock	move.l	lf_buffer,d0
		move.l	lf_fileLen,d1
		movem.l	(sp)+,d2-d7/a0-a6
		rts
;------------------
lf_Error	clr.l	lf_buffer
		bra.s	lf_close
lf_no_mem
lf_erroropen	clr.l	lf_buffer
		bra.s	lf_unlock
;**************SAVE FILE*******************************************************
SAVE_FILE	;IN: d0-filename
		;    d1-data
		;    d2-lenght
		;OUT: d0=0 => O.K.

		movem.l	d1-d7/a0-a6,-(sp)
		movea.l	DosBase,a6
		move.l	d0,lf_filename
		move.l	d1,d4		;store
		move.l	d2,d5

	;***Open file
		move.l	lf_filename,d1
		move.l	#MODE_NEWFILE,d2
		jsr	(_LVOOpen,a6)	;open file
		move.l	d0,lf_fhandle
		beq.s	sf_erroropen
	;***write buffer
		move.l	lf_fhandle,d1	;fhandle
		move.l	d4,d2		;buffer
		move.l	d5,d3		;lenght
		jsr	(_LVOWrite,a6)
		cmp.l	d0,d3
		bne.s	sf_errorwrite

	;***saved->close file
		clr.l	-(sp)
sf_close	move.l	lf_fhandle,d1
		jsr	(_LVOClose,a6)

sf_exit
		move.l	(sp)+,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts
sf_erroropen	move.l	#-1,-(sp)
		bra.s	sf_exit
sf_errorwrite	move.l	#-1,-(sp)
		bra.s	sf_close
;*****************************************************************
ADDALLOC	;IN - d0-size,d1-flags
		movem.l	a0/a1/a6,-(sp)
		movea.l	(EB,PC),a6
		move.l	d0,-(sp)	;store size
		jsr	(_LVOAllocMem,a6)
		movea.l	AllocPos,a0
		move.l	d0,(a0)+	;addr
		beq.s	.nomem
		addq.l	#8,AllocPos
.nomem		move.l	(sp)+,(a0)	;size
		movem.l	(sp)+,a0/a1/a6
		rts
;*****************************************************************
;********FreeAllMemory	;..also if nothing was allocated.
FreeAllMemory	move.l	(EB,PC),a6
		lea	Allocated,a5
FM_Loop		move.l	(a5)+,d0	;Get addr
		beq.s	FM_Done		;End of structure?
		movea.l	d0,a1
		move.l	(a5)+,d0	;Get size
		jsr	(_LVOFreeMem,a6)	;Free block
		bra.s	FM_Loop
FM_Done		rts
;*****************************************************************
FreeMemBlock	;IN: a1-address
		;Searches in the "Allocated" structure
		;for matching values and frees memory
		movem.l	d0/d1/a0/a6,-(sp)
		lea	Allocated,a0
fmb_next	move.l	(a0)+,d1
		beq.s	fmb_NotFound
		move.l	(a0)+,d0	;size
		cmpa.l	d1,a1	;check address
		bne.s	fmb_next
	;found. Free it now.
		move.l	a0,-(sp)	;store structure position
		movea.l	(EB,PC),a6
		jsr	(_LVOFreeMem,a6)
	;cut item from the structure
		movea.l	(sp)+,a0
		movea.l	a0,a1
		subq.l	#8,a0	;free block
.loop		move.l	(a1)+,(a0)+
		beq.s	.ok
		move.l	(a1)+,(a0)+
		bra.s	.loop
.ok		subq.l	#8,AllocPos	;structure is now shorter
fmb_NotFound	movem.l	(sp)+,d0/d1/a0/a6
		rts

;---------------------------------------------------------------------------
InitSemaphore	;IN: NIL  OUT: d0 - addr. of the structure or FALSE
		;Unfortunally, when calling this routine the ADDALLOC
		;system is not initialized yet, so don't forget to free
		;"Semaphore" manually (call "FreeSemaphore")

		movea.l	(EB,PC),a6
		move.l	#SS_SIZE,d0	;Signal semaphore - sizeof
		move.l	#MEMF_PUBLIC!MEMF_CLEAR,d1
		jsr	(_LVOAllocMem,a6)
		move.l	d0,Semaphore
		beq.s	.error
		move.l	d0,d2	;store
		movea.l	(EB,PC),a6
		movea.l	d0,a0
		jsr	(_LVOInitSemaphore,a6)	;void()
		move.l	d2,d0	;ret. code
.error		rts

FreeSemaphore	movea.l	(EB,PC),a6
		movea.l	Semaphore,a1
		move.l	#SS_SIZE,d0
		jsr	(_LVOFreeMem,a6)
		rts
;---------------------------------------------------------------------------
CallOtherSweeper
		bsr.s	InitSemaphore
		tst.l	d0
		beq.s	.noSemaphore

		movea.l	(EB,PC),a6
		jsr	(_LVOCreateMsgPort,a6)
		tst.l	d0
		beq.s	.exit
		movea.l	d0,a4	;store

		movea.l	Semaphore,a0
		jsr	(_LVOObtainSemaphore,a6)
		lea	(MinesPortName,pc),a1
		jsr	(_LVOFindPort,a6)
		tst.l	d0
		beq.s	.nomines
		movea.l	d0,a3

		lea	(COSMsg,pc),a1		;msg
		move.l	a4,(MN_REPLYPORT,a1)
		move.w	#am_ID+4,(MN_LENGTH,a1)
		move.l	#'MINE',(am_ID,a1)
		movea.l	a3,a0			;port
		jsr	(_LVOPutMsg,a6)		;hey! wake up!

		movea.l	a4,a0
		jsr	(_LVOWaitPort,a6)	;wait for reply

		addq.l	#4,a7	;rts
		movea.l	Semaphore,a0
		jsr	(_LVOReleaseSemaphore,a6)
		bsr.w	FreeSemaphore
		bra.s	.skp
.nomines
		movea.l	Semaphore,a0
		jsr	(_LVOReleaseSemaphore,a6)
.skp
		movea.l	a4,a0
		jsr	(_LVODeleteMsgPort,a6)
		rts

.exit
	;free Semaphore structure
		bsr.w	FreeSemaphore

.noSemaphore	addq.l	#4,a7	;rts
		rts

COSMsg		dcb.b	am_ID+4,0
		cnop	0,4
;*****************************************************************
EB		dc.l	0	;****ExecBase
;*****************************************************************
		SECTION	wbstartup,CODE
_IconStart	movem.l	d0/a0,-(sp)	;prik. radka
		sub.l	a1,a1		;a1=0 - vlastni task
		movea.l	4.w,a6
		jsr	(_LVOFindTask,a6)
		movea.l	d0,a2
		tst.l	($ac,a2)		;z WB?  pr_CLI
		bne.s	From_CLI		; ne
* from WorkBench *
		lea	($5c,a2),a2	;pr_MsgPort
		move.l	a2,a0
		jsr	(_LVOWaitPort,a6)
		move.l	a2,a0
		jsr	(_LVOGetMsg,a6)
		lea	(WBmessage,PC),a0
		move.l	d0,(a0)
		movem.l	(sp)+,d0/a0
		bra.s	CoWB_run
From_CLI	movem.l	(sp)+,d0/a0	;d0 = d×lka pÒÉk. ÒÁdky vÃetnÅ LF ($a)
					;a0 ->na 1. znak ÒÁdky (Ucase<>Lcase)
CoWB_run	jsr	_main
CoWB_end	move.l	d0,-(sp)	;returncode
* nÁvrat do CLI | WB ? *-------------------------

		tst.l	(WBmessage,pc)
		beq.s	To_CLI
		movea.l	4.w,a6
		jsr	(_LVOForbid,a6)
		move.l	(WBmessage,pc),a1
		jsr	(_LVOReplyMsg,a6)
To_CLI		move.l	(sp)+,d0			;Errorcode
		rts

WBmessage	dc.l	0

		SECTION	GfxData,DATA_C
		INCDIR	"SOURCES:Mines/gfx/"
rawFlag		INCBIN	"Flag.raw"
rawNoFlag	INCBIN	"NoFlag.raw"
rawBomb		INCBIN	"Bomb.raw"
rawBlowed	INCBIN	"Blowed.raw"
rawMagicFlag	INCBIN	"MagicFlag.raw"
rawMagicNoFlag	INCBIN	"MagicNoFlag.raw"
rawMagicBomb	INCBIN	"MagicBomb.raw"
rawMagicBlowed	INCBIN	"MagicBlowed.raw"

rawSun		INCBIN	"Sun.raw"
rawSunPressed	INCBIN	"Sun.pressed.raw"
rawSunLoose	INCBIN	"Sun.loose.raw"
rawSunWon	INCBIN	"Sun.won.raw"
rawNumbers	INCBIN	"Numbers1bpl.raw"

		SECTION	MinesData,DATA
	;**Bitmap structures for predefined gfx
bmapFlag	dc.w	((BUTMINX-1)/16+1)*2	;bm_BytesPerRow
		dc.w	BUTMINY			;bm_Rows
		dc.b	0			;bm_Flags
		dc.b	BUTMAXBPL		;bm_Depth
		dc.w	0			;bm_Pad
		dc.l	0,0,0,0,0,0,0,0

bmapNoFlag	dc.w	((BUTMINX-1)/16+1)*2	;bm_BytesPerRow
		dc.w	BUTMINY			;bm_Rows
		dc.b	0			;bm_Flags
		dc.b	BUTMAXBPL		;bm_Depth
		dc.w	0			;bm_Pad
		dc.l	0,0,0,0,0,0,0,0

bmapBomb	dc.w	((BUTMINX-1)/16+1)*2	;bm_BytesPerRow
		dc.w	BUTMINY			;bm_Rows
		dc.b	0			;bm_Flags
		dc.b	BUTMAXBPL		;bm_Depth
		dc.w	0			;bm_Pad
		dc.l	0,0,0,0,0,0,0,0

bmapBlowed	dc.w	((BUTMINX-1)/16+1)*2	;bm_BytesPerRow
		dc.w	BUTMINY			;bm_Rows
		dc.b	0			;bm_Flags
		dc.b	BUTMAXBPL		;bm_Depth
		dc.w	0			;bm_Pad
		dc.l	0,0,0,0,0,0,0,0

	;**image structures for gadget-sun
img_Sun		dc.w	0		;ig_LeftEdge 
		dc.w	0		;ig_TopEdge
		dc.w	SUNMINX		;ig_Width (though data is word-aligned)
		dc.w	SUNMINY		;ig_Height
		dc.w	SUNMAXBPL	;ig_Depth
		dc.l	rawSun		;ig_ImageData
		dc.b	%111,0
		dc.l	0
img_SunPressed	dc.w	0		;ig_LeftEdge 
		dc.w	0		;ig_TopEdge
		dc.w	SUNMINX		;ig_Width (though data is word-aligned)
		dc.w	SUNMINY		;ig_Height
		dc.w	SUNMAXBPL	;ig_Depth
		dc.l	rawSunPressed	;ig_ImageData
		dc.b	%111,0
		dc.l	0
img_SunLoose	dc.w	0		;ig_LeftEdge 
		dc.w	0		;ig_TopEdge
		dc.w	SUNMINX		;ig_Width (though data is word-aligned)
		dc.w	SUNMINY		;ig_Height
		dc.w	SUNMAXBPL	;ig_Depth
		dc.l	rawSunLoose	;ig_ImageData
		dc.b	%111,0
		dc.l	0
img_SunWon	dc.w	0		;ig_LeftEdge 
		dc.w	0		;ig_TopEdge
		dc.w	SUNMINX		;ig_Width (though data is word-aligned)
		dc.w	SUNMINY		;ig_Height
		dc.w	SUNMAXBPL	;ig_Depth
		dc.l	rawSunWon	;ig_ImageData
		dc.b	%111,0
		dc.l	0

img_Number	dc.w	0		;ig_LeftEdge 
		dc.w	0		;ig_TopEdge
		dc.w	NUMWIDTH	;ig_Width (though data is word-aligned)
		dc.w	NUMHEIGHT	;ig_Height
		dc.w	2		;ig_Depth
		dc.l	0		;ig_ImageData
		dc.b	%100,0		;ig_PlanePick,ig_PlaneOnOff
		dc.l	0


SunGadget	dc.l	0		;gg_NextGadget
		dc.w	0		;gg_LeftEdge
		dc.w	0		;gg_TopEdge
		dc.w	SUNMINX		;gg_Width
		dc.w	SUNMINY		;gg_Height
		dc.w	GFLG_GADGIMAGE!GFLG_GADGHIMAGE	;gg_Flags
		dc.w	GACT_RELVERIFY!GACT_IMMEDIATE	;gg_Activation
		dc.w	0		;gg_GadgetType
		dc.l	0		;gg_GadgetRender
		dc.l	0		;gg_SelectRender
		dc.l	0		;gg_GadgetText		; text for this gadget;
		dc.l	0		;gg_MutualExclude 	; obsolete
		dc.l	0		;gg_SpecialInfo
		dc.w	0		;gg_GadgetID	; user-definable ID field
		dc.l	0		;gg_UserData	;(ignored by Intuit)
Gadget_Image	dc.l	0
;-----------------EndGadget
;-------------------------------------------------------------------
IntuiName	dc.b	'intuition.library',0
GfxName		dc.b	'graphics.library',0
DosName		dc.b	'dos.library',0
ReqToolsName	dc.b	'reqtools.library',0
DiskFontName	dc.b	'diskfont.library',0
GadtoolsName	dc.b	'gadtools.library',0
UtilityName	dc.b	'utility.library',0

TimDevName	dc.b	'timer.device',0

wbName		dc.b	'Workbench',0

	;**This is the main window**********************************
		cnop	0,4
MyWinTags
		dc.l	WA_Left,0
		dc.l	WA_Top,0
		dc.l	WA_InnerWidth,0
		dc.l	WA_InnerHeight,0

		dc.l	WA_CustomScreen,0
		dc.l	WA_Title,MyWinTitle
		dc.l	WA_ScreenTitle,MyWinScrTitle
		dc.l	WA_PubScreenName,0

	;  **some flags now
		dc.l	WA_Activate,FALSE	;default is false
		dc.l	WA_DragBar,TRUE
		dc.l	WA_DepthGadget,TRUE
		dc.l	WA_CloseGadget,TRUE
		dc.l	WA_Zoom,ZoomParams
		dc.l	WA_SmartRefresh,TRUE
		dc.l	WA_NewLookMenus,TRUE	;V39
		dc.l	WA_ReportMouse,TRUE
		dc.l	WA_IDCMP,0
		dc.l	WA_Gadgets,0
		dc.l	WA_RptQueue,0
		dc.l	WA_MouseQueue,3

		dc.l	TAG_DONE,0

ZoomParams	dc.w	-1,-1,0,0

	;***O.k. That was my window***********************************
	;***Now the screen
MyScreenTags
		dc.l	SA_Title,MyScrTitle
		dc.l	SA_Type,CUSTOMSCREEN
		dc.l	SA_MinimizeISG,TRUE		;V40
		dc.l	SA_AutoScroll,TRUE
		dc.l	SA_LikeWorkbench,0	;V39

		dc.l	SA_Depth,BUTMAXBPL
		dc.l	SA_Left,0
		dc.l	SA_Top,0
		dc.l	SA_Width,0	;set by OpenMyScreen
		dc.l	SA_Height,0
		dc.l	SA_Overscan,OSCAN_TEXT
		dc.l	SA_Pens,newLook
		dc.l	SA_SysFont,1	;WB screen font
		dc.l	SA_DisplayID,0
		dc.l	TAG_DONE,0

newLook		dc.w	-1

PALENTRIES	=	8
DefaultPalette	dc.w	PALENTRIES,0
		dc.l	$AAAAAAAA,$AAAAAAAA,$AAAAAAAA,$00000000,$00000000,$00000000
		dc.l	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$66666666,$88888888,$BBBBBBBB
		dc.l	$EEEEEEEE,$44444444,$44444444,$55555555,$DDDDDDDD,$55555555
		dc.l	$00000000,$44444444,$DDDDDDDD,$EEEEEEEE,$99999999,$00000000
		dc.l	0

MagicPalette	dc.w	PALENTRIES,0
		dc.l	$95959595,$95959595,$95959595,$00000000,$00000000,$00000000
		dc.l	$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$3B3B3B3B,$67676767,$A2A2A2A2
		dc.l	$7B7B7B7B,$7B7B7B7B,$7B7B7B7B,$AFAFAFAF,$AFAFAFAF,$AFAFAFAF
		dc.l	$AAAAAAAA,$90909090,$7C7C7C7C,$FFFFFFFF,$A9A9A9A9,$97979797
		dc.l	0

MyWinTitle	dc.b	'MineSweeper '
		dc.b	V,E,R,S,I
		dc.b	0
MyScrTitle
MyWinScrTitle	dc.b	'MineSweeper '
		dc.b	V,E,R,S,I,'          PEGAS Software (May-1997)'
		dc.b	0
	;just version information
		dc.b	0,'$VER: MineSweeper '
		dc.b	V,E,R,S,I
		dc.b	' (21.5.97)',0

	;*****Menu structures*************************

		cnop	0,4
NewMenuTags	dc.l	GTMN_FullMenu,TRUE
		dc.l	TAG_DONE,0

LayoutTags	dc.l	GTMN_NewLookMenus,TRUE
		dc.l	TAG_DONE,0

MyMenu		dc.b	NM_TITLE,0	;They must be in this order...
		dc.w	0,0	;MENUENABLED
		dc.l	0,0,MGame,0
		;**
		dc.b	NM_ITEM,0
		dc.w	$f800,STDFLAGS
		dc.l	csStrt,0,MStart,mh_Start

		dc.b	NM_ITEM,0
		dc.w	$f800!1<<MIS,STDFLAGS
		dc.l	csPaus,0,MPause,mh_Pause

		dc.b	NM_ITEM,0
		dc.w	$f800!2<<MIS,STDFLAGS
		dc.l	csAbou,0,MAbout,mh_About

		dc.b	NM_ITEM,0
		dc.w	$f800!3<<MIS,0
		dc.l	0,0,NM_BARLABEL,0

		dc.b	NM_ITEM,0
		dc.w	$f800!4<<MIS,STDFLAGS
		dc.l	csIcon,0,MIcon,mh_Iconify

		dc.b	NM_ITEM,0
		dc.w	$f800!5<<MIS,STDFLAGS
		dc.l	csQuit,0,MQuit,mh_Quit
	;***************************
		dc.b	NM_TITLE,0
		dc.w	0,0	;MENUENABLED
		dc.l	0,0,MScores,0

		dc.b	NM_ITEM,0
		dc.w	$f801,STDFLAGS
		dc.l	csHisc,0,MHiScores,mh_HiScores

		dc.b	NM_ITEM,0
		dc.w	$f801!1<<MIS,STDFLAGS
		dc.l	0,0,MClearHi,0

			dc.b	NM_SUB,0
			dc.w	$0001!(1<<MIS),STDFLAGS
			dc.l	0,0,MClrCustom,mh_ClearCustom

			dc.b	NM_SUB,0
			dc.w	$0001!(1<<MIS)!(1<<SIS),STDFLAGS
			dc.l	0,0,MClrAll,mh_ClearAll

		dc.b	NM_ITEM,0
		dc.w	$f801!2<<MIS,STDFLAGS
		dc.l	0,0,MJoin,mh_JoinScores

		dc.b	NM_ITEM,0
		dc.w	$f801!3<<MIS,STDFLAGS
		dc.l	csSaHi,0,MSave,mh_SaveScores
	;***************************
		dc.b	NM_TITLE,0
		dc.w	0,0	;MENUENABLED
		dc.l	0,0,MLevel,0

LevelItems	dc.b	NM_ITEM,0
		dc.w	$f802,MCHECK
		dc.l	csLev1,$fffe,MEasy,mh_Level

		dc.b	NM_ITEM,0
		dc.w	$f802!1<<MIS,MCHECK
		dc.l	csLev2,$fffd,MMedium,mh_Level

		dc.b	NM_ITEM,0
		dc.w	$f802!2<<MIS,MCHECK
		dc.l	csLev3,$fffb,MHard,mh_Level

		dc.b	NM_ITEM,0
		dc.w	$f802!3<<MIS,MCHECK
		dc.l	csLev4,$fff7,MProfi,mh_Level

		dc.b	NM_ITEM,0
		dc.w	$f802!4<<MIS,MCHECK
		dc.l	csLev5,$ffef,MCustom,mh_Level
	;***************************
		dc.b	NM_TITLE,0
		dc.w	0,0	;MENUENABLED
		dc.l	0,0,MSettings,0
		;**

		dc.b	NM_ITEM,0
		dc.w	$f803,STDFLAGS
		dc.l	csPref,0,MPrefs,mh_AdjustPrefs

		dc.b	NM_ITEM,0
		dc.w	$f803!1<<MIS,STDFLAGS
		dc.l	0,0,MSavePrefs,mh_SavePrefs

		dc.b	NM_END,0
		dc.l	0,0,0,0,0

MMI_NUMOF	=	25	;don't forget!! (include NM_END)

csStrt		dc.b	'S'
csAbou		dc.b	'?'
csHisc		dc.b	'H'
csSaHi		dc.b	'W'
csLev1		dc.b	'1'
csLev2		dc.b	'2'
csLev3		dc.b	'3'
csLev4		dc.b	'4'
csLev5		dc.b	'5'
csIcon		dc.b	'I'
csQuit		dc.b	'Q'
csPref		dc.b	'A'
csPaus		dc.b	'P'

MGame		dc.b	'GAME',0
MStart		dc.b	'Start',0
MPause		dc.b	'Pause',0
MAbout		dc.b	'About',0
MIcon		dc.b	'Iconify   ',0
MQuit		dc.b	'QUIT',0

MScores		dc.b	'Hi-Scores',0
MHiScores	dc.b	'Show',0
MClearHi	dc.b	'Clear    ',0
MClrCustom	dc.b	 'Custom',0
MClrAll		dc.b	 'All',0
MJoin		dc.b	'Join',0
MSave		dc.b	'Save',0

MLevel		dc.b	'Level',0

MEasy		dc.b	'Easy',0
MMedium		dc.b	'Medium',0
MHard		dc.b	'Hard',0
MProfi		dc.b	'Profi',0
MCustom		dc.b	'Custom',0

MSettings	dc.b	'Settings',0
MPrefs		dc.b	'Adjust',0
MSavePrefs	dc.b	'Save',0

;**inform. requests
nointui_Text	dc.b	'"intuition.library" V39 required!',0
nointui_Button	dc.b	'I see.',0
nodos_Text	dc.b	'"dos.library" V36 required!',0
nodos_Button	dc.b	'I see.',0
nogfx_Text	dc.b	'"graphics.library" V39 required!',0
nogfx_Button	dc.b	'I see.',0
nogad_Text	dc.b	'"gadtools.library" V36 required!',0
nogad_Button	dc.b	'I see.',0
noutility_Text	dc.b	'"utility.library V36 required!',0
noutility_Button dc.b	'I see.',0

noreq_Text	dc.b	'"reqtools.library" V38 required!',10,0 ;for PrintText
notclosed_Text	dc.b	'ERROR: Couldn',39,'t close output file.',0

nomenu_Text	dc.b	'Couldn',39,'t allocate menu structures.',0
nomenu_Button	dc.b	'Continue',0
NoScr_Text	dc.b	'Failed to open required screen.',0
NoScr_Button	dc.b	'Continue',0
nowin_Text	dc.b	'Failed to open required window.',0
nowin_Button	dc.b	'Continue',0
nofont_Text	dc.b	'Failed to open required font.',10
		dc.b	'Default font is used.',0
nofont_Button	dc.b	'I see.',0
noprefs_Text	dc.b	'There',39,'s no memory for Preference structure.',0
noprefs_Button	dc.b	'Exit',0
changed_Text	dc.b	'Hey! Somebody has changed the window!!',10
		dc.b	'( Sorry, not me!! )',0
changed_Button	dc.b	'Well...',0
nomygfx_Text	dc.b	'No chip memory for gfx.',0
nomygfx_Button	dc.b	'Well...',0
nopf_Text	dc.b	'Fatal lack of memory.',0
nopf_Button	dc.b	'Exit MineSweeper',0
pfbig_Text	dc.b	'Sorry, but the required playfield is too big.',10
		dc.b	'I can handle only 65535 buttons.',10
		dc.b	'( That',39,'s e.G. 85 x 771 or 255 x 257 :)',10,10
		dc.b	'Sorry, but this is a fatal error :( ',0
pfbig_Button	dc.b	'Exit MineSweeper',0
toobig_Text	dc.b	'The playfield size is too big for your screen.',0
toobig_Button	dc.b	'I see..',0
oldproc_Text	dc.b	'Sorry, but I prefer a 68020+',0
oldproc_Button	dc.b	'O.K. I',39,'ll upgrade.',0
oldks_Text	dc.b	'System 3.0+ (V39+) required.',0
oldks_Button	dc.b	'No money.',0
notimd_Text	dc.b	'Sorry. Couldn',39,'t open "timer.device"',0
notimd_Button	dc.b	'Abort',0
unexp_Text	dc.b	'Couldn',39,'t open required window',10
		dc.b	'(perhaps low memory or something..)',0
unexp_Button	dc.b	'O.K.',0
nopubport_Text	dc.b	'Couldn',39,'t open message port.',0
nopubport_Button dc.b	'Leave',0
noidcmp_Text	dc.b	'Couldn',39,'t open IDCMP communication port.',0
noidcmp_Button	dc.b	'Exit',0
toolong_Text	dc.b	'(TIME OUT!)',10
		dc.b	'SORRY! UNFORTUNALLY, I WAS NOT INFORMED ABOUT YOUR IQ.',10
		dc.b	'BUT DO NOT PANIC. JUST MOVE THE POINTER TO THE BUTTON BELOW',10
		dc.b	'THIS TEXT AND PRESS LEFT BUTTON OF THE THING, YOU ARE MOVING WITH.',10
		dc.b	'THEN TRY TO FIND THE "CLOSE GADGET".',10
		dc.b	'IT IS IN THE UPPER-LEFT CORNER OF THE RECTANGLE,',10
		dc.b	'WHICH CONTAINS THOSE MANY SQUARES AND THE SUN. GOOD LUCK!',10
		dc.b	'(hope you got it..! :-)',0
toolong_Button	dc.b	'HERE!  PRESS HERE!!',0
toomuch_Text	dc.b	'There are too many mines on custom level.',10
		dc.b	'It must be max. Width*Height-1',0
toomuch_Button	dc.b	'O.K. Let',39,'s correct it.',0
toosmall_Text	dc.b	'The window would be too small for this button-sizes',10
		dc.b	'and the specified PF width.',0
toosmall_Button	dc.b	'OK Let',39,'s correct it',0
surec_Text	dc.b	'Are you sure to clear custom hi-scores?',0
surec_Button	dc.b	'Yes|No',0
surea_Text	dc.b	'Are you sure to clear all hi-scores?',0
surea_Button	dc.b	'Yes|No',0

xmas_Text	dc.b	'  --- PEGAS SOFTWARE WISH YOU MERRY CHRISTMAS ---',10,10
		dc.b	'These are personal wishes from Andry :',10
		dc.b	'Lack of depression, lot of love, many presents',10
		dc.b	'and a wonderful Christmas-tree.',10
		dc.b	'----------------------------------------------------',10,10
		dc.b	'Well, did you pay for this game?',10
		dc.b	'Not yet? ... oh , you are going to!',10
		dc.b	'Then it',39,'s all right.',0

xmas_Button	dc.b	'Enjoy MineSweeper',0

about_Text	dc.b	10,'MineSweeper '
		dc.b	V,E,R,S,I
		dc.b	10,'-----------------',10
		dc.b	'PEGAS Software  (Mai-1997)',10,10
		dc.b	'  Code: Andry  e-mail: xbednar@fi.muni.cz',10
		dc.b	'                  tel: +420-641-68284',10,10
		dc.b	'  Gfx : Troda  e-mail: kozubv@vtx.cz',10
		dc.b	'                  tel: +420-641-204595',10,10,10
		dc.b	'     Language: 100%% assembler',10
		dc.b	'Compiled with: PhxAss v4.35(alpha)  (freeware!!!)',10
		dc.b	'               by Frank Wille.  (Danke sehr :)',10,10
		dc.b	'This program is freeware, but a little support',10
		dc.b	'would be nice :)  ...refer to documentation.',10
		dc.b	0
about_Button	dc.b	'Enjoy!',0

HiScoresButton	dc.b	'Hmmm...',0
HiScoresButtonSave dc.b	'Save|Don',39,'t save',0

HsFileName	dc.b	'Mines.hiscores',0
		cnop	0,4

AboutTags
HiScoresTags	dc.l	RT_Window,0
		dc.l	RT_TextAttr,MyTextAttr
		dc.l	TAG_DONE,0
IReqTags	dc.l	RTEZ_Flags,EZREQF_CENTERTEXT
		dc.l	RT_Window,0
		dc.l	TAG_DONE,0
JoinGetTags	dc.l	RT_Window,0
		dc.l	RTFI_Flags,FREQF_MULTISELECT!FREQF_PATGAD
		dc.l	RTFI_OkText,join_Text
		dc.l	TAG_DONE,0
GSReqTags	dc.l	RT_Window,0
		dc.l	RTGS_Flags,GSREQF_CENTERTEXT
		dc.l	RTGS_TextFmt,hsgs_text
		dc.l	TAG_DONE,0

hsgs_text	dc.b	'You have reached the high score.',10
		dc.b	'Please enter your name.',0
		cnop	0,4
;**For bevel boxes
VisualInfo	dc.l	0
dbb_TagList1	dc.l	GT_VisualInfo,0		;normal button
		dc.l	GTBB_FrameType,BBFT_BUTTON
		dc.l	TAG_DONE,0
dbb_TagList2	dc.l	GT_VisualInfo,0		;recessed button
		dc.l	GTBB_FrameType,BBFT_BUTTON
		dc.l	GTBB_Recessed,TRUE
		dc.l	TAG_DONE,0

MyTextAttr	dcb.b	ta_SIZEOF,0

		cnop	0,4
pnrt_Text	dc.l	0	;ptr to the final text

pnrt_Button	dc.b	'I',39,'ll have a look',0
		cnop	0,4

PrefItems
		dc.l	PNameCustom,Pref_CustomScreen,sp_CustomScreen
		dc.l	PNamePub,Pref_PubScreen,sp_PubScreen

		dc.l	PNameLevel,Pref_Level,sp_Level
		dc.l	PNameCusWid,Pref_CusWid,sp_CusWid
		dc.l	PNameCusHei,Pref_CusHei,sp_CusHei
		dc.l	PNameCusBom,Pref_CusBom,sp_CusBom

		dc.l	PNameWBLike,Pref_WBLike,sp_WBLike
		dc.l	PNameNotCenter,Pref_NotCenter,sp_NotCenter
		dc.l	PNameNotActivate,Pref_NotActiv,sp_NotActiv
		dc.l	PNameNoQuestion,Pref_NoQuest,sp_NoQuest
		dc.l	PNameDeadQ,Pref_DeadQ,sp_DeadQ
		dc.l	PNameCountD,Pref_CountD,sp_CountD
		dc.l	PNameNoRMouse,Pref_NoRMouse,sp_NoRMouse
		dc.l	PNameWarn,Pref_Warn,sp_Warn
		dc.l	PNameScale,Pref_Scale,sp_Scale

		dc.l	PNamePalette,Pref_Palette,sp_Palette
		dc.l	PNameGfx,Pref_GfxType,sp_GfxType
		dc.l	PNameIconify,Pref_Iconify,sp_Iconify
		dc.l	PNameModeID,Pref_ModeID,sp_ModeID
		dc.l	PNameSizeX,Pref_SizeX,sp_SizeX
		dc.l	PNameSizeY,Pref_SizeY,sp_SizeY
		dc.l	PNameWinX,Pref_WinX,sp_WinX
		dc.l	PNameWinY,Pref_WinY,sp_WinY
		dc.l	PNameZoomX,Pref_ZoomX,sp_ZoomX
		dc.l	PNameZoomY,Pref_ZoomY,sp_ZoomY

		dc.l	PNameFont,Pref_Font,sp_Font
		dc.l	PNameFontSize,Pref_FontSize,sp_FontSize
		dc.l	0,0,0		;end

PNamePub	dc.b	'PUBSCREEN',0
PNameCustom	dc.b	'CUSTOMSCREEN',0
PNameModeID	dc.b	'ModeID',0
PNameSizeX	dc.b	'Scr_Width',0
PNameSizeY	dc.b	'Scr_Height',0

PNameNotCenter	dc.b	'DONOTCENTER',0
PNameNotActivate dc.b	'DONOTACTIVATE',0
PNameWinX	dc.b	'Window_Left',0
PNameWinY	dc.b	'Window_Top',0
PNameZoomX	dc.b	'Paused_Left',0
PNameZoomY	dc.b	'Paused_Top',0

PNameLevel	dc.b	'Level',0
PNameCusWid	dc.b	'CUSTOM_WIDTH',0
PNameCusHei	dc.b	'CUSTOM_HEIGHT',0
PNameCusBom	dc.b	'CUSTOM_MINES',0

PNameFont	dc.b	'Font',0
PNameFontSize	dc.b	'FontSize',0
PNamePalette	dc.b	'PALETTE',0
PNameGfx	dc.b	'GFXTYPE',0

PNameNoQuestion	dc.b	'NOQMARK',0
PNameDeadQ	dc.b	'QUESTION_DEAD',0
PNameCountD	dc.b	'COUNTDOWN',0
PNameNoRMouse	dc.b	'NORMOUSEGAME',0
PNameWBLike	dc.b	'WBLIKE',0
PNameWarn	dc.b	'DONOTWARN',0
PNameIconify	dc.b	'ICONIFY',0
PNameScale	dc.b	'SCALEGFX',0
TOOLTYPEITEMS	=	27

;***Structure Default playfield sizes
		even
DefPFSizes	dc.l	0,0	;no data
		dc.w	EASYWIDTH
		dc.w	EASYHEIGHT
		dc.w	EASYBOMBS,0	;zero just for allign (8)
		dc.w	MEDIUMWIDTH
		dc.w	MEDIUMHEIGHT
		dc.w	MEDIUMBOMBS,0
		dc.w	HARDWIDTH
		dc.w	HARDHEIGHT
		dc.w	HARDBOMBS,0
		dc.w	PROFIWIDTH
		dc.w	PROFIHEIGHT
		dc.w	PROFIBOMBS,0
cpf_Width	= 0
cpf_Height	= 2
cpf_Bombs	= 4
CusPFSizes	dc.w	MEDIUMWIDTH	;for custom
		dc.w	MEDIUMHEIGHT
		dc.w	MEDIUMBOMBS,0

;***Join Hi-Scores data
join_Text	dc.b	'Join',0
JoinFilename	dcb.b	108,0
JoinGetTitle	dc.b	'Select Hi-Score files',0
		cnop	0,4
JoinOldDir	dc.l	0
JoinDirLock	dc.l	0
JoinPrefsBuf	dc.l	0
JoinRequester	dc.l	0
JoinFileList	dc.l	0

		SECTION	BssVars,BSS
		cnop	0,4
Semaphore	ds.l	1	;must not be cleared!

BssStart
IntuiBase	ds.l	1
_GfxBase	ds.l	1
DosBase		ds.l	1
_ReqToolsBase	ds.l	1
GadtoolsBase	ds.l	1
UtilityBase	ds.l	1

MyScreen	ds.l	1	;pointer to the screen used (Workbench or custom)
MyWindow	ds.l	1
OldIDCMP	ds.l	1	;IDCMP flags of my window
WinFont		ds.l	1	;screen rastport font

MyFontName	ds.b	30
		cnop	0,4
SysTime		ds.l	2
OldSysTime	ds.l	2
MyTime		ds.l	2
Ctime		ds.l	2	;current time
EndTime		ds.l	2
TimDevBase	ds.l	1
StartTime	ds.w	2

MenuStruct	ds.l	1

TimPort		ds.l	1
TimIoReq	ds.l	1
RndSeed		ds.l	1
Storage		ds.l	2	;just 8 free bytes
OldDirectory	ds.l	1
ProgDir		ds.l	1
SeedFillStack	ds.l	1	;adr
SeedFillSP	ds.l	1	;ptr at end
MyPrefs		ds.l	1	;ptr to MyPrefs structure
MyDrawInfo	ds.l	1
MGGfx		ds.l	1	;ptr to an array of bitmap pointers
PFAdr		ds.l	1	;ptr to play field
PFSize		ds.w	1	;size of play field in bytes
WinCount	ds.w	1	;howmany buttons to press before you win
MaxRandRange	ds.w	1
LastXmas	ds.w	1

MinRowBut	ds.w	1	;minimum of buttons per row (pf width)
MyBarHeight	ds.w	1	;size of main bar (note MYBARWIDTH is a constant)
winBarH		ds.w	1	;height of the window bar
WinWidth	ds.w	1	;MyWindow size
WinHeight	ds.w	1
ZoomWidth	ds.w	1
ZoomHeight	ds.w	1
WinX		ds.w	1	;MyWindow position
WinY		ds.w	1
MinX		ds.w	1	;upper left corner of the inner area
MinY		ds.w	1
MinPFX		ds.w	1	;start of the playfield gfx
MinPFY		ds.w	1
PFXPix		ds.w	1	;playfield size in pixels
PFYPix		ds.w	1
InnWidth	ds.w	1	;size of the inner area
InnHeight	ds.w	1
PFWidth		ds.w	1	;Play Field Size (buttons per x/y)
PFHeight	ds.w	1
PFBombs		ds.w	1
ButtWidth	ds.w	1	;button size
ButtHeight	ds.w	1
TimeX		ds.w	1	;position of Time and BCount displays
TimeY		ds.w	1
BCountX		ds.w	1
BCountY		ds.w	1
BCount		ds.w	1
CenterPointX	ds.w	1
CenterPointY	ds.w	1
LastX		ds.w	1
LastY		ds.w	1

ScreenPalette	ds.l	PALENTRIES*3+2

gtl_IText	ds.b	it_SIZEOF

;***Some flags------------------
Play		ds.b	1	;if set: timer, rmbtrap, ...
Win		ds.b	1	;if won then 1
Ready		ds.b	1	;if ready to play
HandleNext	ds.b	1	;handle next selected menu?
IDidTheChange	ds.b	1	;Who changed the window size?
Disable		ds.b	1	;if set, disables drawing to screen and playing.
				;You can use menu (to change window size)
DisplayTooBig	ds.b	1	;inform user, that he cannot play (disabled)
Sign		ds.b	1	;sign flag for number converting
TimerGo		ds.b	1	;timer stopped/running
FirstTime	ds.b	1
ValidHSText	ds.b	1
CPointSet	ds.b	1
TestXmas	ds.b	1
Pause		ds.b	1	;game paused?
SunPressedOnce	ds.b	1
FromIconify	ds.b	1
PausedLevel	ds.b	1
;------------------------------
LastLevel	ds.b	1
		cnop	0,4
Allocated	ds.l	MAXALLOCBLOCKS*2+2
AllocPos	ds.l	1

;**********Load/Save file data
lf_filename	ds.l	1
lf_fhandle	ds.l	1
lf_fileLock	ds.l	1
lf_buffer	ds.l	1
lf_fileLen	ds.l	1
lf_fib		ds.b	$104	;File_Info_Block

CurrDate	ds.b	CD_SIZE
GTNewMenu	ds.b	MMI_NUMOF*gnm_SIZEOF	;buffer for NewMenu structures
IntuiMessBuf	ds.b	im_SIZEOF
NameBuffer	ds.b	NAMELEN
HiScoresText	ds.b	HS_TEXTMEM
PROGNAMELEN = 32
ProgramName	ds.b	PROGNAMELEN
WinPortSigBit	ds.b	1
PubPortSigBit	ds.b	1
		cnop	0,4
SignalBits	ds.l	1
bitScaleArgs	ds.w	bsa_SIZEOF/2

		cnop	0,4
BssSectionAlign	ds.l	1
BssEnd
