Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

7. Obsluha čísel

Nyní se budeme zabývat vykreslováním číslic na digitální displej automatu. Do souboru PROGRAM.ASM, na konec části s "include", doplňte řádek %include "DIGITS.ASM". Zrušte návěští InitDigOff, skupinu proměnných označenou komentářem "Digits" a naopak doplňte následující proměnné:


Credit:		dw	100		; current credit
Bet:		db	1		; current bet (0=no, 1-5=low, 6=high)
Win:		dw	750		; current win
Bank:		dw	5000		; current bank
Bonus:		dw	0		; remaining bonus (<> 0 Bonus game)

Za návěští GameStart3: doplňte příkazy:


GameStart3:	call	DrawCredit	; draw credit
		call	DrawBet		; draw bet
		call	DrawWin		; draw win
		call	DrawBank	; draw bank
		dec	word [Credit]	; decrement credits

Připravte soubor DIGITS.ASM a naplňte jej následujícím obsahem:


; ============================================================================
;
;                            VEGASLOT - Digits
;
; ============================================================================

SECTION		.text

DIGITS		equ	12		; digits (0 to 9, 10=space, 11=H)
SPACE		equ	10		; index of SPACE digit
DOT		equ	11		; index of DOT digit
BANKDIG		equ	4		; digits of BANK
WINDIG		equ	3		; digits of WIN
BETDIG		equ	1		; digits of BET
CREDDIG		equ	4		; digits of CREDIT

; ----------------------------------------------------------------------------
;                        Init offsets of digits
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

InitDigOff:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX
		push	si		; push SI
		push	di		; push DI

; ------------- Init offsets of digits

		mov	cx,[DigitT]	; top coordinate of digits
		mov	bx,[DigitL]	; left coordinate of first digit
		mov	di,DigOff+4*SPACE; pointer to offsets of digit " "
		call	InitDig1	; init offset of " "
		mov	di,DigOff	; pointer to offsets of digits
		call	InitDig1	; init offset of "0"
		call	InitDig1	; init offset of "1"
		call	InitDig1	; init offset of "2"
		add	bx,[DigitW]	; left coordinate of "3"
		call	InitDig1	; init offset of "3"
		call	InitDig1	; init offset of "4"
		call	InitDig1	; init offset of "5"
		add	bx,[DigitW]	; left coordinate of "6"
		call	InitDig1	; init offset of "6"
		add	bx,[DigitW]	; left coordinate of "7"
		call	InitDig1	; init offset of "7"
		call	InitDig1	; init offset of "8"
		call	InitDig1	; init offset of "9"
		add	di,4		; pointer to offset of digit "H"
		call	InitDig1	; init offset of "H"

; ------------- Pop registers

		pop	di		; pop DI
		pop	si		; pop SI
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                        Init offsets of one digit
; ----------------------------------------------------------------------------
; INPUT:	BX = X coordinate of digit
;		CX = Y coordinate of digit
;		DI = pointer of offset of digit
;		DS = data segment
; OUTPUT:	BX = X coordinate of next digit
;		DI = pointer of offset of next digit
; DESTROY:	AX, SI
; ----------------------------------------------------------------------------

InitDig1:	call	CalcSrc		; calculate offset of digit
		mov	[di],si		; offset LOW of digit
		mov	[di+2],ax	; offset HIGH of digit
		add	di,4		; increase pointer of offset
		add	bx,[DigitW]	; X coordinate of next digit
		ret

; ----------------------------------------------------------------------------
;                                Draw credit
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

DrawCredit:	push	ax		; push AX
		push	bx		; push BX

; ------------- Draw number

		mov	ax,[Credit]	; AX <- value of credit
		cmp	ax,9999		; check maximal credit
		jbe	DrawCredit2	; credit is OK
		mov	ax,9999		; limit credit value
DrawCredit2:	mov	bx,40bh		; BH <- 4 digits, BL <- 11 position
		call	DrawNum		; draw number

; ------------- Pop registers

		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                                Draw bet
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

DrawBet:	push	ax		; push AX

; ------------- Draw number

		mov	al,[Bet]	; AX <- value of bet
		cmp	al,0		; is it valid game?
		jne	DrawBet1	; it is valid game
		mov	al,10		; space for no credit
		jmp	short DrawBet2	; display bet
DrawBet1:	cmp	al,6		; is it HIGH game?	
		jb	DrawBet2	; it is LOW game
		mov	al,11		; code for HIGH game
DrawBet2:	cmp	word [Bonus],0	; is it bonus game?
		je	DrawBet3	; it is normal game
		mov	al,0		; number for bonus game
DrawBet3:	call	DrawBetChar	; draw bet character

; ------------- Pop registers

		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                          Draw bet character
; ----------------------------------------------------------------------------
; INPUT:	AL = character to draw on Bet field
;		DS = data segment
; ----------------------------------------------------------------------------

DrawBetChar:	push	bx		; push BX
		mov	bx,109h		; BH <- 1 digit, BL <- 9 position
		call	DrawNum		; draw number
		pop	bx		; pop BX
		ret

; ----------------------------------------------------------------------------
;                                Draw win
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

DrawWin:	push	ax		; push AX
		push	bx		; push BX

; ------------- Draw number

		mov	ax,[Win]	; AX <- value of win
		mov	bx,305h		; BH <- 3 digits, BL <- 5 position
		call	DrawNum		; draw number

; ------------- Pop registers

		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                                Draw bank
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

DrawBank:	push	ax		; push AX
		push	bx		; push BX

; ------------- Draw number

		mov	ax,[Bank]	; AX <- value of bank
		cmp	ax,9999		; check maximal bank
		jbe	DrawBank2	; bank is OK
		mov	ax,9999		; limit bank value
DrawBank2:	mov	bx,400h		; BH <- 4 digits, BL <- 0 position
		call	DrawNum		; draw number

; ------------- Pop registers

		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                              Draw number
; ----------------------------------------------------------------------------
; INPUT:	AX = number (or character)
;		BL = position of first digit
;		BH = digits (1=print number as character)
;		DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

DrawNum:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX
		push	si		; push SI

; ------------- Number of digits -> CX

		mov	cl,bh		; CL <- digits
		mov	ch,0		; CX = digits

; ------------- Calculate X coordinate of last digit -> BX

		push	ax		; push AX
		mov	ax,[DigitW]	; width of one digit
		mov	bh,0		; BX = position of first digit
		add	bx,cx		; BX = position behing digits
		dec	bx		; BX <- position of last digit
		mul	bx		; AX <- offset of last digit
		add	ax,[DigitL]	; AX <- X coordinate of last digit
		xchg	ax,bx		; BX <- X coordinate of last digit
		pop	ax		; pop AX

; ------------- Immediate print character for bet

		cmp	cl,1		; is it bet?
		je	DrawNum4	; print bet character

; ------------- Decode number

		mov	si,10		; SI <- 10 divider
DrawNum2:	xor	dx,dx		; DX <- 0 (number HIGH)
		div	si		; DX <- calc last significant digit

; ------------- Substitute zero with space if there is no other digit

		or	dx,dx		; is it zero digit?
		jnz	DrawNum3	; it is not zero digit
		or	ax,ax		; remains any number?
		jnz	DrawNum3	; remains any number
		mov	dl,SPACE	; substitute with space

; ------------- Draw digit

DrawNum3:	xchg	ax,dx		; AL <- digit, DX <- number
DrawNum4:	call	DrawDigit	; draw one digit
		xchg	ax,dx		; AX <- number
		sub	bx,[DigitW]	; BX <- X coordinate of prev char
		loop	DrawNum2	; draw next digit

; ------------- Pop registers

		pop	si		; pop SI
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                          Draw one digit character
; ----------------------------------------------------------------------------
; INPUT:	AL = digit (0 to 9, 10=space, 11=dot)
;		BX = X coordinate
;		DS = data segment
; ----------------------------------------------------------------------------

; ------------- Push registers

DrawDigit:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX
		push	si		; push SI
		push	di		; push DI

; ------------- Prepare destination offset (-> DX:DI)

		mov	cx,[DigitT]	; top coordinate of digits
		call	CalcDest	; calculate destination offset

; ------------- Prepare source offset (-> AX:SI)

		mov	ah,0		; AX = digit
		shl	ax,1		; digit * 2
		shl	ax,1		; digit * 4
		xchg	ax,si		; SI <- digit * 4
		mov	ax,[DigOff+si+2]; offset of digit HIGH
		mov	si,[DigOff+si]	; offset of digit LOW

; ------------- Draw digit

		mov	bx,[DigitW]	; length of line
		mov	cx,[DigitH]	; height of one digit
DrawDigit2:	call	DrawLine	; draw line of digit
		loop	DrawDigit2	; draw next line of digit

; ------------- Pop registers

		pop	di		; pop DI
		pop	si		; pop SI
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                                    Data
; ----------------------------------------------------------------------------

; ------------- Digits

DigitW:		dw	0		; width of one digit
DigitH:		dw	0		; height of one digit
DigitL:		dw	0		; left coordinate of first digit
DigitT:		dw	0		; top coordinate od digits
BankL:		dw	0		; left coordinate of BANK
WinL:		dw	0		; left coordinate of WIN
BetL:		dw	0		; left coordinate of BET
CredL:		dw	0		; left coordinate of CREDIT

; ----------------------------------------------------------------------------
;          Uninitialized data (60 KB area in place of VGA graphics)
; ----------------------------------------------------------------------------

SECTION		.bss

; ------------- Offsets of digits (0 to 9, 10=space, 11=H)

DigOff:		resd	DIGITS		; offset of digits

Během inicializace programu je z funkce InitGraph volána funkce InitDigOff, která připraví zdrojové offsety jednotlivých číslic a uloží je do tabulky DigOff. Znaky s indexem 0 až 9 představují číslice 0 až 9, znak s indexem 10 je mezera a znak 11 je písmeno H, které se používá k indikaci "Horní hry". Při výpočtu se využívá zjednodušení, že jednotlivé části displeje jsou od sebe vzdáleny právě na šířku 1 znaku.

Ústřední funkcí pro vykreslení jednoho znaku na digitální displej je funkce DrawDigit. Jejími vstupními parametry jsou index znaku k vykreslení a jeho horizontální pozice, vertikální souřadnice je u všech částí displeje stejná. Nejdříve funkce vypočte cílový offset k uložení znaku a z tabulky DigOff si načte zdrojový offset pro příslušný znak. Poté znak vykresluje po jednotlivých linkách pomocí funkce DrawLine.

Funkce DrawNum vypíše číslo na jeden úsek displeje. Vstupními parametry jsou: číslo k zobrazení, pozice prvního znaku (poměrně k začátku celého displeje) a počet pozic displeje. Číslo 0 se nezobrazí, namísto něj bude displej prázdný. Speciálním případem je displej o 1 pozici. Jedná se o displej k zobrazení sázky, tento displej není zobrazen jako číslo, namísto čísla se zobrazí znak odpovídající vstupnímu číslu, tím je možné na pozici sázky zobrazit i znaky "0" a "H".

Funkce na začátku vypočte z pozice prvního znaku a z šířky displeje souřadnici X posledního znaku displeje. Pro šířku displeje 1 udělá "odbočku" a vykreslí pouze 1 znak z registru čísla. Jinak pokračuje cyklem přes všechny pozice displeje. Vydělí zobrazované číslo číslem 10 a zbytek po dělení zobrazí jako číslici. Pokud se jednalo o nevýznamnou nulu, nahradí ji před zobrazením znakem mezery. Posune ukazatel souřadnice X na předešlý znak a pokračuje dekódováním další číslice.

Funkce DrawBank zobrazí obsah proměnné Bank. Zobrazenou hodnotu omezí na 9999. Funkce DrawWin zobrazí obsah proměnné Win. DrawBetChar zobrazí znak na displeji sázky. Tato funkce je z programu volána jednak samostatně během losování a jednak z funkce DrawBet, která zobrazí aktuální stav sázky s korekcí pro bonusovou hru (zobrazí "0") a horní hru (zobrazí "H"). DrawCredit zobrazí obsah proměnné Credit, zobrazenou hodnotu omezí na 9999.

Program přeložte a vyzkoušejte. Na displejích by se mělo zobrazit: "5000 750 1 100", po každém otočení válců (po stisku mezerníku) se stav kreditů sníží o 1.

Download zdrojového kódu obsluhy čísel

Zpět na aplikaci VEGASLOT