TITLE GAME5: PADDLE_BALL
;This is the main program that prompts the user for information, such as
;what court they want to use, the level etc. It then calls rounds which starts
;the game.
;input: information obtained through procedure questions
;output: displays a game for 15 sets
EXTRN SET_DISPLAY_MODE:NEAR, DISPLAY_BALL:NEAR 
EXTRN MOVE_BALL_A:NEAR, DRAW_PADDLE:NEAR, DRAW_PADDLE_RIGHT:NEAR
EXTRN MOVE_PADDLE:NEAR, MOVE_PADDLE_RIGHT:NEAR
EXTRN KEYBOARD_INT:NEAR, TIMER_TICK:NEAR, QUESTIONS:NEAR
EXTRN SETUP_INT:NEAR, KEEP_SCORE:NEAR, KEEP_SCORE_2:NEAR, DISPLAY_COUNTRY:NEAR

PUBLIC TIMER_FLAG, KEY_FLAG, SCAN_CODE, POINTS, POINTS2, WHICH_COUNTRY
PUBLIC PADDLE_TOP, PADDLE_BOTTOM, VEL_X, VEL_Y, PADDLE_TOP_RIGHT, PADDLE_BOTTOM_RIGHT
PUBLIC VEL_X2, COURT_TYPE, WHICH_COUNTRY2, HOW_MANY_SET

.MODEL SMALL
.STACK 100H
.DATA

NEW_TIMER_VEC   DW      ?,?
OLD_TIMER_VEC   DW      ?,?
NEW_KEY_VEC     DW      ?,?
OLD_KEY_VEC     DW      ?,?
SCAN_CODE       DB      0
KEY_FLAG        DB      0
TIMER_FLAG      DB      0
PADDLE_TOP      DW      27
PADDLE_BOTTOM   DW      45
PADDLE_TOP_RIGHT        DW      27
PADDLE_BOTTOM_RIGHT     DW      45
POINTS          DW      0
POINTS2         DW      0
VEL_X           DW      ?
VEL_X2          DW      ?
VEL_Y           DW      1
WHICH_COUNTRY   DB      ?
WHICH_COUNTRY2  DB      ?
COURT_TYPE      DB      ?
HOW_MANY_SET    DB      ?
UP_ARROW = 72
DOWN_ARROW = 80
ESC_KEY = 1
TAB = 15
SHIFT = 42

.CODE
MAIN PROC
        MOV AX,@DATA
        MOV DS,AX                     ;intialize ds
        CALL QUESTIONS                ;call that prompts user for information
        MOV NEW_TIMER_VEC,OFFSET TIMER_TICK     ;offset
        MOV NEW_TIMER_VEC+2,CS                  ;segment
        MOV AL,1CH                              ;interrupt number
        LEA DI,OLD_TIMER_VEC                    ;set di equal to old_timer_vec 
        LEA SI,NEW_TIMER_VEC                    ;set si equal to new_timer_vec
        CALL SETUP_INT      ;call that saves old vector and sets up new vector
        MOV NEW_KEY_VEC,OFFSET KEYBOARD_INT     ;offest
        MOV NEW_KEY_VEC+2,CS                    ;segment
        MOV AL,9H                               ;interrupt number
        LEA DI,OLD_KEY_VEC                      ;set di equal to old_key_vec
        LEA SI,NEW_KEY_VEC                      ;set si equal to new_key_vec
        CALL SETUP_INT      ;call that saves old vector and sets up new vector
        MOV DX, 15          ;move 15 into dx, sets game for 15 points
       
NO_LOOP:
        PUSH DX             ;save number of sets
        CALL ROUNDS         ;calls the set
        POP DX              ;restores the number of sets
        SUB DX, 1           ;subtracts the set just completed
        PUSH BX             ;saves bx
        MOV BX, VEL_X2      
        MOV VEL_X, BX       ;restores x_vel which may have been altered in set
        POP BX              ;restores bx
        CMP DX, 0           ;compare number of sets left with zero
        JG NO_LOOP          ;if already completed 15 sets stop, else repeat
     
DONE:                       ;restores computer to orginal mode before game
        ;-reset timer interrupt vector
        LEA DI,NEW_TIMER_VEC   ;sets di equal to new_timer_vector
        LEA SI,OLD_TIMER_VEC   ;sets si equal to old_timer_vector
        MOV AL,1CH             ;intertupt number
        CALL SETUP_INT         ;call that saves old vector and sets up new vector

        ;-reset keyboard interrupt vector
        LEA DI,NEW_KEY_VEC     ;sets di equal to new_key_vec
        LEA SI,OLD_KEY_VEC     ;sets si equal to old_key_vec
        MOV AL,9H              ;interrupt number
        CALL SETUP_INT         ;call that saves old vector and sets up new vector

        ;-read key                                 
        MOV AH,0                ;read key function
        INT 16H                 ;read key

        ;-reset to text mode
        MOV AH,0                ;wait for input
	MOV AL,3
	INT 10H

        ;-return to dos
	MOV AH,4CH
	INT 21H

MAIN ENDP


ROUNDS PROC
        CALL SET_DISPLAY_MODE           
        MOV AL,5                        ;color of hand
        CALL DRAW_PADDLE
        MOV AL,5
        CALL DRAW_PADDLE_RIGHT
        MOV CX,294                      ;starting ball location
	MOV DX,100
        MOV AL,3                        ;color of ball
	CALL DISPLAY_BALL
        MOV BL, 3                       ;score color
        CALL KEEP_SCORE
        CALL KEEP_SCORE_2
        CALL DISPLAY_COUNTRY
TEST_KEY:                                ;check to see if timer flag 1
	CMP KEY_FLAG,1
        JNE TEST_TIMER                   ;if not keep checking
        MOV KEY_FLAG,0                   ;flag set, clear and check
        CMP SCAN_CODE,ESC_KEY            ;esc key
        JNE TK_1                         ;check other keys
        JMP DONE                         ;if esc jump out

TK_1:   CMP SCAN_CODE,TAB                ;tab, left upwards
        JNE TK_2                         ;check other keys
        MOV AX,-4                        
        CALL MOVE_PADDLE                 ;move hand 4 keys upward
        JMP TEST_TIMER                   ;go check timer flag
TK_2:   CMP SCAN_CODE,SHIFT              ;shift, left downwards
        JNE TEST_KEY_RIGHT               ;similar as tab key
        MOV AX,4
	CALL MOVE_PADDLE
	JMP TEST_TIMER
TEST_KEY_RIGHT:
        CMP SCAN_CODE,UP_ARROW            ;up arrow, right upward
        JNE TK_3                          ;similar as above
        MOV AX,-4
	CALL MOVE_PADDLE_RIGHT
	JMP TEST_TIMER
TK_3:   CMP SCAN_CODE,DOWN_ARROW          ;down arrow key, right downward
        JNE TEST_TIMER                    ;similar as above
        MOV AX,4
	CALL MOVE_PADDLE_RIGHT


TEST_TIMER:
        CMP TIMER_FLAG,1                   ;flag set?
        JNE TEST_KEY                       ;no check key flag
        MOV TIMER_FLAG,0                   ;yes clear 
        CALL MOVE_BALL_A                   ;move ball to new position
        MOV BL, 3                          ;update score
        CALL KEEP_SCORE
        CALL KEEP_SCORE_2
        CALL DISPLAY_COUNTRY               ;display country
        CMP CX,12
        JNE CHECK_RIGHT                    ;check left hand, does ball hit
        CMP DX,PADDLE_TOP                  ;hand or wall?
        JL FIRST_DONE_RIGHT
	CMP DX,PADDLE_BOTTOM
        JG FIRST_DONE_RIGHT
	JMP DELAY
CHECK_RIGHT:
        CMP CX,294                         ;check right hand, does ball hit
        JNE OUT_OF_RANGE                   ;hand or wall?
	CMP DX,PADDLE_TOP_RIGHT
	JL FIRST_DONE
	CMP DX,PADDLE_BOTTOM_RIGHT
        JG FIRST_DONE
	JMP DELAY

OUT_OF_RANGE:
        JMP TEST_KEY                        ;continue playing

DELAY:  
        CMP TIMER_FLAG,1                   ;check if timer ticked
	JNE DELAY
        MOV TIMER_FLAG,0                   ;reset timer flag
        CALL MOVE_BALL_A                   ;move the ball to new position.
        MOV BL, 3                          ;score color.
        CALL KEEP_SCORE                    ;update score1.
        CALL KEEP_SCORE_2                  ;update score2 (player2
        CALL DISPLAY_COUNTRY               ;display country
        MOV AL,5                           ;color of hand
        CALL DRAW_PADDLE                   ;left hand.
        MOV AL,5
        CALL DRAW_PADDLE_RIGHT             ;right hand.
        JMP TEST_KEY


FIRST_DONE:                                ;if player one won, then points
        INC POINTS                         ;are increase...else
        CALL KEEP_SCORE
        RET

FIRST_DONE_RIGHT:
        INC POINTS2                        ;increase points for player 2.
        CALL KEEP_SCORE_2
        RET

ENDP ROUNDS


END MAIN
