;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Project : FDOS 0.0.9
;; Author : Stefan Tappertzhofen (tappertzhofen@t-online.de)
;; Webpage : http://www.visual-opal.de
;; Date : 1.5.2004
;; Info : Ping Pong Game Example
;; Filename : pingpong.asm
;; Compile Syntax : nasm pingpong.asm -f bin -o pingpong.bin
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
JMP NEAR Init
HeadSignature DB 'BI,'
SysFileName DB 'PingPong,'
FDVerRequ DB '0.0.9.4,'
SysVersion DB '0.0.0.5,'
Copyright DB 'Stefan Tappertzhofen (c) 2002 - 2004,',
Information DB 'Pingpong example game for two players,'
Product DB 'FDOS,'
Init:
MOV AX, CS ; Load Segment Registers
MOV DS, AX
MOV ES, AX
Begin:
; Welcome
MOV AH, 4 ; CLS
INT 21h
MOV SI, MSG_Welcome
MOV AH, 1
INT 21h
XOR AH, AH
INT 16h
CMP AL, '0'
JE SHORT End_Program
CMP AL, '1'
JE SHORT StartGame1
CMP AL, '2'
JE SHORT StartGame2
CMP AL, '3'
JE SHORT StartGame3
JMP SHORT Begin
End_Program:
MOV AH, 4 ; CLS
INT 21h
MOV AH, 0
INT 21h
StartGame1:
MOV AX, 1
MOV [Speed], AX
JMP SHORT StartGame
StartGame2:
MOV AX, 2
MOV [Speed], AX
JMP SHORT StartGame
StartGame3:
MOV AX, 3
MOV [Speed], AX
JMP SHORT StartGame
StartGame
MOV AH, 1
MOV CX, 10280 ; Disable Coursor
INT 10h
; Init Player 1 Position
MOV BYTE [PosPlayer1], 9
MOV BYTE [LastPlayer1], 9
; Init Player 2 Position
MOV BYTE [PosPlayer2], 9
MOV BYTE [LastPlayer2], 9
; Init Ball Position
MOV BYTE [XPos], 39
MOV BYTE [LastX], 39
MOV BYTE [YPos], 12
MOV BYTE [LastY], 12
; Init Direction of Ball
MOV BYTE [DirectionX], 1
MOV BYTE [DirectionY], 1
MOV AH, 4 ; CLS
INT 21h
; Print Game Screen
CALL PrintPlayer1
CALL PrintPlayer2
CALL PrintBall
DoGame:
PUSH CX
.IfX:
MOV AL, [XPos]
CMP AL, 4
JB NEAR .CheckPlayer1
CMP AL, 75
JA NEAR .CheckPlayer2
.IfY:
MOV AL, [YPos]
CMP AL, 2
JB NEAR .PosYDirection
CMP AL, 21
JA NEAR .NegYDirection
.PrintTheBall:
; Check If any Player pressed a key:
mov ah, 01h
int 16h
jz .DoPrint
xor ah, ah
int 16h
CMP AL, 'w'
JE .SubPlayer1
CMP AL, 's'
JE .AddPlayer1
CMP AL, 'o'
JE .SubPlayer2
CMP AL, 'l'
JE .AddPlayer2
JMP .DoPrint
.AddPlayer1:
MOV AL, [PosPlayer1]
CMP AL, 17
JE SHORT .DoPrint
ADD AL, 1
MOV [PosPlayer1], AL
JMP SHORT .DoPrint
.SubPlayer1:
MOV AL, [PosPlayer1]
CMP AL, 0
JE SHORT .DoPrint
SUB AL, 1
MOV [PosPlayer1], AL
JMP SHORT .DoPrint
.AddPlayer2:
MOV AL, [PosPlayer2]
CMP AL, 17
JE SHORT .DoPrint
ADD AL, 1
MOV [PosPlayer2], AL
JMP SHORT .DoPrint
.SubPlayer2:
MOV AL, [PosPlayer2]
CMP AL, 0
JE SHORT .DoPrint
SUB AL, 1
MOV [PosPlayer2], AL
JMP SHORT .DoPrint
.DoPrint:
MOV AX, [XPos]
ADD AX, [DirectionX]
MOV [XPos], AX
MOV AX, [YPos]
ADD AX, [DirectionY]
MOV [YPos], AX
CALL PrintScreen ; Print Game Screen
CALL PrintPlayer1
CALL PrintPlayer2
CALL PrintBall
CALL WaitTime
JMP ResumeGame
.PosXDirection:
MOV BYTE [DirectionX], 1
JMP NEAR .IfY
.NegXDirection:
MOV BYTE [DirectionX], -1
JMP NEAR .IfY
.PosYDirection:
MOV BYTE [DirectionY], 1
JMP NEAR .PrintTheBall
.NegYDirection:
MOV BYTE [DirectionY], -1
JMP NEAR .PrintTheBall
.CheckPlayer1:
MOV AL, [YPos]
MOV BL, [PosPlayer1]
CMP AL, BL
JE .PosXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer1]
ADD BL, 1
CMP AL, BL
JE .PosXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer1]
ADD BL, 2
CMP AL, BL
JE .PosXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer1]
ADD BL, 3
CMP AL, BL
JE .PosXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer1]
ADD BL, 4
CMP AL, BL
JE .PosXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer1]
ADD BL, 5
CMP AL, BL
JE .PosXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer1]
ADD BL, 5
CMP AL, BL
JE .PosXDirection
JMP .Player1Lost
.CheckPlayer2:
MOV AL, [YPos]
MOV BL, [PosPlayer2]
CMP AL, BL
JE .NegXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer2]
ADD BL, 1
CMP AL, BL
JE .NegXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer2]
ADD BL, 2
CMP AL, BL
JE .NegXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer2]
ADD BL, 3
CMP AL, BL
JE .NegXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer2]
ADD BL, 4
CMP AL, BL
JE .NegXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer2]
ADD BL, 5
CMP AL, BL
JE .NegXDirection
MOV AL, [YPos]
MOV BL, [PosPlayer2]
ADD BL, 6
CMP AL, BL
JE .NegXDirection
JMP .Player2Lost
.Player1Lost:
MOV AH, 4 ; CLS
INT 21h
MOV CX, 3085
MOV CX, 1543
MOV AH, 1
INT 10h
MOV SI, MSG_Player1_Lost
MOV AH, 1
INT 21h
MOV SI, MSG_PressAKey
MOV AH, 1
INT 21h
XOR AX, AX
INT 16h
MOV AH, 0
INT 21h
.Player2Lost:
MOV AH, 4 ; CLS
INT 21h
MOV CX, 3085
MOV CX, 1543
MOV AH, 1
INT 10h
MOV SI, MSG_Player2_Lost
MOV AH, 1
INT 21h
MOV SI, MSG_PressAKey
MOV AH, 1
INT 21h
XOR AX, AX
INT 16h
MOV AH, 0
INT 21h
ResumeGame:
POP CX
JMP DoGame
WaitTime:
XOR AH, AH
INT 1Ah
MOV BX, DX
.GetNewTime:
PUSH BX
XOR AH, AH
INT 1Ah
POP BX
SUB DX, BX
MOV AX, [Speed]
CMP DX, AX
JB SHORT .GetNewTime
JMP ResumeGame
PrintScreen:
MOV DL, [XPos]
MOV DH, [YPos]
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
SUB DL, 1
SUB DH, 1
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
SUB DL, 1
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
SUB DH, 1
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
ADD DH, 1
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
ADD DL, 1
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
ADD DL, 1
ADD DH, 1
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
ADD DL, 1
SUB DH, 1
CALL LocateXY
CALL PrintDummy
MOV DL, [XPos]
MOV DH, [YPos]
SUB DL, 1
ADD DH, 1
CALL LocateXY
CALL PrintDummy
RETN
PrintPlayer1:
; Clear Last Position of Player
MOV DH, [LastPlayer1]
MOV DL, 3
CALL LocateXY
MOV CX, 6
.ClearOldPos:
CALL PrintSpace
CALL PrintSpace
INC DH
MOV DL, 3
CALL LocateXY
LOOPNZ .ClearOldPos
; Print Player
MOV DH, [PosPlayer1]
MOV DL, 3
CALL LocateXY
MOV CX, 6
.PrintPos:
CALL PrintBlock
CALL PrintBlock
INC DH
MOV DL, 3
CALL LocateXY
LOOPNZ .PrintPos
MOV AL, [PosPlayer1]
MOV [LastPlayer1], AL
RETN
PrintPlayer2:
; Clear Last Position of Player
MOV DH, [LastPlayer2]
MOV DL, 76
CALL LocateXY
MOV CX, 6
.ClearOldPos:
CALL PrintSpace
CALL PrintSpace
INC DH
MOV DL, 76
CALL LocateXY
LOOPNZ .ClearOldPos
; Print Player
MOV DH, [PosPlayer2]
MOV DL, 76
CALL LocateXY
MOV CX, 6
.PrintPos:
CALL PrintBlock
CALL PrintBlock
INC DH
MOV DL, 76
CALL LocateXY
LOOPNZ .PrintPos
MOV AL, [PosPlayer2]
MOV [LastPlayer2], AL
RETN
PrintBall:
; Clear Last Position of Ball
MOV AL, [XPos]
MOV [LastX], AL
MOV AL, [YPos]
MOV [LastY], AL
; Print New Ball
MOV DL, [XPos]
MOV DH, [YPos]
CALL LocateXY
CALL PrintB
RETN
PrintSpace:
MOV AH, 11
MOV AL, ' '
INT 21h
RETN
PrintDummy:
MOV AH, 11
MOV AL, ' '
INT 21h
RETN
PrintBlock:
MOV AH, 11
MOV AL, '²'
INT 21h
RETN
PrintB:
MOV AH, 11
MOV AL, 'Û'
INT 21h
RETN
LocateXY:
; DL = X
; DH = Y
PUSH AX
PUSH BX
MOV AH, 02h
MOV BH, 0
INT 10h
POP BX
POP AX
RETN
PosPlayer1 DB 0
LastPlayer1 DB 0
PosPlayer2 DB 0
LastPlayer2 DB 0
XPos DB 0
LastX DB 0
YPos DB 0
LastY DB 0
DirectionX DB 0 ; -1 and +1
DirectionY DB 0 ; -1 and +1
Speed DB 0
Free TIMES 10 DB 0
MSG_Welcome DB 'FDOS Ping Pong (v 0.1)',13,10,
DB '----------------------',13,10,10,13,
DB 'Copyright Stefan Tappertzhofen 2002 - 2003',13,10,13,
DB 'This game is made for two player. The aim of the game is to bounce the ball',13,10,
DB 'so that it can not reach the screen boarder.',13,10,
DB 'Player 1 controlls his block with the Key >W< to move it upwards and >S< to',13,10,
DB 'move it downwards. Player 2 controlls his key with >O< for upwards and >L<',13,10,
DB 'downwards.',13,10,
DB 'The game will be terminated when a Player lost.',13,10,13,10,
DB 'Choose your game speed. After pressing the option the game will be started.',13,10,
DB ' 0 - terminate the game',13,10,
DB ' 1 - fast',13,10,
DB ' 2 - middle',13,10,
DB ' 3 - slow',13,10,
DB 'Your Option: ',0
MSG_Player1_Lost DB 'Player 1 lost the game!',13,10,0
MSG_Player2_Lost DB 'Player 2 lost the game!',13,10,13,10,0
MSG_PressAKey DB 'Press a key to exit for FDOS!',13,10,0
Dummy TIMES 10 DB 0