401 lines
7.8 KiB
NASM
401 lines
7.8 KiB
NASM
;****************************************
|
|
; Elmar Kresse 19-INB-1 (2021)
|
|
; game.asm
|
|
; file contains source code for the
|
|
; basic functions of the game logic
|
|
;
|
|
; - conkf MACRO x_kord, y_kord
|
|
; - conkf_prog PROC FAR
|
|
; - game_logic PROC
|
|
; - check_won_value MACRO a, b, c
|
|
; - check_draw PROC
|
|
; - reset_player_data PROC
|
|
; - check_won PROC
|
|
; - reset_timerisr PROC
|
|
; - start_game PROC
|
|
;****************************************
|
|
|
|
conkf MACRO x_kord, y_kord ;MACRO for coordinates to field
|
|
push dx
|
|
push cx
|
|
|
|
|
|
mov cx, x_kord
|
|
mov dx, y_kord
|
|
mov field, 0h
|
|
call conkf_prog
|
|
|
|
pop cx
|
|
pop dx
|
|
ENDM
|
|
|
|
conkf_prog PROC FAR ;PROC for coordinates to field
|
|
push ax
|
|
push bx
|
|
push cx
|
|
push dx
|
|
;horizontal x
|
|
cmp cx, 482
|
|
jg out_of_range
|
|
cmp cx, 352
|
|
mov x_wert, 357
|
|
jnl x_3
|
|
cmp cx, 218
|
|
mov x_wert, 223
|
|
jnl x_2
|
|
cmp cx, 84
|
|
mov x_wert, 89
|
|
jnl x_1
|
|
jmp out_of_range
|
|
|
|
x_3:
|
|
mov ax, 2
|
|
jmp y_kordi
|
|
x_2:
|
|
mov ax, 1
|
|
jmp y_kordi
|
|
x_1:
|
|
mov ax, 0
|
|
|
|
y_kordi:
|
|
;vertical y
|
|
cmp dx, 412
|
|
jg out_of_range
|
|
cmp dx, 282
|
|
mov y_wert, 287
|
|
jnl y_3
|
|
cmp dx, 148
|
|
mov y_wert, 153
|
|
jnl y_2
|
|
cmp dx, 14
|
|
mov y_wert, 19
|
|
jnl y_1
|
|
jmp out_of_range
|
|
|
|
y_3:
|
|
mov bx, 6
|
|
jmp calc_field
|
|
y_2:
|
|
mov bx, 3
|
|
jmp calc_field
|
|
y_1:
|
|
mov bx, 0
|
|
|
|
calc_field:
|
|
add ax, bx ;(A = ax) * (B = bx) = (goal = AX)
|
|
mov field, ax
|
|
jmp kord_final
|
|
|
|
out_of_range:
|
|
mov field, 10 ;not in range(0-8) 10 is set for later checks
|
|
|
|
kord_final:
|
|
|
|
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
|
|
|
|
|
|
|
|
ret
|
|
conkf_prog ENDP
|
|
|
|
game_logic PROC
|
|
|
|
conkf x_wert, y_wert
|
|
|
|
;check valid field 0-8
|
|
cmp field, 0ah
|
|
je end_game_logic
|
|
|
|
;Feld frei
|
|
push ax
|
|
push si
|
|
mov si, field
|
|
shl si, 1
|
|
cmp player1[si], 1
|
|
pop si
|
|
pop ax
|
|
je end_game_logic
|
|
|
|
push ax
|
|
push si
|
|
mov si, field
|
|
shl si, 1
|
|
cmp player2[si], 1
|
|
pop si
|
|
pop ax
|
|
je end_game_logic
|
|
|
|
|
|
|
|
mov ax, spieler
|
|
cmp ax, 0
|
|
je kreuz_spieler
|
|
jne kreis_spieler
|
|
|
|
kreuz_spieler:
|
|
cross_draw x_wert, y_wert, 120
|
|
|
|
;Sound
|
|
PUSH AX BX CX DX
|
|
MOV BX, OFFSET placeSound
|
|
MOV CX, OFFSET placeSoundLength
|
|
CALL playbeep
|
|
POP DX CX BX AX
|
|
|
|
mov spieler, 1 ;Spieler umschalten
|
|
|
|
;Geklicketes Feld belegen
|
|
push ax
|
|
push si
|
|
mov si, field
|
|
shl si, 1
|
|
mov player1[si], 1
|
|
pop si
|
|
pop ax
|
|
|
|
push cx
|
|
mov cx, offset player1
|
|
call check_won
|
|
pop cx
|
|
cmp ax, 1
|
|
jne end_game_logic
|
|
mov cx, 2
|
|
call reset_timerisr
|
|
call start_programm
|
|
|
|
kreis_spieler:
|
|
;Kreis zeichnen
|
|
circle_draw x_wert, y_wert, 60
|
|
|
|
|
|
;Sound
|
|
PUSH AX BX CX DX
|
|
MOV BX, OFFSET placeSound
|
|
MOV CX, OFFSET placeSoundLength
|
|
CALL playbeep
|
|
POP DX CX BX AX
|
|
|
|
mov spieler, 0 ;Spieler umschalten
|
|
|
|
;Geklicketes Feld belegen
|
|
push ax
|
|
push si
|
|
mov si, field
|
|
shl si, 1
|
|
mov player2[si], 1
|
|
pop si
|
|
pop ax
|
|
|
|
push cx
|
|
mov cx, offset player2
|
|
call check_won
|
|
pop cx
|
|
|
|
cmp ax, 1
|
|
jne end_game_logic
|
|
mov cx, 3
|
|
call reset_timerisr
|
|
call start_programm
|
|
|
|
end_game_logic:
|
|
|
|
call check_draw
|
|
ret
|
|
game_logic ENDP
|
|
|
|
check_won_value MACRO a, b, c
|
|
push ax
|
|
push bx
|
|
mov bx, 0
|
|
mov ax, a;
|
|
shl ax, 1
|
|
add bp, ax
|
|
add bx, ds:[bp]
|
|
mov bp, cx
|
|
mov ax, b;
|
|
shl ax, 1
|
|
add bp, ax
|
|
add bx, ds:[bp]
|
|
mov bp, cx
|
|
mov ax, c;
|
|
shl ax, 1
|
|
add bp, ax
|
|
add bx, ds:[bp]
|
|
mov bp, cx
|
|
cmp bx, 3
|
|
pop bx
|
|
pop ax
|
|
je got_winner
|
|
ENDM
|
|
|
|
check_draw PROC
|
|
|
|
;Überprüfen ob Unentschieden
|
|
push bx ;Counter ob alle Felder belegt sind
|
|
push ax ;Zahlvariable für Shiften
|
|
push cx ;Pointer für das Array des jeweiligen Spielers
|
|
push dx ;Zählvariable für Schleifen
|
|
push bp
|
|
mov bx, 0
|
|
mov ax, 0
|
|
mov dx, 0
|
|
|
|
mov cx, offset player1 ;pointer for player1
|
|
|
|
player1_field_loop:
|
|
mov ax, dx
|
|
shl ax, 1
|
|
mov bp, cx
|
|
add bp, ax
|
|
add bx, ds:[bp]
|
|
inc dx
|
|
cmp dx, 9
|
|
jne player1_field_loop
|
|
|
|
mov cx, offset player2 ;pointer for player2
|
|
mov dx, 0
|
|
player2_field_loop:
|
|
mov ax, dx
|
|
shl ax, 1
|
|
mov bp, cx
|
|
add bp, ax
|
|
add bx, ds:[bp]
|
|
inc dx
|
|
cmp dx, 9
|
|
jne player2_field_loop
|
|
|
|
|
|
cmp bx, 9
|
|
|
|
pop bp
|
|
pop dx
|
|
pop cx
|
|
pop ax
|
|
pop bx
|
|
|
|
je draw_end
|
|
jmp check_draw_end
|
|
|
|
draw_end:
|
|
mov cx, 4 ; 4 = Unentschieden
|
|
call reset_timerisr
|
|
call start_programm
|
|
|
|
check_draw_end:
|
|
ret
|
|
check_draw ENDP
|
|
|
|
reset_player_data PROC
|
|
|
|
push ax
|
|
push si
|
|
push bx ;Schleifen Zähler
|
|
mov bx, 0
|
|
|
|
resetloop_player1:
|
|
mov si, bx
|
|
shl si, 1
|
|
mov player1[si], 0
|
|
inc bx
|
|
cmp bx, 9
|
|
jne resetloop_player1
|
|
|
|
mov bx, 0
|
|
resetloop_player2:
|
|
mov si, bx
|
|
shl si, 1
|
|
mov player2[si], 0
|
|
inc bx
|
|
cmp bx, 9
|
|
jne resetloop_player2
|
|
|
|
pop bx
|
|
pop si
|
|
pop ax
|
|
ret
|
|
reset_player_data ENDP
|
|
|
|
check_won PROC
|
|
push bp
|
|
mov bp, cx
|
|
|
|
;vertical
|
|
check_won_value 0, 3, 6
|
|
check_won_value 1, 4, 7
|
|
check_won_value 2, 5, 8
|
|
|
|
;horizontal
|
|
|
|
check_won_value 2, 1, 0
|
|
check_won_value 3, 4, 5
|
|
check_won_value 6, 7, 8
|
|
|
|
;cross
|
|
check_won_value 0, 4, 8
|
|
check_won_value 6, 4, 2
|
|
jmp ende_check_won
|
|
|
|
got_winner:
|
|
pop bp
|
|
|
|
;play gameover sound
|
|
MOV BX, OFFSET gameOverSound
|
|
MOV CX, gameOverSoundLength
|
|
CALL playbeep
|
|
|
|
mov ax, 1 ;var for save winner exists
|
|
ret
|
|
|
|
ende_check_won:
|
|
pop bp
|
|
mov ax, 0
|
|
ret
|
|
check_won ENDP
|
|
|
|
reset_timerisr PROC
|
|
PUSH CX
|
|
PUSH DS
|
|
PUSH AX
|
|
PUSH DX
|
|
MOV AX, 251Ch ; Restore old user timer interrupt vector
|
|
MOV DX, [CS:old_timer]
|
|
MOV CX, [CS:old_segment]
|
|
MOV DS, CX
|
|
INT 21h
|
|
POP DX
|
|
POP AX
|
|
POP DS
|
|
POP CX
|
|
ret
|
|
reset_timerisr ENDP
|
|
|
|
start_game PROC
|
|
CLI
|
|
|
|
mov ax,00h
|
|
int 33h
|
|
or ax,ax
|
|
|
|
call reset_player_data ;Spieler Array reset
|
|
mov ax,12h ;Videomodus
|
|
int 10h
|
|
|
|
call prepare_display
|
|
|
|
mov ax, 1 ;Curser an
|
|
int 33h
|
|
|
|
;Ersten Spieler setzten
|
|
|
|
call prepare_mouse
|
|
mov spieler, 0
|
|
call prepare_display
|
|
|
|
STI
|
|
ret
|
|
start_game endp |