Remy Vincent
Joined: 16 Sep 2005
Posts: 155
Location: France
|
Somewhere in this forum, a small tennis game have been posted
some monthes ago, but it was hard to adapt it to CGA or EGA or SVGA
so I have done a very fast tennis game, and FULLY commented...
HOW could I translate it to CGA 640x200 graphic mode ?
ORG 100h
USE16
START:
;----- Graphic mode 13h ( VGA 320x200 256 colors )
MOV AX , 0013h ; INT 10h , Function 00h : Change screen mode
INT 10h
;--------------- Init background temp data ---------------
;----- Adjust segments pointers
PUSH CS
POP ES
MOV DI , G_BkTopLine
;----- LOOP , Prepare background top line
XOR CH , CH
MOV CL , 160 ; 160 = 320 Div 2
MOV AX , 0F0Fh
REP STOSW
MOV DI , G_BkBlankLine
;----- LOOP , Prepare background blank line
XOR CH , CH
MOV CL , 160 ; 160 = 320 Div 2
MOV AX , 0000h
REP STOSW
;--------------- / ---------------
;----- LOOP , MAIN MOVING & DRAWING
MAIN_LOOP:
;----- Adjust segments pointers
PUSH CS
POP DS
PUSH WORD 0A000h
POP ES
;--------------- Draw paddle 1 ---------------
XOR DH , DH ; Convert byte to word
MOV DL , [G_Paddle1_Y]
; 2 = 0 + 1 + 1
MOV DI , 322 ; 322 = '2' + 320
;----- LOOP , Draw above paddle 1
XOR CH , CH
MOV CL , DL
DEC CL ; 1 = 1
JCXZ Paddle1_Above_END
Paddle1_Above_LOOP:
MOV [ES:DI] , DWORD 000F0000h
ADD DI , 320
LOOP Paddle1_Above_LOOP
Paddle1_Above_END:
;----- Calculate paddle 1 first address
;--MOV DI , DX --
;--IMUL DI , 320-- ; G_Paddle1_Y * 320 + G_Paddle1_X
;--ADD DI , 2 -- ; 2 = 0 + 1 + 1
;----- LOOP , Draw paddle 1
XOR CH , CH
MOV CL , 16
Paddle1_Draw_LOOP:
MOV [ES:DI] , DWORD 0F0F0F0Fh
ADD DI , 320
LOOP Paddle1_Draw_LOOP
;----- LOOP , Draw below paddle 1
XOR CH , CH
MOV CL , 198
MOV AL , DL
DEC AL ; 1 = 1
SUB CL , AL
SUB CL , 16
JCXZ Paddle1_Below_END
Paddle1_Below_LOOP:
MOV [ES:DI] , DWORD 00000000h
ADD DI , 320
LOOP Paddle1_Below_LOOP
Paddle1_Below_END:
;--------------- Draw paddle 2 ---------------
XOR DH , DH ; Convert byte to word
MOV DL , [G_Paddle2_Y]
; 314 = 319 - 1 - 1 - 4 +1
MOV DI , 634 ; 634 = '314' + 320
;----- LOOP , Draw above paddle 2
XOR CH , CH
MOV CL , DL
DEC CL ; 1 = 1
JCXZ Paddle2_Above_END
Paddle2_Above_LOOP:
MOV [ES:DI] , DWORD 00000F00h
ADD DI , 320
LOOP Paddle2_Above_LOOP
Paddle2_Above_END:
;----- Calculate paddle 2 first address
;--MOV DI , DX --
;--IMUL DI , 320-- ; G_Paddle2_Y * 320 + G_Paddle2_X
;--ADD DI , 314-- ; 314 = 319 - 1 - 1 - 4 +1
;----- LOOP , Draw paddle 2
MOV CX , 16
Paddle2_Draw_LOOP:
MOV [ES:DI] , DWORD 0F0F0F0Fh
ADD DI , 320
LOOP Paddle2_Draw_LOOP
;----- LOOP , Draw below paddle 2
XOR CH , CH
MOV CL , 198
MOV AL , DL
DEC AL ; 1 = 1
SUB CL , AL
SUB CL , 16
JCXZ Paddle2_Below_END
Paddle2_Below_LOOP:
MOV [ES:DI] , DWORD 00000000h
ADD DI , 320
LOOP Paddle2_Below_LOOP
Paddle2_Below_END:
;--------------- Draw background ( At 0A000h ) ---------------
;--XOR DI , DI --
;----- LOOP , Clear the background
;--MOV CX , 32000-- ; 32000 = 320X * 200Y * 8BitColor / 8Bit / 2Byte
;--MOV AX , 0000h--
;--REP STOSW --
;--MOV CX , 64000-- ; 64000 = 320X * 200Y * 8BitColor / 8Bit
;--MOV AL , 00h --
;--REP STOSB --
XOR DI , DI
MOV SI , G_BkTopLine
;----- LOOP , Draw horizontal top line
XOR CH , CH
MOV CL , 80
REP MOVSD
;--XOR CH , CH --
;--MOV CL , 160 --
;--MOV AX , 0F0Fh--
;--REP STOSW --
;--MOV CX , 320--
;--MOV AL , 0Fh--
;--REP STOSB --
; 159 = 0 + (320 Div 2) -1
MOV DI , 479 ; 479 = '159' + 320
;----- LOOP , Draw vertical middle line
XOR CH , CH
MOV CL , 198
MOV AL , 0Fh
Vertical_Middle_Line_LOOP:
STOSB
ADD DI , 319
LOOP Vertical_Middle_Line_LOOP
MOV DI , 320
;----- LOOP , Draw vertical left & right line
XOR CH , CH
MOV CL , 198
MOV AL , 0Fh
Vertical_LR_Line_LOOP:
STOSB
ADD DI , 318
STOSB
LOOP Vertical_LR_Line_LOOP
MOV SI , G_BkBottomLine
;----- LOOP , Draw horizontal bottom line
XOR CH , CH
MOV CL , 80
REP MOVSD
;--XOR CH , CH --
;--MOV CL , 160 --
;--MOV AX , 0F0Fh--
;--REP STOSW --
;--MOV CX , 320--
;--MOV AL , 0Fh--
;--REP STOSB --
MOV DI , 321 ; 321 = 0 + 1 + 320
;----- LOOP , Clear the background
XOR CH , CH
MOV CL , 198
Background_Blank_Line_LOOP:
PUSH CX
MOV SI , G_BkBlankLine
;----- Clear very left part
MOVSB
ADD DI , 4 ; 4 = 4
;----- LOOP .1 , Clear left part
XOR CH , CH
MOV CL , 38 ; 38 = (160 - 1 - 1 - 4 - 1) Div 4
REP MOVSD
MOVSB ; 1 = (160 - 1 - 1 - 4 - 1) - ('38' * 4)
INC DI ; 1 = 1
;----- LOOP .2 , Clear right part
XOR CH , CH
MOV CL , 38 ; 38 = (160 - 4 - 1 - 1) Div 4
REP MOVSD
MOVSW ; 2 = (160 - 4 - 1 - 1) - (38 * 4)
ADD DI , 4 ; 4 = 4
;----- Clear very right part
MOVSB
ADD DI , 2 ; 2 = 1 + 1
POP CX
LOOP Background_Blank_Line_LOOP
;--------------- Draw ball ( At 0A000h ) ---------------
XOR DH , DH ; Convert byte to word
MOV DL , [G_Ball_Y]
;----- Calculate ball first address
MOV DI , DX
IMUL DI , 320 ; G_Ball_Y * 320 + G_Ball_X
ADD DI , BX
;----- LOOP , Draw ball 4x4 pixels ( = 4 bytes * 4 )
MOV CL , 4
Ball_Draw_LOOP:
MOV [ES:DI] , DWORD 0F0F0F0Fh
ADD DI , 320
LOOP Ball_Draw_LOOP
;--------------- Move ball Y ---------------
;--MOV DL , [G_Ball_Y]--
MOV AL , [G_Ball_dy]
;----- Update ball Y direction "G_Ball_dy"
CMP AL , 0
JG Ball_Y_GoingDown
JE Ball_Y_STEP02_END
Ball_Y_GoingUp:
CMP DL , 1 ; 1 = 0 + 1
JA Ball_Y_STEP01_END
NEG AL
JMP Ball_Y_Store_dy
Ball_Y_GoingDown:
CMP DL , 195 ; 195 = 199 - 1 - 4 +1
JB Ball_Y_STEP01_END
NEG AL
Ball_Y_Store_dy:
MOV [G_Ball_dy] , AL ;--- Store ball new Y direction "G_Ball_dy"
Ball_Y_STEP01_END:
;----- Update ball Y location "G_Ball_Y"
Ball_Y_STEP02:
CMP AL , 0
JG Ball_Y_Inc
JE Ball_Y_STEP02_END
Ball_Y_Dec:
DEC DL
JMP Ball_Y_Store
Ball_Y_Inc:
INC DL
Ball_Y_Store:
MOV [G_Ball_Y] , DL ;--- Store ball new Y location "G_Ball_Y"
Ball_Y_STEP02_END:
;--------------- Move ball X ---------------
MOV BX , [G_Ball_X]
MOV AL , [G_Ball_dx]
;----- Update ball X direction "G_Ball_dx"
CMP AL , 0
JG Ball_X_GoingRight
JE Ball_X_STEP02_END
Ball_X_GoingLeft:
CMP BX , 6 ; 6 = 0 + 1 + 1 + 4
JA Ball_X_STEP01_END
NEG AL
JMP Ball_X_Store_dx
Ball_X_GoingRight:
CMP BX , 310 ; 310 = 319 - 1 - 1 - 4 - 4 +1
JB Ball_X_STEP01_END
NEG AL
Ball_X_Store_dx:
MOV [G_Ball_dx] , AL ;--- Store ball new X direction "G_Ball_dx"
Ball_X_STEP01_END:
;----- Update ball X location "G_Ball_X"
Ball_X_STEP02:
CMP AL , 0
JG Ball_X_Inc
JE Ball_X_STEP02_END
Ball_X_Dec:
DEC BX
JMP Ball_X_Store
Ball_X_Inc:
INC BX
Ball_X_Store:
MOV [G_Ball_X] , BX ;--- Store ball new X location "G_Ball_X"
Ball_X_STEP02_END:
;--------------- Move paddles ---------------
;----- Paddle 1 need auto move ?
CMP BYTE [G_Ball_dx] , 0 ; Check ball X direction
JG Paddle1_Move_END
;----- Auto move paddle 1
MOV AL , [G_Paddle1_Y]
CALL Paddle_AutoMovedQ
JNC Paddle1_Move_Unchanged
MOV [G_Paddle1_Y] , AL
Paddle1_Move_Unchanged:
Paddle1_Move_END:
;----- Paddle 2 need auto move ?
CMP BYTE [G_Ball_dx] , 0 ; Check ball X direction
JL Paddle2_Move_END
;----- Auto move paddle 2
MOV AL , [G_Paddle2_Y]
CALL Paddle_AutoMovedQ
JNC Paddle2_Move_Unchanged
MOV [G_Paddle2_Y] , AL
Paddle2_Move_Unchanged:
Paddle2_Move_END:
;--------------- Check keys ---------------
;----- If no key pressed, loop again
MOV AH , 11h ; INT 16h , Function 11h : Keystroke status
INT 16h
JZ MAIN_LOOP
;--------------- / ---------------
;----- Text mode 03h ( CGA 80x25 16 colors )
MOV AX , 0003h ; INT 10h , Function 00h : Change screen mode
INT 10h
INT 20h
;=============== Data
;----- Ball parameters
G_Ball_X DW 160
G_Ball_Y DB 100
G_Ball_dx DB -1
G_Ball_dy DB -1
;----- Left & right paddle parameters
G_Paddle1_Y DB 108
G_Paddle2_Y DB 92
;
;------------------------------------------------------------------------------
; This program routines
;------------------------------------------------------------------------------
;
;
;---------------
; Paddle routines
;---------------
; Paddle_AutoMovedQ
;---------------
;
;===== Paddle_AutoMovedQ
Paddle_AutoMovedQ:
;AL(I_Paddle_Y) , DL(I_Ball_Y) ==> AL(O_Paddle_Y_AutoMoved) , cf(O_Paddle_Y_ChangedQ)
CMP DL , AL
JB Paddle_NeedGoingUp
JA Paddle_MayNeedGoingDown
JMP Paddle_AutoMovedQ_NO
Paddle_NeedGoingUp:
DEC AL
JMP Paddle_AutoMovedQ_Store_Y
Paddle_MayNeedGoingDown:
SUB DL , 12 ; Paddle height is 16, ball height is 4
CMP DL , AL
JBE Paddle_AutoMovedQ_NO
INC AL
Paddle_AutoMovedQ_Store_Y:
STC ; Need to be stored by caller
JMP Paddle_AutoMovedQ_EXIT
Paddle_AutoMovedQ_NO:
CLC
Paddle_AutoMovedQ_EXIT:
RET
;=============== Temp data
;----- Background temp data
G_BkTopLine RB 0 ; Size is 0, so using next bytes ( Bottom line bytes )
G_BkBottomLine RB 320
G_BkBlankLine RB 320
|