'
' NeoLib - Font Module
'
' Features:
'  12 subs
'  2 functions
' For a total of: 14 routines
'
' Specially designed and coded for AAP's QBCPC
' Official Library of the QuickBASIC Caliber Programming Compo (Summer & Autumn 2003)
'

DECLARE FUNCTION neoFontLen% (Text AS STRING)
DECLARE FUNCTION neoFontOpen% (FontFile AS STRING)

DECLARE SUB neoFontInitLayers ()
DECLARE SUB neoFontPrint (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Colour AS INTEGER, Italic AS INTEGER)
DECLARE SUB neoFontPrintT (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Italic AS INTEGER)
DECLARE SUB neoFontPrintG (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Colour AS INTEGER, Italic AS INTEGER)
DECLARE SUB neoFontPrintB (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Colour AS INTEGER, Italic AS INTEGER, Tex%, Grad%, StdPal AS STRING, Neg AS INTEGER)
DECLARE SUB neoFontPrintN (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Italic AS INTEGER, StdPal AS STRING)
DECLARE SUB neoFontPrintS (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, xScale AS INTEGER, yScale AS INTEGER, Colour AS INTEGER, Italic AS INTEGER, Tex%, Grad%)
DECLARE SUB neoFontPrintSB (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, xScale AS INTEGER, yScale AS INTEGER, Colour AS INTEGER, Italic AS INTEGER, Tex%, Grad%, StdPal AS STRING, Neg AS INTEGER)
DECLARE SUB neoFontPrintSN (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, xScale AS INTEGER, yScale AS INTEGER, Italic AS INTEGER, StdPal AS STRING)
DECLARE SUB neoFontSetTexture (TexSeg AS INTEGER, TexOff AS INTEGER)
DECLARE SUB neoFontSetClipBox (X1 AS INTEGER, Y1 AS INTEGER, X2 AS INTEGER, Y2 AS INTEGER)
DECLARE SUB neoFontClose (FontHandle AS INTEGER)


DEFINT A-Z
'$DYNAMIC
'$INCLUDE: 'QB.BI'
'$INCLUDE: 'neoEMS.bi'
'$INCLUDE: 'neoLAYER.bi'

DIM SHARED Regs AS RegType
DIM SHARED RegsX AS RegTypeX
DIM SHARED FontHandle AS INTEGER
DIM SHARED fClipBox(4) AS INTEGER
DIM SHARED FontTexture(32) AS INTEGER
DIM SHARED FBYTE AS STRING * 1

'/////////////////////////////////////////////////////////////////////////
' FUNCTIONS
'/////////////////////////////////////////////////////////////////////////
FUNCTION neoFontLen (Text AS STRING)
	'returns the amount of pixels needed to display Text
	'- Text: the text to calculate length from
	'Returns: the amount of pixels needed, or -1 when text is too long

	IF LEN(Text) > 4090 THEN neoFontLen = -1
	neoFontLen = LEN(Text) * 8
END FUNCTION

FUNCTION neoFontOpen (FontFile AS STRING)
	'Opens a Font File for use with NeoLib
	'- FontFile: the font file, with full extension
	'Returns: Font Handle (keep this one!)

	FF = FREEFILE
	OPEN FontFile FOR BINARY AS #FF
		SEEK #FF, 1

	neoFontOpen = FF
END FUNCTION

'/////////////////////////////////////////////////////////////////////////
' SUBS
'/////////////////////////////////////////////////////////////////////////
SUB neoFontClose (FontHandle AS INTEGER)
	'Closes a font file
	'- FontHandle: handle of the font file
	CLOSE #FontHandle
END SUB

SUB neoFontInitLayers
	'initializes the font module for use with created layers
	'CALL THIS ROUTINE BEFORE USING ANY OTHER FONT ROUTINE!!!

	FontHandle = neoLayerGetHandle

	fClipBox(0) = 0
	fClipBox(1) = 319
	fClipBox(2) = 0
	fClipBox(3) = 199
END SUB

SUB neoFontPrint (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Colour AS INTEGER, Italic AS INTEGER)
        'prints text on a specified layer
        '- FontHandle: handle of the font file
        '- Layer: layer to print on (0 or VIDEO for the screen)
        '- Text: the text to print
        '- xPos: the start xposition to display the text
        '- yPos: the y-position to display the text on
        '- Colour: the colour to display the text with
        '- Italic: TRUE or FALSE whether to display the text in italic

	IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	DEF SEG = addr%
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)

			nowY% = yPos + scanline
			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	nowX% = xposnow% + (7 - bit) + (3 - scanline \ 2) * ABS(Italic)
                                	IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN
                                		POKE 320& * nowY% + nowX%, Colour
                                	END IF
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontPrintT (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Italic AS INTEGER)
        'prints textured text on a specified layer
        '- FontHandle: handle of the font file
        '- Layer: layer to print on (0 or VIDEO for the screen)
        '- Text: the text to print
        '- xPos: the start xposition to display the text
        '- yPos: the y-position to display the text on
        '- Italic: TRUE or FALSE whether to display the text in italic

	IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	texseg% = VARSEG(FontTexture(0))
	texoff% = VARPTR(FontTexture(0))
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)

			nowY% = yPos + scanline
			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	nowX% = xposnow% + (7 - bit) + (3 - scanline \ 2) * ABS(Italic)
                                	IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN
                                		DEF SEG = texseg%
						texCol% = PEEK(texoff%  + scanline * 8 + 7 - bit)

                                		DEF SEG = addr%
                                		POKE 320& * nowY% + nowX%, texCol%
                                	END IF
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontPrintG (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Colour AS INTEGER, Italic AS INTEGER)
        'prints gradiented text on a specified layer
        '- FontHandle: handle of the font file
        '- Layer: layer to print on (0 or VIDEO for the screen)
        '- Text: the text to print
        '- xPos: the start xposition to display the text
        '- yPos: the y-position to display the text on
        '- Colour: the colour to display the text with
        '- Italic: TRUE or FALSE whether to display the text in italic

	IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)

			DEF SEG = addr%
			nowY% = yPos + scanline
			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	nowX% = xposnow% + (7 - bit) + (3 - scanline \ 2) * ABS(Italic)
                                	IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN
                                		POKE 320& * nowY% + nowX%, Colour + scanline
                                	END IF
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontPrintB (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Colour AS INTEGER, Italic AS INTEGER, Textured AS INTEGER, Gradiented AS INTEGER, StdPal AS STRING, Neg AS INTEGER)
	'prints blended text on a layer
	'- FontHandle: handle of the font file
        '- Layer: layer to print on (0 or VIDEO for the screen)
        '- Text: the text to print
        '- xPos: the start xposition to display the text
        '- yPos: the y-position to display the text on
        '- Colour: colour to draw the text with
        '- Italic: TRUE or FALSE whether to display the text in italic
        '- Textured: TRUE or FALSE whether to display the text with a texture
        '- Gradiented: TRUE or FALSE whether to display the text with a gradient
        '- StdPal: current 768-byte string palette
        '- Neg: FALSE for positive blending, TRUE for negative blending

        IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	texseg% = VARSEG(FontTexture(0))
	texoff% = VARPTR(FontTexture(0))
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)


			nowY% = yPos + scanline
			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	nowX% = xposnow% + (7 - bit) + (3 - scanline \ 2) * ABS(Italic)
                                	IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN
                                		valuehere% = Colour
                                		IF Gradiented THEN valuehere% = Colour + scanline
                                		IF Textured THEN
                                			DEF SEG = texseg%
							valuehere% = PEEK(texoff%  + scanline * 8 + 7 - bit)
						END IF

						'get the therecolour
						DEF SEG = addr%
						valuethere% = PEEK(320& * nowY% + nowX%)

						aR = ASC(MID$(StdPal, valuehere% * 3 + 1, 1))
 						aG = ASC(MID$(StdPal, valuehere% * 3 + 2, 1))
 						aB = ASC(MID$(StdPal, valuehere% * 3 + 3, 1))

 						dR = ASC(MID$(StdPal, valuethere% * 3 + 1, 1))
 						dG = ASC(MID$(StdPal, valuethere% * 3 + 2, 1))
 						dB = ASC(MID$(StdPal, valuethere% * 3 + 3, 1))

 						IF NOT Neg THEN
 							mR = aR + dR
 							mG = aG + dG
 							mB = aB + dB
 							IF mR > 63 THEN mR = 63
 							IF mG > 63 THEN mG = 63
 							IF mB > 63 THEN mB = 63
 						ELSE
 							mR = ABS(aR - dR)
 							mG = ABS(aG - dG)
 							mB = ABS(aB - dB)
 						END IF

						'search best matching color in StdPal, equal to neoPalSearchIn
 						mindif% = 32000
 						minimum% = 0
 						FOR checkC = 0 TO 255
							aR = ASC(MID$(StdPal, checkC * 3 + 1, 1))
							aG = ASC(MID$(StdPal, checkC * 3 + 2, 1))
							aB = ASC(MID$(StdPal, checkC * 3 + 3, 1))
                                			dif% = ABS(mR - aR) + ABS(mG - aG) + ABS(mB - aB)
                                			IF dif% < mindif% THEN mindif% = dif%: minimum% = checkC
 						NEXT checkC

                                		DEF SEG = addr%
                                		POKE 320& * nowY% + nowX%, minimum%
                                	END IF
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontPrintS (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, xScale AS INTEGER, yScale AS INTEGER, Colour AS INTEGER, Italic AS INTEGER, Textured AS INTEGER, Gradiented AS INTEGER)
	'prints scaled text on a layer
	'- FontHandle: handle of the font file
        '- Layer: layer to print on (0 or VIDEO for the screen)
        '- Text: the text to print
        '- xPos: the start xposition to display the text
        '- yPos: the y-position to display the text on
        '- xScale: x-scale of the text (>= 1)
        '- yScale: y-scale of the text (>= 1)
        '- Colour: colour to draw the text with
        '- Italic: TRUE or FALSE whether to display the text in italic
        '- Textured: TRUE or FALSE whether to display the text with a texture
        '- Gradiented: TRUE or FALSE whether to display the text with a gradient

	IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	texseg% = VARSEG(FontTexture(0))
	texoff% = VARPTR(FontTexture(0))
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)

			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	clr% = Colour
                                       	IF Gradiented THEN clr% = Colour + scanline
                                        IF Textured THEN
                                        	DEF SEG = texseg%
                                                clr% = PEEK(texoff% + scanline * 8 + 7 - bit)
                                        END IF
                                	FOR xScaled = 0 TO xScale - 1
                                		FOR yScaled = 0 TO yScale - 1
                                			nowX% = xposnow% + (7 - bit) * xScale + (3 - scanline \ 2) * ABS(Italic) * xScale + xScaled
                                			nowY% = yPos + scanline * yScale + yScaled
                                			IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN
                                				DEF SEG = addr%
                                				POKE 320& * nowY% + nowX%, clr%
                                			END IF
                                		NEXT yScaled
                                	NEXT xScaled
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8 * xScale
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontPrintSB (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, xScale AS INTEGER, yScale AS INTEGER, _
		    Colour AS INTEGER, Italic AS INTEGER, Textured AS INTEGER, Gradiented AS INTEGER, StdPal AS STRING, Neg AS INTEGER)
	'prints scaled blended text on a layer
	'- FontHandle: handle of the font file
        '- Layer: layer to print on (0 or VIDEO for the screen)
        '- Text: the text to print
        '- xPos: the start xposition to display the text
        '- yPos: the y-position to display the text on
        '- xScale: x-scale of the text (>= 1)
        '- yScale: y-scale of the text (>= 1)
        '- Colour: colour to draw the text with
        '- Italic: TRUE or FALSE whether to display the text in italic
        '- Textured: TRUE or FALSE whether to display the text with a texture
        '- Gradiented: TRUE or FALSE whether to display the text with a gradient
        '- StdPal: current 768-byte string palette
        '- Neg: FALSE for positive blending, TRUE for negative blending

	IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	texseg% = VARSEG(FontTexture(0))
	texoff% = VARPTR(FontTexture(0))
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)

			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	clr% = Colour
                                       	IF Gradiented THEN clr% = Colour + scanline
                                        IF Textured THEN
                                        	DEF SEG = texseg%
                                                clr% = PEEK(texoff% + scanline * 8 + 7 - bit)
                                        END IF
                                	FOR xScaled = 0 TO xScale - 1
                                		FOR yScaled = 0 TO yScale - 1
                                			nowX% = xposnow% + (7 - bit) * xScale + (3 - scanline \ 2) * ABS(Italic) * xScale + xScaled
                                			nowY% = yPos + scanline * yScale + yScaled
                                			IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN
                                				valuehere% = clr%
                                				'get the therecolour
								DEF SEG = addr%
								valuethere% = PEEK(320& * nowY% + nowX%)

								aR = ASC(MID$(StdPal, valuehere% * 3 + 1, 1))
 								aG = ASC(MID$(StdPal, valuehere% * 3 + 2, 1))
 								aB = ASC(MID$(StdPal, valuehere% * 3 + 3, 1))

 								dR = ASC(MID$(StdPal, valuethere% * 3 + 1, 1))
 								dG = ASC(MID$(StdPal, valuethere% * 3 + 2, 1))
 								dB = ASC(MID$(StdPal, valuethere% * 3 + 3, 1))

 								IF NOT Neg THEN
 									mR = aR + dR
 									mG = aG + dG
 									mB = aB + dB
 									IF mR > 63 THEN mR = 63
 									IF mG > 63 THEN mG = 63
 									IF mB > 63 THEN mB = 63
 								ELSE
 									mR = ABS(aR - dR)
 									mG = ABS(aG - dG)
 									mB = ABS(aB - dB)
 								END IF

								'search best matching color in StdPal, equal to neoPalSearchIn
 								mindif% = 32000
 								minimum% = 0
 								FOR checkC = 0 TO 255
									aR = ASC(MID$(StdPal, checkC * 3 + 1, 1))
									aG = ASC(MID$(StdPal, checkC * 3 + 2, 1))
									aB = ASC(MID$(StdPal, checkC * 3 + 3, 1))
                                					dif% = ABS(mR - aR) + ABS(mG - aG) + ABS(mB - aB)
                                					IF dif% < mindif% THEN mindif% = dif%: minimum% = checkC
 								NEXT checkC

                                				DEF SEG = addr%
                                				POKE 320& * nowY% + nowX%, minimum%
                                			END IF
                                		NEXT yScaled
                                	NEXT xScaled
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8 * xScale
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontPrintN (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, Italic AS INTEGER, StdPal AS STRING)
	'prints font on a layer, negatively
	'- FontHandle: handle of the font file
	'- Layer: layer to print font on
	'- Text: text to print
	'- xPos: xposition to draw text
	'- yPos: yposition to draw text
	'- Italic: flag, TRUE or FALSE, whether the font is printed in italic
	'- StdPal: current 768-byte string palette

	IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	texseg% = VARSEG(FontTexture(0))
	texoff% = VARPTR(FontTexture(0))
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)

			nowY% = yPos + scanline
			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	nowX% = xposnow% + (7 - bit) + (3 - scanline \ 2) * ABS(Italic)
                                	IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN
                                		'get the therecolour
						DEF SEG = addr%
						valuethere% = PEEK(320& * nowY% + nowX%)

						dR = ASC(MID$(StdPal, valuethere% * 3 + 1, 1))
 						dG = ASC(MID$(StdPal, valuethere% * 3 + 2, 1))
 						dB = ASC(MID$(StdPal, valuethere% * 3 + 3, 1))

 						mR = 63 - dR
 						mG = 63 - dG
 						mB = 63 - dB

						'search best matching color in StdPal, equal to neoPalSearchIn
 						mindif% = 32000
 						minimum% = 0
 						FOR checkC = 0 TO 255
							aR = ASC(MID$(StdPal, checkC * 3 + 1, 1))
							aG = ASC(MID$(StdPal, checkC * 3 + 2, 1))
							aB = ASC(MID$(StdPal, checkC * 3 + 3, 1))
                                			dif% = ABS(mR - aR) + ABS(mG - aG) + ABS(mB - aB)
                                			IF dif% < mindif% THEN mindif% = dif%: minimum% = checkC
 						NEXT checkC

                                		DEF SEG = addr%
                                		POKE 320& * nowY% + nowX%, minimum%
                                	END IF
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontPrintSN (FontHandle AS INTEGER, Layer AS INTEGER, Text AS STRING, xPos AS INTEGER, yPos AS INTEGER, xScale AS INTEGER, yScale AS INTEGER, Italic AS INTEGER, StdPal AS STRING)
	'prints scaled negativised text on a layer
	'- FontHandle: handle of the font file
        '- Layer: layer to print on (0 or VIDEO for the screen)
        '- Text: the text to print
        '- xPos: the start xposition to display the text
        '- yPos: the y-position to display the text on
        '- xScale: x-scale of the text (>= 1)
        '- yScale: y-scale of the text (>= 1)
        '- Italic: TRUE or FALSE whether to display the text in italic
        '- StdPal: current 768-byte string palette

	IF Layer = VIDEO THEN
		addr% = &HA000
	ELSE
		addr% = neoEMSpageFrame
		neoEMSmapX (Layer - 1) * 4, 0, 4, FontHandle
	END IF


	xposnow% = xPos
	texseg% = VARSEG(FontTexture(0))
	texoff% = VARPTR(FontTexture(0))
	FOR I = 1 TO LEN(Text)
		ascii% = ASC(MID$(Text, I, 1))
		FOR scanline = 0 TO 7
			GET #FontHandle, ascii% * 8& + scanline + 1, FBYTE
			ScanData = ASC(FBYTE)

			FOR bit = 0 TO 7
                                IF (ScanData AND (2 ^ bit)) > 0 THEN
                                	FOR xScaled = 0 TO xScale - 1
                                		FOR yScaled = 0 TO yScale - 1
                                			nowX% = xposnow% + (7 - bit) * xScale + (3 - scanline \ 2) * ABS(Italic) * xScale + xScaled
                                			nowY% = yPos + scanline * yScale + yScaled
                                			IF nowX% >= fClipBox(0) AND nowX% <= fClipBox(1) AND nowY% >= fClipBox(2) AND nowY% <= fClipBox(3) THEN

                                				'get the therecolour
								DEF SEG = addr%
								valuethere% = PEEK(320& * nowY% + nowX%)

								dR = ASC(MID$(StdPal, valuethere% * 3 + 1, 1))
 								dG = ASC(MID$(StdPal, valuethere% * 3 + 2, 1))
 								dB = ASC(MID$(StdPal, valuethere% * 3 + 3, 1))

 								mR = 63 - dR
 								mG = 63 - dG
 								mB = 63 - dB

								'search best matching color in StdPal, equal to neoPalSearchIn
 								mindif% = 32000
 								minimum% = 0
 								FOR checkC = 0 TO 255
									aR = ASC(MID$(StdPal, checkC * 3 + 1, 1))
									aG = ASC(MID$(StdPal, checkC * 3 + 2, 1))
									aB = ASC(MID$(StdPal, checkC * 3 + 3, 1))
                                					dif% = ABS(mR - aR) + ABS(mG - aG) + ABS(mB - aB)
                                					IF dif% < mindif% THEN mindif% = dif%: minimum% = checkC
 								NEXT checkC

                                				DEF SEG = addr%
                                				POKE 320& * nowY% + nowX%, minimum%
                                			END IF
                                		NEXT yScaled
                                	NEXT xScaled
                                END IF
			NEXT bit
		NEXT scanline
		xposnow% = xposnow% + 8 * xScale
	NEXT I

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
                        neoEMSmove 0, addr%, &H4000& * I, FontHandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoFontSetTexture (TexSeg AS INTEGER, TexOff AS INTEGER)
	'sets the default font texture for text
	'- TexSeg: the segment of the font texture
	'- TexOff: the offset of the font texture

	FOR I = 0 TO 63
		DEF SEG = TexSeg
		byte% = PEEK(TexOff + 4 + I)

		DEF SEG = VARSEG(FontTexture(0))
		POKE VARPTR(FontTexture(0)) + I, byte%
	NEXT I
END SUB

SUB neoFontSetClipBox (X1 AS INTEGER, Y1 AS INTEGER, X2 AS INTEGER, Y2 AS INTEGER)
	'sets the clipbox
	'- X1: upperleft x-corner of the clipbox
	'- Y1: upperleft y-corner of the clipbox
	'- X2: lowerright x-corner of the clipbox
	'- Y2: lowerright y-corner of the clipbox

	fClipBox(0) = X1
	fClipBox(1) = X2
	fClipBox(2) = Y1
	fClipBox(3) = Y2
END SUB
