COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

	Copyright (c) Geoworks 1994 -- All Rights Reserved

PROJECT:	PC GEOS
MODULE:		
FILE:		cwordVictory.asm

AUTHOR:		Steve Scholl, Sep 26, 1994

ROUTINES:
	Name			Description
	----			-----------

	
REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	Steve	9/26/94		Initial revision


DESCRIPTION:
	
		

	$Id: cwordVictory.asm,v 1.1 97/04/04 15:14:22 newdeal Exp $

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

; State for the random-number generator. This beast comes from the
; BSD random-number generator, which is supposed to be random in all 31
; bits it produces...
;
RAND_DEG	equ	31
RAND_SEP	equ	3
RAND_MULT	equ	1103515245
RAND_ADD	equ	12345

idata	segment


frontPtr	nptr.dword	randTbl[(RAND_SEP+1)*dword]
rearPtr		nptr.dword	randTbl[1*dword]
endPtr		nptr.dword	randTbl[(RAND_DEG+1)*dword]


randTbl		dword	3,	; generator type
			0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 
			0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, 
			0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 
			0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 
			0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, 
			0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 
			0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 
				    0xf5ad9d0e, 0x8999220b, 0x27fb47b9



idata	ends

CwordVictoryCode	segment resource


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		GameSeedRandom
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Seed the random number generator, using 128 bytes of state

CALLED BY:	
PASS:		dx:ax	= initial seed

RETURN:		nothing

DESTROYED:	dx, ax

PSEUDO CODE/STRATEGY:
		state[0] = seed;
		for (i = 1; i < RAND_DEG; i++) {
			state[i] = 1103515245*state[i-1] + 12345;
		}
		frontPtr = &state[RAND_SEP];
		rearPtr = &state[0];
		for (i = 0; i < 10*RAND_DEG; i++) {
			GameRandom();
		}

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	ardeb	4/14/91		Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
GameSeedRandom	proc	far
		uses	si, di, bx, cx, ds
		.enter
		mov	bx, handle dgroup	;Do this so there is no segment
		call	MemDerefDS		; relocs to dgroup (so the
						; dgroup resource is 
						; discardable on XIP platforms)

		mov	di, offset (randTbl[1*dword])
		mov	cx, RAND_DEG-1
seedLoop:
		mov	({dword}ds:[di]).low, ax
		mov	({dword}ds:[di]).high, dx
		add	di, size dword

	;
	; Perform a 32-bit unsigned multiply by RAND_MULT, leaving the result
	; in si:bx:
	;
	; 			h	mh	ml	l
	;ax*low(RAND_MULT)			x	x
	;dx*low(RAND_MULT)		x	x
	;ax*high(RAND_MULT)		x	x
	;dx*high(RAND_MULT)	x	x
	;
	; The highest two words are discarded, which means we don't even have
	; to multiply dx by high(RAND_MULT).
	; 
		push	ax
		push	dx
		mov	dx, RAND_MULT AND 0xffff
		mul	dx
		xchg	bx, ax		; bx <- low(result)
		mov	si, dx		; si <- partial high(result)

		pop	ax		; ax <- original dx
		mov	dx, RAND_MULT AND 0xffff
		mul	dx
		add	si, ax		; high(result) += low(dx*low(RAND_MULT))

		pop	ax		; ax <- original ax
		mov	dx, RAND_MULT / 65536
		mul	dx
		add	si, ax		; high(result)+=low(high(RAND_MULT)*ax)
	;
	; Place result in the proper registers and add in the additive factor.
	; 
		mov	dx, si
		mov	ax, bx
		add	ax, RAND_ADD
		adc	dx, 0
		loop	seedLoop
	;
	; Store the final result.
	; 
		mov	({dword}ds:[di]).low, ax
		mov	({dword}ds:[di]).high, dx

	;
	; Initialize the pointers.
	; 
		mov	ds:[frontPtr], offset (randTbl[(RAND_SEP+1)*dword])
		mov	ds:[rearPtr], offset (randTbl[1*dword])
		
	;
	; Now randomize the state according to the degree of the
	; polynomial we're using.
	; 
		mov	cx, 10*RAND_DEG
initLoop:
		mov	dx, 0xffff
		call	GameRandom
		loop	initLoop
		.leave
		ret
GameSeedRandom	endp






COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		GameRandom
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Return a random number

CALLED BY:	GLOBAL

PASS:		dx	= max for returned value

RETURN:		dx	= number between 0 and max-1

DESTROYED:	nothing 

PSEUDO CODE/STRATEGY:
		We assume we're using a type 3 random number generator here,
		so the code looks like this:
			*frontPtr += *rearPtr;
			i = (*frontPtr >> 1)&0x7fffffff;
			if (++frontPtr >= endPtr) {
				frontPtr = state;
				rearPtr += 1;
			} else if (++rearPtr >= endPtr) {
				rearPtr = state;
			}
			
			return(i % DL);

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	ardeb	3/25/91		Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
GameRandom	proc	far
		uses	ds, cx, si, di, ax, bx
		.enter
		mov	bx, handle dgroup	;Do this so there is no segment
		call	MemDerefDS		; relocs to dgroup (so the
						; dgroup resource is 
						; discardable on XIP platforms)
		mov	si, ds:[frontPtr]
		mov	di, ds:[rearPtr]
		mov	ax, ({dword}ds:[di]).low
		mov	cx, ({dword}ds:[di]).high
		add	ax, ({dword}ds:[si]).low
		adc	cx, ({dword}ds:[si]).high
		mov	({dword}ds:[si]).low, ax
		mov	({dword}ds:[si]).high, cx
		
		shr	cx
		rcr	ax
		
		add	si, size dword
		add	di, size dword
		cmp	si, ds:[endPtr]
		jb	adjustRear
		mov	si, offset (randTbl[1*dword])
		jmp	storePtrs
adjustRear:
		cmp	di, ds:[endPtr]
		jb	storePtrs
		mov	di, offset (randTbl[1*dword])
storePtrs:
		mov	ds:[frontPtr], si
		mov	ds:[rearPtr], di

		mov	cx, dx		; ignore high word, to avoid painful
					;  divide. Since all the bits are
					;  random, we just make do with the
					;  low sixteen, thereby avoiding
					;  quotient-too-large faults
		clr	dx
		div	cx
		.leave
		ret
GameRandom	endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardPlaySound
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Play a sound.

CALLED BY:	BoardVerify, BoardVerifyWord
PASS:		nothing
RETURN:		nothing
DESTROYED:	nothing
SIDE EFFECTS:	
PSEUDO CODE/STRATEGY:
		Call WavPlayInitSound for the sound

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	DH	3/15/2000   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
; These constants match those used in the [sound] section.
SOUND_CWORD_CHECK_OK	equ	0

BoardPlaySound	proc near
        uses   ax, bx, cx, dx, di, es

soundToken	local	GeodeToken
	.enter

	; Retrieve our GeodeToken.
	segmov	es, ss, ax
	lea	di, soundToken
	mov	bx, handle 0		; bx <- app geode token
	mov	ax, GGIT_TOKEN_ID
	call	GeodeGetInfo

	; Play the sound.
	mov	bx, SOUND_CWORD_CHECK_OK
	mov	cx, es
	mov	dx, di
	call	WavPlayInitSound

	.leave
	ret
BoardPlaySound	endp


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardVerify
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Verify all the user letters in non-empty cells and
		give feedback of the results to the user.

		Also reset HWR macro if in PEN mode.
		
CALLED BY:	MSG_CWORD_BOARD_VERIFY
PASS:		*ds:si	= CwordBoardClass object
		ds:di	= CwordBoardClass instance data
		ds:bx	= CwordBoardClass object (same as *ds:si)
		es 	= segment of CwordBoardClass
		ax	= message #
RETURN:		nothing
DESTROYED:	nothing
SIDE EFFECTS:	
PSEUDO CODE/STRATEGY:
REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	JL	7/25/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardVerify	method dynamic CwordBoardClass, 
					MSG_CWORD_BOARD_VERIFY
	uses	ax, cx, dx, bp
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	cmp	ds:[di].CBI_system, ST_PEN
	jne	dontReset
	call	BoardGestureResetMacroProcFar
dontReset:

	call	BoardPlaySound

	mov	dx,ds:[di].CBI_engine
	tst	dx
	jz	done
	call	EngineCheckForAllCellsCorrect
	jnc	success

	call	EngineVerifyAllCells
	call	BoardAnimateVerify

	call	EngineCheckForAllCellsFilled
	jnc	allFilled

enableDisable:
	call	CwordEnableDisableClearXSquares

done:
	.leave
	ret


allFilled:
	;    If no wrong cells on screen, then do something about it
	;

	call	BoardDetermineIfWrongCellOnScreen
	jc	enableDisable
	call	BoardGetWrongCellOnScreen	
	jmp	enableDisable

success:
	call	BoardFoolinAround

	mov	bx,handle CompletedInteraction
	mov	si,offset CompletedInteraction
	mov	ax,MSG_GEN_INTERACTION_INITIATE
	mov	di,mask MF_FIXUP_DS
	call	ObjMessage

	jmp	done

BoardVerify	endm




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardFoolinAround
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Do cool stuff to celebrate the completion of the puzzle

CALLED BY:	BoardVerify

PASS:		*ds:si - Board

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/22/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardFoolinAround		proc	near
	uses	ax,cx,dx,bp,es,bx
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	call	TimerGetCount
	call	GameSeedRandom

	mov	bx,handle CwordStrings
	call	MemLock
	mov	es,ax

	mov	dx,length coolTextOffsets
	call	GameRandom
	shl	dx				;word size table
	add	dx,offset coolTextOffsets
	mov	bx,dx				;offset into table
	mov	bx,cs:[bx]			;chunk of text from table
	mov	bx,es:[bx]			;offset of text from chunk

	call	BoardFadeInCoolString

	mov	bx,handle CwordStrings
	call	MemUnlock

	call	BoardDoShootingStars

	call	BoardFadeOutScreen

	mov	ax,MSG_VIS_INVALIDATE
	call	ObjCallInstanceNoLock

	.leave
	ret

coolTextOffsets	word \
	offset	CoolText,
	offset	FinisText,
	offset	RadText,
	offset	DoneText,
	offset	YesText

BoardFoolinAround		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardEnumerateCells
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Call call back routine for each cell. Process left to right
		on first row then right to left and so on.

CALLED BY:	UTILITY

PASS:		*ds:si - Board
		di - offset to near routine in segment cs
		cx,bp - data to pass to call back

		PASSED to call back
			*ds:si - Board
			dx - engine token
			bx - cell token
			cx,bp - data passed to BoardEnumerateCells

RETURN:		
		carry clear - enumerated all cells
			ax - destroyed
		carry set - enumeration stopped
			ax - cell number that stopped

DESTROYED:	
		see RETURN

PSEUDO CODE/STRATEGY:
		call back routine returning carry stops enumeration

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/20/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardEnumerateCells		proc	near
	class	CwordBoardClass
	uses	dx,bx
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	GetInstanceDataPtrDSBX	CwordBoard_offset
	mov	dx,ds:[bx].CBI_engine

	clr	bx					;initial
makeCall:
	call	di
	mov	ax,bx					;cell token
	jc	done

leftToRight:
	call	EngineGetNextCellTokenInRowFar
	cmp	bx,ENGINE_GRID_EDGE
	je	rightToLeftStart
	call	di
	mov	ax,bx					;cell token
	jc	done
	jmp	leftToRight

rightToLeftStart:
	call	EngineGetNextCellTokenInColumnFar
	cmp	bx,ENGINE_GRID_EDGE
	je	doneNoTermination
	call	di
	mov	ax,bx					;cell token
	jc	done

rightToLeft:
	call	EngineGetPrevCellTokenInRowFar
	cmp	bx,ENGINE_GRID_EDGE
	je	leftToRightStart
	call	di
	mov	ax,bx					;cell token
	jc	done
	jmp	rightToLeft

done:
	.leave
	ret

doneNoTermination:
	clc
	jmp	done

leftToRightStart:
	call	EngineGetNextCellTokenInColumnFar
	cmp	bx,ENGINE_GRID_EDGE
	je	doneNoTermination
	jmp	makeCall	

BoardEnumerateCells		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardEnumerateCellsInWord
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Call call back routine for each cell in the word

CALLED BY:	UTILITY

PASS:		*ds:si - Board
		bx - Direction
		ax - CellToken
		di - offset to near routine in segment cs
		cx,bp - data to pass to call back

		PASSED to call back
			*ds:si - Board
			dx - engine token
			bx - cell token
			cx,bp - data passed to BoardEnumerateCellsInWord

RETURN:		
		carry clear - enumerated all cells
			ax - destroyed
		carry set - enumeration stopped
			ax - cell number that stopped

DESTROYED:	
		see RETURN

PSEUDO CODE/STRATEGY:
		call back routine returning carry stops enumeration

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/20/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardEnumerateCellsInWord		proc	near
	class	CwordBoardClass
	uses	cx,dx,bx

passedBP	local	word	push bp
passedCX	local	word	push cx
lastToken	local	word	

	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	mov	cx,bx					;direction
	GetInstanceDataPtrDSBX	CwordBoard_offset
	mov	dx,ds:[bx].CBI_engine
	call	BoardMapWordToFirstNLastCellsFar
	mov	lastToken,bx
	mov	bx,ax					;first cell

makeCall:
	push	bp,cx					;locals, direction
	mov	cx,passedCX
	mov	bp,passedBP
	call	di
	mov	ax,bx					;current cell
	pop	bp,cx					;locals, direction
	jc	doneWithTermination
	cmp	ax,lastToken
	je	doneNoTermination

	cmp	cx, ACROSS
	je	nextRow
	call	EngineGetNextCellTokenInColumnFar
	jmp	makeCall

doneNoTermination:
	clc
done:
	.leave
	ret

doneWithTermination:
	stc
	jmp	done

nextRow:
	call	EngineGetNextCellTokenInRowFar
	mov	ax,bx					;next cell
	jmp	makeCall

BoardEnumerateCellsInWord		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardGetWrongCellOnScreen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Find a wrong cell and make sure it is visible and select it.

CALLED BY:	BoardVerify

PASS:		
		*ds:si - Board

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/20/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardGetWrongCellOnScreen		proc	near
	class	CwordBoardClass
	uses	di,dx
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	GetInstanceDataPtrDSDI	CwordBoard_offset
	mov	dx,ds:[di].CBI_engine
	call	EngineFindFirstWrongCell
	jnc	done
	call	BoardMoveSelectedSquare
done:
	.leave
	ret
BoardGetWrongCellOnScreen		endp





COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardGetEmptyCellOnScreen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	See message defintion

PASS:		
		*(ds:si) - instance data of object
		ds:[bx] - instance data of object
		ds:[di] - master part of object
		es - segment of CwordBoardClass

RETURN:		
		nothing
	
DESTROYED:	
		ax

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	10/ 5/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardGetEmptyCellOnScreen	method dynamic CwordBoardClass, 
						MSG_CWORD_BOARD_FIND_EMPTY_CELL
	uses	ax,dx
	.enter

	mov	dx,ds:[di].CBI_engine
	tst	dx
	jz	done
	call	EngineFindFirstEmptyCell
	jnc	done
	call	BoardMoveSelectedSquare
done:
	.leave
	ret

BoardGetEmptyCellOnScreen		endm






COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardClearPuzzle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	See message defintion

PASS:		
		*(ds:si) - instance data of object
		ds:[bx] - instance data of object
		ds:[di] - master part of object
		es - segment of CwordBoardClass

RETURN:		
		nothing
	
DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	10/ 5/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardClearPuzzle	method dynamic CwordBoardClass, 
						MSG_CWORD_BOARD_CLEAR_PUZZLE
	uses	ax,dx
	.enter

	cmp	ds:[di].CBI_system, ST_PEN
	jne	dontReset
	call	BoardGestureResetMacroProcFar
dontReset:
	mov	dx,ds:[di].CBI_engine
	tst	dx
	jz	done
	call	EngineClearAllCells
	mov	ax,MSG_VIS_INVALIDATE
	call	ObjCallInstanceNoLock
	call	CwordEnableDisableClearXSquares

done:
	.leave
	ret
BoardClearPuzzle		endm




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardClearXCells
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	See message defintion

PASS:		
		*(ds:si) - instance data of object
		ds:[bx] - instance data of object
		ds:[di] - master part of object
		es - segment of CwordBoardClass

RETURN:		
		nothing
	
DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	10/ 5/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardClearXCells	method dynamic CwordBoardClass, 
					MSG_CWORD_BOARD_CLEAR_X_CELLS
	uses	ax,dx
	.enter

	cmp	ds:[di].CBI_system, ST_PEN
	jne	dontReset
	call	BoardGestureResetMacroProcFar
dontReset:
	mov	dx,ds:[di].CBI_engine
	tst	dx
	jz	done
	call	EngineClearWrongCells
	mov	ax,MSG_VIS_INVALIDATE
	call	ObjCallInstanceNoLock

	call	CwordEnableDisableClearXSquares
done:
	.leave
	ret
BoardClearXCells		endm





COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardDetermineIfWrongCellOnScreen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Enumerate through the cells and determine if any of the
		wrong cells are currently visible.

CALLED BY:	

PASS:		
		*ds:si - Board

RETURN:		
		stc - yes
		clc - no

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/20/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardDetermineIfWrongCellOnScreen		proc	far
	class	CwordBoardClass
	uses	ax,di
visibleRect	local	Rectangle
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	GetInstanceDataPtrDSDI CwordBoard_offset
	mov	ax,ds:[di].CBI_cellWidth
	shr	ax,1

	;    Make sure a reasonable portion of the wrong cell
	;    is visible
	;

	call	BoardGetVisibleRect
	add	visibleRect.R_left,ax
	add	visibleRect.R_top,ax
	sub	visibleRect.R_right,ax
	sub	visibleRect.R_bottom,ax

	mov	di,offset BoardIsWrongCellOnScreenCallback
	call	BoardEnumerateCells

	.leave
	ret
BoardDetermineIfWrongCellOnScreen		endp






COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardIsWrongCellOnScreenCallback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Determine if cell is wrong and on screen

CALLED BY:	BoardEnumerateCells

PASS:		
		*ds:si - Board
		dx - engine token
		bx - cell token
		cx,bp - data passed to BoardEnumerateCells

RETURN:		
		clc - if cell is not wrong or not on screen
		stc - if cell is wrong and on screen

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/20/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardIsWrongCellOnScreenCallback		proc	near
	uses	ax,bx,cx,dx
visibleRect	local	Rectangle
	.enter inherit

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
	Assert	CellTokenType	bx
	Assert	EngineTokenType	dx
;;;;;;;;

	mov	ax,bx				;cell token
	call	EngineGetCellFlagsFar
	test	cl,mask CF_WRONG
	jz	dontStop

	mov	cx,ax				;cell token
	call	BoardGetCellBounds
	cmp	ax,visibleRect.R_right
	jg	dontStop
	cmp	cx,visibleRect.R_left
	jl	dontStop
	cmp	bx,visibleRect.R_bottom
	jg	dontStop
	cmp	dx,visibleRect.R_top
	jge	stopIt

dontStop:
	clc
done:
	.leave
	ret

stopIt:
	stc
	jmp	done

BoardIsWrongCellOnScreenCallback		endp






COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardAnimateVerify
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Highlight each cell and the verify it, drawing
		the slashed if it is wrong.

CALLED BY:	

PASS:		*ds:si - CwordBoardClass object

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	8/25/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardAnimateVerify		proc	far
	class	CwordBoardClass
	uses	ax,cx,bx,dx,di
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;


	call	BoardGetGStateDI
	BoardEraseHiLites

	GetInstanceDataPtrDSBX	CwordBoard_offset
	mov	dx,ds:[bx].CBI_engine
	call	EngineFindFirstWrongCell
	jc	atLeastOneWrongCell

	call	BoardFlashOK

enumerate:
	mov	cx,di				;gstate
	mov	di,offset BoardRedrawWrongCellCallback
	call	BoardEnumerateCells

	mov	di,cx				;gstate
	BoardDrawHiLites
	call	GrDestroyState

	.leave
	ret

atLeastOneWrongCell:
	call	GrGetWinBounds
	call	BoardFlashRect
	jmp	enumerate

BoardAnimateVerify		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardVerifyWord
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	See message defintion

PASS:		
		*(ds:si) - instance data of object
		ds:[bx] - instance data of object
		ds:[di] - master part of object
		es - segment of CwordBoardClass

RETURN:		
		nothing
	
DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	10/ 5/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardVerifyWord	method dynamic CwordBoardClass, 
					MSG_CWORD_BOARD_VERIFY_WORD
	uses	ax,cx,dx,bp
	.enter

	cmp	ds:[di].CBI_system, ST_PEN
	jne	dontReset
	call	BoardGestureResetMacroProcFar
dontReset:

	call	BoardPlaySound

	call	BoardGetGStateDI
	BoardEraseHiLites

	GetInstanceDataPtrDSBX CwordBoard_offset
	mov	ax,ds:[bx].CBI_cell
	mov	cx,ds:[bx].CBI_direction
	push	ax,cx				;cell, direction
	call	BoardMapWordToFirstNLastCellsFar
	call	BoardGetBoundsForFirstNLastCellsFar
	call	BoardFlashRect

	pop	ax,bx				;cell, direction
	mov	cx,di				;gstate
	mov	di,offset BoardRedrawWrongCellCallback
	call	BoardEnumerateCellsInWord

	mov	di,cx				;gstate
	BoardDrawHiLites
	call	GrDestroyState

	call	CwordEnableDisableClearXSquares

	.leave
	ret
BoardVerifyWord		endm



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardFlashRect
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Tempoarily invert a rectangle

CALLED BY:	BoardAnimateVerify
		BoardVerifyWord

PASS:		di - Gstate Handle
		ax,bx,cx,dx - rectangle

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	10/ 5/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardFlashRect		proc	near
	uses	ax
	.enter

	push	ax
	mov	al,MM_INVERT
	call	GrSetMixMode
	pop	ax
	call	GrFillRect	

	push	ax
	mov	ax,15
	call	TimerSleep
	pop	ax

	call	GrFillRect	
	mov	al,MM_COPY
	call	GrSetMixMode

	.leave
	ret
BoardFlashRect		endp





COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardRedrawWrongCellCallback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	If the letter is wrong then draw slashed in it.
	
CALLED BY:	BoardEnumerateCells

PASS:		
		*ds:si - CwordBoardClass object
		dx - engine token
		bx - cell token
		cx - gstate

RETURN:		
		ax - passed cell token

DESTROYED:	
		clc - to keep enumerating

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	8/25/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardRedrawWrongCellCallback		proc	near
	uses	ax,cx,dx,di
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
	Assert	gstate		cx
	Assert	CellTokenType	bx
	Assert	EngineTokenType	dx
;;;;;;;;

	mov	di,cx				;gstate
	mov	ax,bx				;cell token
	call	EngineVerifyCell
	jc	itsWrong

done:
	clc
	.leave
	ret

itsWrong:
	call	BoardRedrawCellFar
	jmp	done

BoardRedrawWrongCellCallback		endp






COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardFadeInCoolString
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Slowly fade out board and fade in the string

CALLED BY:	

PASS:		
		*ds:si - Board
		es:bx - null terminated cool string

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/21/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
CoolStringStruc	struc
	CSS_stringOffset	word
	CSS_textPos		Point
	CSS_textSize		Point			;width, height
	CSS_scaleX		WWFixed
	CSS_scaleY		WWFixed
CoolStringStruc	ends

BoardFadeInCoolString		proc	far
	class	CwordBoardClass
	uses	ax,bx,cx,dx,di,si,bp,ds

coolLocals	local	CoolStringStruc

	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
	Assert  nullTerminatedAscii esbx
;;;;;;;;
	mov	coolLocals.CSS_stringOffset, bx
	
	call	BoardCreateGStateForCoolString
	GetInstanceDataPtrDSBX CwordBoard_offset
	cmp	ds:[bx].CBI_drawOptions, mask DO_COLOR
	jz	10$
	mov	ax, C_BLUE or (CF_INDEX shl 8)
	call	GrSetTextColor
10$:
	call	BoardCalcCoolStringBounds
	call	BoardShiftCoolStringBounds
	call	BoardCalcCoolScaleFactor
	call	BoardTranslateScaleCoolString


	mov	si,offset FadeMask1

again:
	push	si					;fade offset

	mov	al, SDM_CUSTOM or mask SDM_INVERSE
	segmov	ds,cs					;segment of fades
	call	GrSetAreaMask
	call	GrSetTextMask

	;    Fade out board. Making sure that it is slightly larger than
	;    window
	;

	mov	ax,-1
	mov	bx,-1
	mov	cx,coolLocals.CSS_textSize.P_x
	inc	cx
	mov	dx,coolLocals.CSS_textSize.P_y
	inc	dx
	call	GrFillRect

	;    Fade in cool
	;

	clr	ax,bx					;position
	clr	cx					;null termed		
	segmov	ds,es					;string segment
	mov	si,coolLocals.CSS_stringOffset
	call	GrDrawText

	pop	si
	add	si, (FadeMask16-FadeMask15)
	cmp	si, offset FadeMask16
	jbe	again

	call	GrDestroyState

	.leave
	ret


BoardFadeInCoolString		endp


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardFlashOK
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Flash an OK in the puzzle area

CALLED BY:	BoardAnimateVerify

PASS:		
		*ds:si - Board
		di - gstate
RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	10/28/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardFlashOK		proc	near
	uses	ax,bx,cx,di,si,ds,es

coolLocals	local	CoolStringStruc
ForceRef	coolLocals

	.enter

	Assert	ObjectBoard	dssi

	segmov	es,cs
	mov	bx,offset okText
	mov	coolLocals.CSS_stringOffset,bx

	call	BoardCreateGStateForCoolString
	mov	al,MM_INVERT
	call	GrSetMixMode
	call	BoardCalcCoolStringBounds
	call	BoardShiftCoolStringBounds
	call	BoardCalcCoolScaleFactor
	call	BoardTranslateScaleCoolString

	call	GrGetWinBounds
	call	GrFillRect

	clr	ax,bx					;position
	clr	cx					;null termed		
	segmov	ds,cs
	mov	si,offset okText
	call	GrDrawText

	mov	ax,15
	call	TimerSleep

	clr	ax					;x pos
	call	GrDrawText

	call	GrGetWinBounds
	call	GrFillRect

	call	GrDestroyState
	.leave
	ret
BoardFlashOK		endp

okText	char	"OK",0


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardFadeOutScreen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Slowly fade out screen

CALLED BY:	

PASS:		
		*ds:si - Board

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/21/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardFadeOutScreen		proc	far
	uses	ax,bx,cx,dx,di,si,bp,ds

	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;
	
	call	BoardCreateGStateForCoolString

	mov	si,offset FadeMask1

again:
	mov	al, SDM_CUSTOM or mask SDM_INVERSE
	segmov	ds,cs					;segment of fades
	call	GrSetAreaMask

	call	GrGetWinBounds
	call	GrFillRect

	add	si, (FadeMask16-FadeMask15)
	cmp	si, offset FadeMask16
	jbe	again

	call	GrDestroyState

	.leave
	ret


BoardFadeOutScreen		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardTranslateScaleCoolString
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Apply translation and scale in stack frame to gstate

CALLED BY:	BoardFadeInCoolString

PASS:		
		di - gstate
		bp - inherited stack frame

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	10/28/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardTranslateScaleCoolString		proc	near
	uses	dx,cx,bx,ax

	.enter inherit BoardFadeInCoolString

	Assert	gstate di

	mov	dx,coolLocals.CSS_textPos.P_x
	mov	bx,coolLocals.CSS_textPos.P_y
	clr	ax,cx
	call	GrApplyTranslation

	movwwf	dxcx,coolLocals.CSS_scaleX
	movwwf	bxax,coolLocals.CSS_scaleY
	call	GrApplyScale

	.leave
	ret
BoardTranslateScaleCoolString		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardCalcCoolStringBounds
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Calculate the bounds of the text string

CALLED BY:	BoardFadeInCoolString

PASS:		
		di - gstate
		bp - inherited stack frame		
			coolLocals.CSS_stringOffset
		es - string segment

RETURN:		
		textPos and textSize in stack frame

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/22/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardCalcCoolStringBounds		proc	near
	uses	ax,bx,cx,dx,ds,si
	.enter inherit BoardFadeInCoolString

;;; Verify argument(s)
	Assert	gstate	di
;;;;;;;;

	segmov	ds,es
	mov	si,coolLocals.CSS_stringOffset
	Assert  nullTerminatedAscii dssi

	clr	ax,bx					;position
	call	GrGetTextBounds
	mov	coolLocals.CSS_textPos.P_x,ax
	mov	coolLocals.CSS_textPos.P_y,bx
	sub	cx,ax
	mov	coolLocals.CSS_textSize.P_x,cx
	sub	dx,bx
	mov	coolLocals.CSS_textSize.P_y,dx

	.leave
	ret
BoardCalcCoolStringBounds		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardShiftCoolStringBounds
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Shift textPos so that text will be drawn at upper left
		of window

CALLED BY:	BoardFadeInCoolString

PASS:		di - Gstate
		bp - inherited stack frame
			textPos
RETURN:		
		textPos changed

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/22/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardShiftCoolStringBounds		proc	near
	uses	ax,bx,cx,dx
	.enter inherit BoardFadeInCoolString

;;; Verify argument(s)
	Assert	gstate	di
;;;;;;;;

	call	GrGetWinBounds
	sub	ax,coolLocals.CSS_textPos.P_x
	mov	coolLocals.CSS_textPos.P_x,ax
	sub	bx,coolLocals.CSS_textPos.P_y
	mov	coolLocals.CSS_textPos.P_y,bx


	.leave
	ret
BoardShiftCoolStringBounds		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardCalcCoolScaleFactor
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Calc scale factor from text size to window size

CALLED BY:	BoardFadeInCoolString

PASS:		di - Gstate
		bp - inherited stack frame
			textSize
RETURN:		
		scaleX, scaleY

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/22/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardCalcCoolScaleFactor		proc	near
	uses	ax,bx,cx,dx
	.enter inherit BoardFadeInCoolString

;;; Verify argument(s)
	Assert	gstate	di
;;;;;;;;

	call	GrGetWinBounds
	sub	cx,ax				;window width
	mov	dx,cx
	mov	bx,coolLocals.CSS_textSize.P_x
	clr	ax,cx
	call	GrSDivWWFixed
	movwwf	coolLocals.CSS_scaleX,dxcx

	call	GrGetWinBounds
	sub	dx,bx				;window height
	mov	bx,coolLocals.CSS_textSize.P_y
	clr	ax,cx
	call	GrSDivWWFixed
	movwwf	coolLocals.CSS_scaleY,dxcx

	.leave
	ret
BoardCalcCoolScaleFactor		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardCreateGStateForCoolString
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Create a gstate for drawing the COOL string into

CALLED BY:	BoardFadeInCoolString

PASS:		
		*ds:si - Board
RETURN:		
		di - gstate
DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/22/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardCreateGStateForCoolString		proc	near
	uses	ax,cx,dx,bp
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	mov	ax,MSG_VIS_VUP_CREATE_GSTATE
	call	ObjCallInstanceNoLock
	mov	di,bp

	mov	al,mask TM_DRAW_ACCENT
	clr	ah
	call	GrSetTextMode

	mov	ax, C_WHITE or (CF_INDEX shl 8)
	call	GrSetAreaColor

	mov	cx,BOARD_TEXT_FONT
	clr	dx,ax
	call	GrSetFont
	mov	al,mask TS_BOLD
	clr	ah
	call	GrSetTextStyle
	mov	al,FW_MAXIMUM
	call	GrSetFontWeight

	.leave
	ret
BoardCreateGStateForCoolString		endp



FadeMask1	label	byte
	db	11111101b
	db	11111111b
	db	11011111b
	db	11111111b
	db	10111111b
	db	11111011b
	db	11111111b
	db	11111111b

	db	11111111b
	db	11101111b
	db	11111111b
	db	11111110b
	db	01111111b
	db	11111111b
	db	11011111b
	db	11111111b

	db	11101111b
	db	11111111b
	db	11110111b
	db	11111111b
	db	11111111b
	db	01111111b
	db	11111111b
	db	11111101b

	db	11111111b
	db	11111101b
	db	11111111b
	db	11110111b
	db	11111111b
	db	11111111b
	db	10111111b
	db	11101111b

	db	11111110b
	db	11111111b
	db	11111101b
	db	11111111b
	db	11111111b
	db	10111111b
	db	11111111b
	db	11110111b

	db	11011111b
	db	11111111b
	db	01111111b
	db	11111111b
	db	11111111b
	db	11011111b
	db	11111111b
	db	11111011b

	db	11111111b
	db	11111110b
	db	11111111b
	db	11101111b
	db	11011111b
	db	11111111b
	db	11111101b
	db	11111111b

	db	11111111b
	db	01111111b
	db	11111111b
	db	10111111b
	db	11101111b
	db	11111111b
	db	11110111b
	db	11111111b

	db	11111011b
	db	10111111b
	db	11111111b
	db	11111111b
	db	11110111b
	db	11111111b
	db	11101111b
	db	11111111b

	db	11111111b
	db	11110111b
	db	11111111b
	db	01111111b
	db	11111111b
	db	11111111b
	db	11111011b
	db	11011111b

	db	10111111b
	db	11111011b
	db	11111111b
	db	11111101b
	db	11111101b
	db	11111111b
	db	11111110b
	db	11111111b

	db	11111111b
	db	11111111b
	db	10111111b
	db	11111111b
	db	11111111b
	db	11111101b
	db	11111111b
	db	10111111b

	db	11111111b
	db	11011111b
	db	11111111b
	db	11111011b
	db	11111110b
	db	11111111b
	db	01111111b
	db	11111110b

	db	01111111b
	db	11111111b
	db	11111110b
	db	11111111b
	db	11111111b
	db	11101111b
	db	11111111b
	db	11111111b

FadeMask15	label	byte
	db	11110111b
	db	11111111b
	db	11101111b
	db	11111111b
	db	11111011b
	db	11111110b
	db	11111111b
	db	11111111b

FadeMask16	label	byte
	db	11111111b
	db	11111111b
	db	11111011b
	db	11011111b
	db	11111111b
	db	11110111b
	db	11111111b
	db	01111111b




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardDoShootingStars
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	

CALLED BY:	

PASS:		

RETURN:		

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardDoShootingStars		proc	far
	uses	ax,cx,dx,di,si
	.enter

	Assert	ObjectBoard	dssi

	call	BoardGetGStateDI
	mov	al,MM_INVERT
	call	GrSetMixMode

	call	ParticleArrayCreate
	jc	destroyState

	;    Always start with at least one star.
	;

	call	ShootingStarCreate

	;     Choose random number of stars to eventually create
	;

	mov	dx,MAX_STARS_CREATED
	mov	cx,MIN_STARS_CREATED
	call	BoardChooseRandom
	mov	bx,dx
	dec	bx

again:
	call	ParticleDraw
	mov	ax,3
	call	TimerSleep
	call	ParticleAdvance
	call	ParticleCleanup

	tst	bx				;stars left to create
	jz	checkForNoParticles

	;     Maybe create new star, but always continue because
	;     there are stars left to create.
	;

	mov	ax,PERCENT_CHANCE_OF_NEW_STAR
	call	BoardPercentageChance
	jnc	again				;jmp if don't create star
	call	ShootingStarCreate
	dec	bx
	jmp	again

checkForNoParticles:
	call	ChunkArrayGetCount
	tst	cx
	jnz	again

	mov	ax,si
	call	LMemFree

destroyState:
	call	GrDestroyState

	.leave
	ret

	


BoardDoShootingStars		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardPercentageChance
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Generate percentage chance event

CALLED BY:	

PASS:		
		ax - 0-100 percentage chance

RETURN:		
		carry clear - didn't happen
		carry set - happened

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardPercentageChance		proc	near
	uses	dx
	.enter

	mov	dx,100
	call	GameRandom
	inc	dx				;100-1 range
	cmp	ax,dx
	jge	itHappened
	clc
done:
	.leave
	ret

itHappened:
	stc
	jmp	done

BoardPercentageChance		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleArrayCreate
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Create chunk array for particles

CALLED BY:	BoardDoShootingStars

PASS:		
		ds - segment of object block

RETURN:		
		clc - array created
			si - chunk handle of chunk array
		stc - array not created
			si - destroyed

DESTROYED:	
		see RETURN

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleArrayCreate		proc	near
	uses	cx,dx
	.enter

	clr	al
	clr	cx,si
	mov	bx,size Particle
	call	ChunkArrayCreate

	.leave
	ret
ParticleArrayCreate		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ShootingStarCreate
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Create a shooting start chunk array element

CALLED BY:	

PASS:		
		*ds:si - chunk array
		di - gstate to window to draw shooting stars

RETURN:		
		clc - particle created
			ax - element
		stc - particle not created
			ax - destroyed

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ShootingStarCreate		proc	near
	uses	bx,cx,dx

initData	local	ParticleInit

	.enter

	Assert	ChunkArray	dssi
	Assert	gstate	di

	mov	dx,MAX_SPARK_PROB
	mov	cx,MIN_SPARK_PROB
	call	BoardChooseRandom
	mov	initData.PI_sparkProb,dl

	;    Choose gravity.
	;

	mov	dx,MAX_STAR_VERT_GRAVITY_INT
	mov	cx,MIN_STAR_VERT_GRAVITY_INT
	mov	bx,MAX_STAR_VERT_GRAVITY_FRAC
	mov	ax,MIN_STAR_VERT_GRAVITY_FRAC
	call	ParticleChooseVelocity
	movwwf	initData.PI_gravity.PF_y,dxax
	clrwwf	initData.PI_gravity.PF_x



	;    Choose vertical velocity. Always negative so stars
	;    start out shooting upwards.
	;

	mov	dx,MAX_STAR_VERT_VELOCITY_INT
	mov	cx,MIN_STAR_VERT_VELOCITY_INT
	mov	bx,MAX_STAR_VERT_VELOCITY_FRAC
	mov	ax,MIN_STAR_VERT_VELOCITY_FRAC
	call	ParticleChooseVelocity
	negwwf	dxax				;always start up
	movwwf	initData.PI_velocity.PF_y,dxax

	;    Choose horiz velocity
	;

	mov	dx,MAX_STAR_HORIZ_VELOCITY_INT
	mov	cx,MIN_STAR_HORIZ_VELOCITY_INT
	mov	bx,MAX_STAR_HORIZ_VELOCITY_FRAC
	mov	ax,MIN_STAR_HORIZ_VELOCITY_FRAC
	call	ParticleChooseVelocity
	movwwf	initData.PI_velocity.PF_x,dxax

	;    Choose left or right side of window and switch velocity
	;    direction if starting from the right side
	;

	call	GrGetWinBounds
	mov	dx,2
	call	GameRandom
	tst	dx
	je	gotSide				;using left
	mov	ax,cx
	negwwf	initData.PI_velocity.PF_x
	negwwf	initData.PI_gravity.PF_x
gotSide:
	mov	initData.PI_position.P_x,ax

	;    Choose vertical position in top 75% of screen
	;

	call	GrGetWinBounds
	sub	dx,bx					;win height
	mov	ax,dx					;win height
	shr	ax					;50% win height
	shr	ax					;25% win height
	sub	dx,ax					;range = 75% win height
	call	GameRandom
	add	dx,bx					;down from top
	mov	initData.PI_position.P_y,dx

	mov	initData.PI_width,STAR_WIDTH
	mov	initData.PI_height,STAR_HEIGHT

	call	ParticleCreate

	.leave
	ret

ShootingStarCreate		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleChooseVelocity
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Calc random velocity

CALLED BY:	ShootingStartCreate

PASS:		
		dx - max int 
		cx - min int 
		bx - max frac 
		ax - min frac 

RETURN:		
		dx:ax - WWFixed velocity

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleChooseVelocity		proc	near
	.enter

	push	dx,cx			;max int,min int
	movdw	dxcx,bxax		;max frac, min frac
	call	BoardChooseRandom
	mov	ax,dx			;frac

	pop	dx,cx			;max int, min int
	call	BoardChooseRandom

	.leave
	ret
ParticleChooseVelocity		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		BoardChooseRandom
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Choose random number in range

CALLED BY:	

PASS:		
		dx - max
		cx - min

RETURN:		
		dx

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BoardChooseRandom		proc	near
	.enter

EC<	cmp	dx,cx				>
EC<	ERROR_B	255	>

	sub	dx,cx			;sub min to get range
	inc	dx
	call	GameRandom
	add	dx,cx			;add min

	.leave
	ret
BoardChooseRandom		endp





COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleCreate
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Create a new particle in the chunk array

CALLED BY:	ShootingStarCreate

PASS:		
		*ds:si - chunk array
		bp - inherited stack frame

RETURN:		
		clc - particle created
			ax - element
		stc - particle not created
			ax - destroyed

DESTROYED:	
		see RETURN

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleCreate		proc	near
	uses	cx,dx,di

initData	local	ParticleInit

	.enter	inherit

	call	ChunkArrayAppend
	jc	done

	clr	dx
	mov	cx, initData.PI_position.P_x
	movdw	ds:[di].P_curPosition.PF_x,cxdx
	mov	cx, initData.PI_position.P_y
	movdw	ds:[di].P_curPosition.PF_y,cxdx

	movdw	cxdx, initData.PI_velocity.PF_x
	movdw	ds:[di].P_velocity.PF_x,cxdx
	movdw	cxdx, initData.PI_velocity.PF_y
	movdw	ds:[di].P_velocity.PF_y,cxdx

	movdw	cxdx, initData.PI_gravity.PF_x
	movdw	ds:[di].P_gravity.PF_x,cxdx
	movdw	cxdx, initData.PI_gravity.PF_y
	movdw	ds:[di].P_gravity.PF_y,cxdx

	mov	cl, initData.PI_sparkProb
	mov	ds:[di].P_sparkProb,cl

	mov	cl, initData.PI_width
	mov	ds:[di].P_width,cl
	mov	cl, initData.PI_height
	mov	ds:[di].P_height,cl

	clr	ds:[di].P_info

	clc

done:
	.leave
	ret
ParticleCreate		endp






COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleDraw
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Draw all particles in the passed particle array

CALLED BY:	

PASS:		
		*ds:si - particle chunk array
		di - gstate

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleDraw		proc	near
	uses	bx,di,bp
	.enter

	Assert	gstate	di
	Assert	ChunkArray dssi

	mov	bp,di				;gstate
	mov	bx,cs
	mov	di,offset ParticleDrawCallback
	call	ChunkArrayEnum

	.leave
	ret
ParticleDraw		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleDrawCallback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Draw the particle if not already drawn

CALLED BY:	ChunkArrayEnum

PASS:		ds:di - particle
		bp - gstate

RETURN:		
		carry clear

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleDrawCallback		proc	far
	uses	di,ax,bx,cx,dx,bp
	.enter

	Assert	gstate	bp

	;    Draw at new position
	;

	BitSet	ds:[di].P_info, PI_DRAWN

	movwwf	axcx,ds:[di].P_curPosition.PF_x
	rndwwf	axcx
	movwwf	bxcx,ds:[di].P_curPosition.PF_y
	rndwwf	bxcx
	cmp	ax,ds:[bp].P_lastDrawnPosition.P_x
	je	checkNoChange

drawNew:
	mov	cl,ds:[di].P_width
	mov	ch,ds:[di].P_height

	xchg	di,bp					;gstate,offset
	call	DrawAParticle

	;    Save just drawn position and Erase at old position if initialized 
	;

	xchg	ax,ds:[bp].P_lastDrawnPosition.P_x
	xchg	bx,ds:[bp].P_lastDrawnPosition.P_y

	test	ds:[bp].P_info, mask PI_LAST_DRAWN_INITIALIZED
	jz	initLastDrawn

	call	DrawAParticle

initLastDrawn:
	BitSet	ds:[bp].P_info, PI_LAST_DRAWN_INITIALIZED


done:
	clc
	.leave
	ret

checkNoChange:
	cmp	bx,ds:[bp].P_lastDrawnPosition.P_y
	jne	drawNew
	jmp	done
	

ParticleDrawCallback		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		DrawAParticle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	

CALLED BY:	

PASS:		
		di - gstate
		ax - x
		bx - y
		cl - width
		ch - height
RETURN:		

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
DrawAParticle		proc	near
	uses	cx,dx
	.enter

	mov	dl,ch				;height
	clr	ch,dh				;high byte of width and height
	add	cx,ax
	add	dx,bx
	call	GrFillRect

	.leave
	ret
DrawAParticle		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleEraseCallback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Erase the particle if it is drawn

CALLED BY:	ChunkArrayEnum

PASS:		ds:di - particle
		bp - gstate

RETURN:		
		carry clear

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleEraseCallback		proc	far
	uses	di,ax,bx,cx
	.enter

	Assert	gstate	bp

	test	ds:[di].P_info,mask PI_DRAWN
	jz	done
	test	ds:[di].P_info,mask PI_LAST_DRAWN_INITIALIZED
	jz	done

	BitClr	ds:[di].P_info,PI_DRAWN

	mov	ax,ds:[di].P_lastDrawnPosition.P_x
	mov	bx,ds:[di].P_lastDrawnPosition.P_y
	mov	cl,ds:[di].P_width
	mov	ch,ds:[di].P_height
	mov	di,bp
	call	DrawAParticle
done:
	clc

	.leave
	ret
ParticleEraseCallback		endp





COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleAdvance
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Advance all particles in the passed particle array

CALLED BY:	

PASS:		
		*ds:si - particle chunk array

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleAdvance		proc	near
	uses	bx,di,bp
	.enter

	Assert	ChunkArray dssi

	mov	bx,cs
	mov	di,offset ParticleAdvanceCallback
	call	ChunkArrayEnum

	.leave
	ret
ParticleAdvance		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleAdvanceCallback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Advance the particle

CALLED BY:	ChunkArrayEnum

PASS:		ds:di - particle

RETURN:		
		carry clear

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleAdvanceCallback		proc	far
	uses	di,bx,ax
	.enter

	;    Treat x gravity as drag in opposite direction of
	;    velocity
	;

	movwwf	bxax,ds:[di].P_velocity.PF_x
	addwwf	ds:[di].P_curPosition.PF_x,bxax
	tst	bx
	movwwf	bxax,ds:[di].P_gravity.PF_x
	js	10$
	negwwf	bxax
10$:
	addwwf	ds:[di].P_velocity.PF_x,bxax

	;     Treat y gravity as gravity, increasing downward velocity
	;

	movwwf	bxax,ds:[di].P_velocity.PF_y
	addwwf	ds:[di].P_curPosition.PF_y,bxax
	movwwf	bxax,ds:[di].P_gravity.PF_y
	addwwf	ds:[di].P_velocity.PF_y,bxax
	
	clr	ah
	mov	al,ds:[di].P_sparkProb
	call	BoardPercentageChance
	jc	makeSpark

done:
	clc

	.leave
	ret

makeSpark:
	call	SparkCreate
	jmp	done

ParticleAdvanceCallback		endp


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		SparkCreate
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Create a spark chunk array element. Append it so that
		it will have moved away from the original before the
		next drawing operation

CALLED BY:	

PASS:		
		*ds:si - chunk array
		ds:di - source particle

RETURN:		
		clc - particle created
			ax - element
		stc - particle not created
			ax - destroyed

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
SparkCreate		proc	near
	uses	ax,bx,cx,dx

initData	local	ParticleInit

	.enter

	Assert	ChunkArray	dssi

	;    Spark gets same position
	;

	movwwf	cxdx,ds:[di].P_curPosition.PF_x
	rndwwf	cxdx
	mov	initData.PI_position.P_x,cx
	movwwf	cxdx,ds:[di].P_curPosition.PF_y
	rndwwf	cxdx
	mov	initData.PI_position.P_y,cx

	;    no babies
	;	

	clr	initData.PI_sparkProb

	;    Give spark random y gravity bigger than source and
	;    a small x gravity opposite in direction to velocity
	;

	mov	dx,MAX_STAR_TO_SPARK_GRAVITY_INCREASE_INT
	mov	bx,MAX_STAR_TO_SPARK_GRAVITY_INCREASE_FRAC
	mov	cx,MIN_STAR_TO_SPARK_GRAVITY_INCREASE_INT
	mov	ax,MIN_STAR_TO_SPARK_GRAVITY_INCREASE_FRAC
	call	ParticleChooseVelocity
	addwwf	dxax,ds:[di].P_gravity.PF_y
	movwwf	initData.PI_gravity.PF_y,dxax

	mov	dx,MAX_SPARK_HORIZ_DRAG_INT
	mov	cx,MIN_SPARK_HORIZ_DRAG_INT
	mov	bx,MAX_SPARK_HORIZ_DRAG_FRAC
	mov	ax,MIN_SPARK_HORIZ_DRAG_FRAC
	call	ParticleChooseVelocity
	movwwf	initData.PI_gravity.PF_x,dxax

	;    Modify the velocity half of the max increase either up
	;    or down.
	;
	
	mov	bx,MAX_STAR_TO_SPARK_VERT_VELOCITY_INCREASE_FRAC
	mov	dx,MAX_STAR_TO_SPARK_VERT_VELOCITY_INCREASE_INT
	clr	ax,cx
	call	ParticleChooseVelocity
	sub	dx,MAX_STAR_TO_SPARK_VERT_VELOCITY_INCREASE_HALF; sub half from
	addwwf	dxax,ds:[di].P_velocity.PF_y
	movwwf	initData.PI_velocity.PF_y,dxax

	;    Give small horiz velocity in same direction
	;

	mov	dx,MAX_SPARK_HORIZ_VELOCITY_INT
	mov	cx,MIN_SPARK_HORIZ_VELOCITY_INT
	mov	bx,MAX_SPARK_HORIZ_VELOCITY_FRAC
	mov	ax,MIN_SPARK_HORIZ_VELOCITY_FRAC
	call	ParticleChooseVelocity
	tst	ds:[di].P_velocity.PF_x.WWF_int
	jns	20$
	negwwf	dxax
20$:
	movwwf	initData.PI_velocity.PF_x,dxax

	mov	dx,SPARK_MAX_WIDTH
	mov	cx,SPARK_MIN_WIDTH
	call	BoardChooseRandom
	mov	initData.PI_width,dl

	mov	dx,SPARK_MAX_HEIGHT
	mov	cx,SPARK_MIN_HEIGHT
	call	BoardChooseRandom
	mov	initData.PI_height,dl

	call	ParticleCreate

	.leave
	ret


SparkCreate		endp



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleCleanup
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Delete all particles no longer on the screen

CALLED BY:	

PASS:		
		*ds:si - particle chunk array
		di - gstate

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleCleanup		proc	near
	uses	bx,di,bp
	.enter

	Assert	ChunkArray dssi
	Assert	gstate	di

	call	GrGetWinBounds
	mov	bp,di				;gstate

	mov	bx,cs
	mov	di,offset ParticleCleanupCallback
	call	ChunkArrayEnum

	.leave
	ret
ParticleCleanup		endp




COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		ParticleCleanupCallback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Erase and delete this particle if it has gone off the
		left, right or bottom of screen

CALLED BY:	ChunkArrayEnum

PASS:		ds:di - particle
		ax - left
		cx - right
		dx - bottom
		bp - gstate

RETURN:		
		carry clear

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	9/23/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ParticleCleanupCallback		proc	far
	uses	di
	.enter

	Assert	gstate	bp

	cmp	ax,ds:[di].P_curPosition.PF_x.WWF_int
	jg	cleanup
	cmp	cx,ds:[di].P_curPosition.PF_x.WWF_int
	jl	cleanup
	cmp	dx,ds:[di].P_curPosition.PF_y.WWF_int
	jl	cleanup
	
done:
	clc

	.leave
	ret

cleanup:
	call	ParticleEraseCallback
	call	ChunkArrayDelete
	jmp	done

ParticleCleanupCallback		endp






COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		CwordEnableDisableClearXSquares
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	If there are any wrong squares in the puzzle then
		enable Clear X Squares

CALLED BY:	UTILITY

PASS:		*ds:si - Board

RETURN:		
		nothing

DESTROYED:	
		nothing

PSEUDO CODE/STRATEGY:
		none

KNOWN BUGS/SIDE EFFECTS/IDEAS:
		none

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	srs	11/ 8/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
CwordEnableDisableClearXSquares		proc	far
	class	CwordBoardClass
	uses	ax,bx,cx,dx,si,di,bp
	.enter

;;; Verify argument(s)
	Assert	ObjectBoard	dssi
;;;;;;;;

	GetInstanceDataPtrDSBX	CwordBoard_offset
	mov	dx,ds:[bx].CBI_engine
	tst	dx
	jz	notEnabled
	call	EngineFindFirstWrongCell
	jnc	notEnabled

	mov	ax,MSG_GEN_SET_ENABLED
sendMessage:
	mov	bx,handle ClearXButton
	mov	si,offset ClearXButton
	mov	di,mask MF_FIXUP_DS
	mov	dl, VUM_NOW
	call	ObjMessage

	.leave
	ret

notEnabled:
	mov	ax,MSG_GEN_SET_NOT_ENABLED
	jmp	sendMessage


CwordEnableDisableClearXSquares		endp


CwordVictoryCode	ends

