-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.asm
More file actions
1392 lines (1306 loc) · 38.2 KB
/
main.asm
File metadata and controls
1392 lines (1306 loc) · 38.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; Including Macros Library
INCLUDE ship.inc
INCLUDE bullet.inc
INCLUDE refl.inc
INCLUDE name.inc
INCLUDE lib.inc
INCLUDE chatlib.inc
.MODEL SMALL
.386
.STACK 64
.DATA
;CHAT_GET_USER_INP
;*************************************************
CURSOR1_Y EQU 11D
CURSOR2_Y EQU 23D
CURSOR1_CUR_X DB 0
CURSOR2_CUR_X DB 0
CHAR1 DB ?
CHAR2 DB ?
CHAT_FLAG1 DB 0
CHAT_FLAG2 DB 0
game_flag1 db 0
game_flag2 db 0
GAME_LEVEL DB 0
SEND_INVITATION DB 0
;name page
;****************************************************
playership1 db 15 dup('$'),'$' ; NAME OF PLAYER SHIP 1
;playership2 DB 15 DUP('$'),'$' ; NAME OF PLAYER SHIP 2
PLAYERSHIP2 DB "ALI",'$'
MES DB 'Press enter to continue $','$'
MESSHIP1 DB 'Please Enter the name $','$'
SCN DB 1 ; TO DETERMINE NAME PAGE TO PLAYER SHIP 1 '1'OR SHIP 2 '2'
word_color equ 0fh
ActualSize1 DB 0
SEND_NAME_F DB 0
RECIVE_NAME_F DB 0
; Printing Strings
;****************************************************
st0 db "to end game click f4 & TO PAUSE F1 $"
st1 db "To Start Chatting Press F1",10,13,10,13," To Start Playing Game Press F2",10,13,10,13," To End The Programe Press Esc",10,13,10,13,'$'
st2 db "press Enter to back to main menu",10,13,10,13,'$'
st3 db "screen for chatting ",10,13,10,13,'$'
st4 db "screen for playing ",10,13,10,13,'$'
st5 db "screen for Exiting ",10,13,10,13,'$'
st7 db 10,13,10,13,"Click f4 to return to main menu $"
ST8 DB 'want TO CHAT YOU','$'
ST9 DB 'want TO game with YOU','$'
ST10 DB "To Start LEVEL ONE press 1 ",10,13,10,13," To Start LEVEL TWO press 2",'$'
window_winner db "*** The Winner is *** ",10,13,10,13,'$'
equal_window db "*** no one ****",'$'
; Printing and Drawing variables
;*****************************************************
BGCOLOR EQU 0H ; background color
REFLECTORCOLOR EQU 56H ; reflector color
SHIP1COLOR DB 33H ; ship 1 color
SHIP2COLOR DB 33H ; ship 1 color
BOARDSCOLOR EQU 043H ; boards color
BOARDERTHICK EQU 2 ; boards thickness
BOARDER1FY EQU 145 ; frist boarder y
BOARDER1FX EQU 0 ; boards frist x
BOARDER1EX EQU 640 ; boards end x
REFLECTORlen EQU 60 ;reflector length
ShipSizep1y EQU 30 ; part 1 in ship length
ShipSizep2Y EQU 8 ; part 2 in ship length
PLAYER_SC_pY EQU 13H ;player score position y
PLAYER1_SC_pX EQU 01H ;player 1 score position x
PLAYER2_SC_pX EQU 14H ;player 2 score position y
PLAYER1_msg_py EQU 15H ;player 1 message position y
PLAYER2_msg_py EQU 18H ;player 2 message position y
ship2Damage EQU 44h ; color to damage
ship1Damage EQU 44h ;color to damage
helthfy equ 151
helthlen equ 8
helthsh1fx dw 99 ,104,109,114,119,124,129,134,139,144
helthsh1ex dw 102,107,112,117,122,127,132,137,142,147
helthcolor equ 04h
helthsh2fx dw 249,254,259,264,269,274,279,284,289,294
helthsh2Ex dw 252,257,262,267,272,277,282,287,292,297
; Player 1 Variables
;****************************************************
Ship1_Speed DW 1
SH1PROTECT_FLAG DB 0
SH1TIMES_PROTECT DB 0
sh1health Dw 10
sh1p1fy DW 1
sh1p2fy DW 12
sh1p1fx EQU 5
sh1p1ENDx equ 15
sh1p2fx EQU 16
sh1p2ENDx equ 21
p1_bulls db 0 ; No of bullets fired
fl db 00h
; Player 2 Variables
;****************************************************
Ship2_Speed DW 1
SH2PROTECT_FLAG DB 0
SH2TIMES_PROTECT DB 0
sh2health Dw 10
sh2p1fy DW 1
sh2p2fy DW 12
sh2p1fx EQU 300
sh2p1ENDx equ 310
sh2p2fx EQU 294
sh2p2ENDx equ 299
p2_bulls db 0 ; No of bullets fired
fr db 00h
; IsThereAWinner - boolean value to determine if there's a final winner or not
IsThereAWinner db 00H
; Reflector Variables
;****************************************************
REFfristY DW 1
REFfristX EQU 151
REFendX EQU 156
REFflag db 01 ; it take one or two to detrmine if it move down "if 1" or move up "if 0"
REFSPEED EQU 0fffh ;It is the counter when equal zero the reflector step & it control speed of reflector
REFCTR dw 0fffh
; Bullets Variables
;****************************************************
buW equ 20 ; Bullet width. No need to keep its height, just 3.
; All Bullets Positions Array, Each bullet is represented by 2 words
; LSW => stores X of the top-left px.
; MSW => stores Y of the top-left px. in the first byte, and type of the bullet in the MSB
; Type of bullet is 0 for left-to-right bullet and 1 for right-to-left
bullPoses dw 100 dup(0FFFFH), 0FEFEH
bullRPwr dW 5
bullLPwr dW 5
bullLSpeed EQU 00FFH ; Speed of left-to-right bullets in gameloop units
bullLCtr dw 00FFH ; Speed of left-to-right bullets in gameloop units
bullRSpeed EQU 0AFFH ; Speed of right-to-left bullets in gameloop units
bullRCtr dw 0AFFH ; Speed of right-to-left bullets in gameloop units
;******************************************************
;power ups
POWERUP_XFLAG DB 1 ; TO DETRMINE RIGTH '0' OR LEFT '1'
POWERUP_fy dw 8 ; FRIST Y
POWERUP_COUNTER dD 0Fffffh ; COUNTER
POWERUP_color DB 04h ; COLOR &TYPE
POWERUP_ON DB 0 ;IF IN SCREEN
POWERUP_L_IS_DRAWN DB 0
POWERUP_R_IS_DRAWN DB 0
POWERUP_LEN EQU 8
POWERUPR_fx EQU 206 ; RIGTH SIDE FRIST X
POWERUPR_ex EQU 211 ; RIGTH SIDE END X
POWERUPL_fx EQU 95 ; LEFT SIDE FRIST X
POWERUPL_ex EQU 101 ; LEFT SIDE END X
POWERUP_TODROW EQU 03FFFFH ;THE MAIN VALUE TO FILL COUNTER WHEN DISAPEARE
POWERUP_TODELETE EQU 03FFFFH ;THE MAIN VALUE TO FILL COUNTER WHEN APEARE
POWERUP_MAXY EQU 130 ; MaX VALUE OF Y
HELTH_UP EQU 04H ;COLOR OF HEALTH BACKET
SPEAD_UP EQU 02H ; COLOR OF SPEED UP
SPEAD_DOWN EQU 01H ; COLOR SPEAD_DOWN
PROTECT EQU 03H ; COLOR PROTECT
;************************************************************
;ROCKET
ROCKET_XFLAG DB 1 ; TO DETRMINE RIGTH '0' OR LEFT '1'
ROCKET_fy dw 4 ; FRIST Y
ROCKET_COUNTER dD 0Affffh ; COUNTER
ROCKET_color DB 0Ch ; COLOR
ROCKET_ON DB 0 ;IF IN SCREEN
ROCK_L_IS_DRAWN DB 0
ROCK_R_IS_DRAWN DB 0
ROCKET_LEN EQU 28
ROCKETR_fx EQU 226 ; RIGTH SIDE FRIST X
ROCKETR_ex EQU 231 ; RIGTH SIDE END X
ROCKETL_fx EQU 75 ; LEFT SIDE FRIST X
ROCKETL_ex EQU 80 ; LEFT SIDE END X
ROCKET_TODROW EQU 03FFFFH ;THE MAIN VALUE TO FILL COUNTER WHEN DISAPEARE
ROCKET_TODELETE EQU 03FFFFH ;THE MAIN VALUE TO FILL COUNTER WHEN APEARE
ROCKET_MAXY EQU 110 ; MaX VALUE OF Y
;*******************************************************
;buffer to take name
MyBuffer LABEL BYTE ; TO READ IN
BufferSize db 40
ActualSize db ?
BufferData db 40 dup('$')
.CODE
MAIN PROC FAR
MOV AX,@DATA
MOV DS,AX
;**********************; TO USE STRING OPERATION
mov AX,DS
mov ES,AX
;***********************
cmp playership1,'$' ; to check if i need to enter player name or if it aready exist
jnz main_menu_pre
name_page
main_menu_pre:
; But DI at the first element of the bullets array
MOV DI,offset bullPoses
; Changes to the mode
DETERMINE_MODE 13H ,0H ; VIDEO MODE
MAIN_MENU:
CALL SHOW_MAIN_MENU
CONFIG
MAIN_GET_USER_INP:
GETKEY_NOWAIT
JZ MAIN_RECIVE_USER_INP
COMPARE_KEY 03BH ; Scan code of F1 Key
JNE CMP_F2_TO_GAME
MOV CHAT_FLAG2,1
MOV CHAR1,0FFH
SENDMSG
JMP CHAT
CMP_F2_TO_GAME:
COMPARE_KEY 03CH ; Scan code of F2 Key
JnE compare_esc
MOV game_FLAG2,1
MOV CHAR1,0FeH
SENDMSG
jmp game
compare_esc:
COMPARE_KEY 01H ; Scan code of ESC key
JE ENDG
JMP MAIN_RECIVE_USER_INP
MAIN_RECIVE_USER_INP:
RECMSG ; Function to recieve a byte, stores ASCII in AH, if nothing is sent, it puts CHAR2=0
CMP CHAR2,0 ; Means nothing to recieve
JZ MAIN_GET_USER_INP ; Go to the top of the loop
COMPARE_KEY_ASCII 0FFH
JNZ compare_for_game_loop ; Go to the top of the loop
MOV CHAT_FLAG1,1
JMP CHAT
compare_for_game_loop:
COMPARE_KEY_ASCII 0FeH
JNZ MAIN_GET_USER_INP ; Go to the top of the loop
MOV game_FLAG1,1
JMP game
CALL SHOW_GAME
JMP MAIN_MENU
; Branch of Chatting screen calls the SHOW_CHAT Proc.
CHAT: CALL SHOW_CHAT
JMP MAIN_GET_USER_INP
; Branch of Game screen calls the SHOW_GAME Proc.
GAME: CALL SHOW_GAME_level
JMP MAIN_GET_USER_INP ; If the user clicks enter, go to main-menu
ENDG: DETERMINE_MODE 03H, 00H
HALT
MAIN ENDP
; Procedures
;***********************************************************
SHOW_MAIN_MENU PROC
PREP_BACKBROUND BGCOLOR; TO PREPARE BACKGROUD COLOR & QUALITIES
MOVE_CURSOR 7H,7H,0 ;to write in the middle of screen
PRINTMESSAGE st1 ;Print 3 cases
RET
SHOW_MAIN_MENU ENDP
;*************************************************
; **** SHOW_CHAT - Showes the Chat screen ****
; * USES : AX, BX, CX , DX
; * PARAMS : NONE
; ************************************************
SHOW_CHAT PROC
CMP CHAT_FLAG1,1
JZ PRINT_CMP_FLAG2
RET
PRINT_CMP_FLAG2:
MOVE_CURSOR 7H,11H,0 ;to write in the END of screen
PRINTMESSAGE playership2 ;Print
MOVE_CURSOR 7H,12H,0 ;to write in the middle of screen
PRINTMESSAGE ST8
CMP CHAT_FLAG2,1
JZ GO_CHAT_MODE
RET
GO_CHAT_MODE:
MOV CHAT_FLAG1,0
MOV CHAT_FLAG2,0
DETERMINE_MODE 07H,00H
CHAT_MODE1
CALL MAIN
RET
SHOW_CHAT ENDP
;**************************************************
;***show game levels two choose level
;**************************************************
SHOW_GAME_level proc
CMP game_FLAG1,1
JZ PRIN_CMP_FLAG2
MOV SEND_INVITATION,1
RET
PRIN_CMP_FLAG2:
CMP game_FLAG2,1
JZ START_LEVEL_PAGE
MOVE_CURSOR 7H,11H,0 ;to write in the END of screen
PRINTMESSAGE playership2 ;Print
MOVE_CURSOR 7H,12H,0 ;to write in the middle of screen
PRINTMESSAGE ST9
MOV SEND_INVITATION,2
RET
START_LEVEL_PAGE:
CMP SEND_INVITATION,1
JNZ RECIVE_LEVEL
DETERMINE_MODE 13H,00H
PREP_BACKBROUND BGCOLOR
MOVE_CURSOR 7H,7H,0 ;to write in the middle of screen
PRINTMESSAGE st10 ;Print 3 cases
TAKE_LEVEL:
GETKEY
CMP AL,'1'
JNZ LEVEL_TWO
MOV GAME_LEVEL ,1
MOV CHAR1,1
SENDMSG
CALL SHOW_GAME
RET
LEVEL_TWO:
CMP AL,'2'
JNZ TAKE_LEVEL
MOV GAME_LEVEL ,2
MOV CHAR1,2
SENDMSG
MOV game_FLAG1,0
MOV game_FLAG2,0
MOV SEND_INVITATION,0
CALL SHOW_GAME
RET
RECIVE_LEVEL:
RECMSG ; Function to recieve a byte, stores ASCII in AH, if nothing is sent, it puts CHAR2=0
CMP CHAR2,0 ; Means nothing to recieve
JZ RECIVE_LEVEL ; Go to the top of the loop
CMP CHAR2,1
JNZ RECIVE_LEVEL_TWO
MOV GAME_LEVEL ,1
CALL SHOW_GAME
RET
RECIVE_LEVEL_TWO:
CMP CHAR2,2
JNZ RECIVE_LEVEL
MOV GAME_LEVEL ,2
MOV game_FLAG1,0
MOV game_FLAG2,0
MOV SEND_INVITATION,0
CALL SHOW_GAME
RET
SHOW_GAME_level endp
;*************************************************
; **** SHOW_GAME - Shows the game screen ****
; * USES : ALL
; * PARAMS : DI => *First_Empty_Byte
; ************************************************
SHOW_GAME PROC
GO_game_MODE:
; Reseting all game variables in the memory
CALL CLRMEMORY
; Drawing and preparing
PREP_BACKBROUND BGCOLOR
CALL DRWINFO
CALL DRWSHIPS
call drawhelthsh1
call drawhelthsh2
CMP GAME_LEVEL,1
JNZ GM_LP
CALL DRWREFL
GM_LP:
; Handling counters and drawing of Powerups
DEC POWERUP_COUNTER
CMP POWERUP_COUNTER,0
JNZ continue2
CMP POWERUP_ON,0
JZ DROW_POWERUP
JNZ DELETE_POWERUP
DROW_POWERUP:
DROWPRE_POWERUP
JMP continue2
DELETE_POWERUP:
DELETEP_POWERUP
JMP continue2
continue2:
DEC ROCKET_COUNTER
CMP ROCKET_COUNTER,0
JNZ continue0
CMP ROCKET_ON,0
JZ DROW_ROCKET
JNZ DELETE_ROCKET
DROW_ROCKET:
DROWPRE_ROCKET
JMP continue0
DELETE_ROCKET:
DELETEP_ROCKET
JMP continue0
continue0:
CMP GAME_LEVEL,1
JNZ CHK_BULL
continue1:
; Moving Reflector and bullets
; Cheking for Moving the Reflector
CMP REFCTR,0
JE MVREFL_LB
; Checking for Moving Bullets and moving them
CHK_BULL:
CMP bullLCtr,0
JNE DEC_CTRS_LB
MOV bullLCtr,bullLSpeed
CALL FAR PTR MVBULLSPROC
; Here we check if it happens to be a winner, then we exit the game function
CMP IsThereAWinner, 00h
JE DEC_CTRS_LB
EXIT_IF_F4:
GETKEY
COMPARE_KEY 03EH
JNE EXIT_IF_F4
RET
; Decrementing speed counter
DEC_CTRS_LB:
DEC REFCTR
DEC bullLCtr
DEC bullRCtr
JMP FAR PTR USER_INP
; Moving Reflector Branch
MVREFL_LB:
MVREFL
JMP CHK_BULL
; Branch of handling User Input
USER_INP:
GETKEY_NOWAIT
; Handle Pause and stop clicks
COMPARE_KEY 03EH ; Scan code for f4
JNE CHK_PAUSE
CALL DRWWINNER
call main
RET ; Ends the game if f4 is clicked
CHK_PAUSE:
COMPARE_KEY 03BH ; Scan code of f1
JNE GO
PAUSE
; Handle click of first player
GO: COMPARE_KEY 72 ; Scan code for UP arrow
CALL_MACRO_IF_EQUAL MVSH1UP
COMPARE_KEY 80 ; Scan code for DOWN arrow
CALL_MACRO_IF_EQUAL MVSH1DOWN
COMPARE_KEY 39H ; Scan code for Space
CALL_MACRO_IF_EQUAL ADDBULL
; Handle click of second player
COMPARE_KEY 11H ; Scan code for W
CALL_MACRO_IF_EQUAL MVSH2UP
COMPARE_KEY 1FH
CALL_MACRO_IF_EQUAL MVSH2DOWN
COMPARE_KEY 02DH ; Scan code for X
CALL_MACRO_IF_EQUAL ADDBULR
JMP GM_LP
RET
SHOW_GAME ENDP
;*************************************************
; **** DRWINFO - Draws Players' Info ****
; * USES : AX, BX, CX, DX
; * PARAMS : NONE
; ************************************************
DRWINFO PROC
; Drawing Borders
drow_thick_line BOARDER1FX,BOARDER1EX ,BOARDER1FY,BOARDERTHICK,BOARDSCOLOR ; "dROW_THICK_line" IS MACRO TO DRAW UPPER BOARD
drow_thick_line BOARDER1FX,BOARDER1EX,BOARDER1FY+15,BOARDERTHICK,BOARDSCOLOR ; "dROW_THICK_line" IS MACRO TO DRAW MIDLE BOARD
drow_thick_line BOARDER1FX,BOARDER1EX ,BOARDER1FY+32,BOARDERTHICK,BOARDSCOLOR ; "dROW_THICK_line" IS MACRO TO DRAW down BOARD
; Printing Strings
MOVE_CURSOR PLAYER1_SC_pX,PLAYER_SC_pY,0
PRINTMESSAGE playership1
MOVE_CURSOR PLAYER2_SC_pX,PLAYER_SC_pY,0
PRINTMESSAGE playership2
; Draw Chat Area
MOVE_CURSOR PLAYER1_SC_pX,PLAYER1_msg_py,0
PRINTMESSAGE playership1
MOVE_CURSOR PLAYER1_SC_pX,PLAYER2_msg_py-1,0
PRINTMESSAGE playership2
MOVE_CURSOR PLAYER1_SC_pX,PLAYER2_msg_py,0
; Draw End game statment
PRINTMESSAGE st0
RET
DRWINFO ENDP
;******************************************
;****DRAW heath
;*****************************************
drawhelthsh1 proc
push cx
push si
push di
mov cx,0
mov si,offset helthsh1fx
mov di,offset helthsh1ex
labh2:
push cx
drow_thick_line [si],[di] ,helthfy,helthlen,BGCOLOR
add di,2
add si,2
pop cx
inc cx
cmp cx,10
jnz labh2
mov cx,0
mov si,offset helthsh1fx
mov di,offset helthsh1ex
labh1:
push cx
drow_thick_line [si],[di] ,helthfy,helthlen,helthcolor
add di,2
add si,2
pop cx
inc cx
cmp cx,sh1health
jnz labh1
pop di
pop si
pop cx
ret
drawhelthsh1 endp
;************************************************
drawhelthsh2 proc
push cx
push si
push di
mov cx,0
mov si,offset helthsh2fx
mov di,offset helthsh2ex
labh3:
push cx
drow_thick_line [si],[di] ,helthfy,helthlen,BGCOLOR
add di,2
add si,2
pop cx
inc cx
cmp cx,10
jnz labh3
mov cx,0
mov si,offset helthsh2fx
mov di,offset helthsh2ex
labh4:
push cx
drow_thick_line [si],[di] ,helthfy,helthlen,helthcolor
add di,2
add si,2
pop cx
inc cx
cmp cx,sh2health
jnz labh4
pop di
pop si
pop cx
ret
drawhelthsh2 endp
;*******************************************************
;*******************************************************
; Game Helper functions
;*******************************************************
;*******************************************************
;*************************************************
; **** DRWWINNER - Function draws winner screen for 5 seconds ****
; * USES : AX, BX, CX, DX
; * PARAMS : NONE
; ************************************************
DRWWINNER PROC
PREP_BACKBROUND 00h
MOVE_CURSOR 07,07,0
PRINTMESSAGE window_winner
MOVE_CURSOR 0fh,09,0
mov ax,sh2health
CMP sh1health,ax
ja labt1
je labt2
jb labt3
labt1:
PRINTMESSAGE playership1
jmp endtlab
labt2:
PRINTMESSAGE equal_window
jmp endtlab
labt3:
PRINTMESSAGE playership2
jmp endtlab
endtlab:
DELAY
RET
DRWWINNER ENDP
;*************************************************
; **** GAMECHAT - Function for in-game chatting ****
; * USES : AX, BX, CX, DX
; * PARAMS : NONE
; ************************************************
GAMECHAT PROC
RET
GAMECHAT ENDP
;*******************************************************
;*******************************************************
; Ship drawing functions
;*******************************************************
; can be moved into a separate module
;*******************************************************
;*******************************************************
;*************************************************
; **** DRWSHIPL - Draws both ship ****
; * USES : ALL
; * PARAMS : Param1 => Reg, Param2 => Reg, ...
; ************************************************
DRWSHIPS PROC
drow_thick_line sh1p1fx,sh1p1ENDx,sh1p1fy,ShipSizep1y,ship1color ; "dROW_THICK_line" IS MACRO TO DRAW SHIP 1 PART 1
drow_thick_line sh1p2fx,sh1p2ENDx,sh1p2fy,ShipSizep2y,ship1color ; "dROW_THICK_line" IS MACRO TO DRAW SHIP 1 PART 2
drow_thick_line sh2p1fx,sh2p1ENDx,sh2p1fy,ShipSizep1y,ship2color ; "dROW_THICK_line" IS MACRO TO DRAW SHIP 2 PART 1
drow_thick_line sh2p2fx,sh2p2ENDx,sh2p2fy,ShipSizep2y,ship2color ; "dROW_THICK_line" IS MACRO TO DRAW SHIP 2 PART 2
RET
DRWSHIPS ENDP
;*******************************************************
; Reflector drawing functions
;*******************************************************
; can be moved into a separate module
;*******************************************************
;*************************************************
; **** DRWREFL - Draws the reflector ****
; * USES : AX, BX, CX, DX
; * PARAMS : NONE
; ************************************************
DRWREFL PROC
drow_thick_line REFfristX,REFendX,REFfristY,REFLECTORlen,REFLECTORCOLOR
RET
DRWREFL ENDP
; ***************************************************************
; SOME BULLET FUNCTIONS
;****************************************************************
; MVBULLS - Main bullet movement logic
MVBULLSPROC PROC FAR
; 1: Use SI to point to the start of the array
MOV SI, offset bullPoses
BUL_START_LB:
; 2: At the beginning of the loop check if SI points to bullet data
; We also check if no data here or reached the mark of the end and if so we break the loop to outside
CMP [SI],0FFFFH
JNE COMPARE_FEFE
RET
COMPARE_FEFE:
CMP [SI],0FEFEH
JNE GO_BULLS_GO
RET
GO_BULLS_GO:
; 3: Put the initial position of X and Y of the current bullet to CX, DX
MOV CX, [SI]
MOV DX, [SI+2]
; Note that SI is kept at the X position so as for MVBULL1 to store the new X position in
; To call the right function according to the type of the bullet, we know that the type of the bullet
; is stored in the MSB of YPos of the bullet, 1 if right and 0 if left, Ok ?
; This means that if the bullet is left, YPos will be less than 8000H
; We can use this piece of information to make condition on the type
; Recall that : CMP dist,src : if dist<src, CF is set (=1)
CMP DX,8000H
JNC R_MV ; No carry means YPos > 8000H i.e. Right Bullet
;***************************************************************************
; LEFT BULLET CHECKS GOES HERE
;***************************************************************************
; 1. End of screen
MOV AX,CX
ADD AX,buW
CMP AX, 320D
JE DEL_BUL_LEFT
; 2. Ship
; TODO: -for me- Add comments
MOV AX,CX
ADD AX,buW
INC AX
CMP AX,sh2p2fx
JNE BULL_CHECK_REFL
MOV AX,sh2p1fy
ADD AX,ShipSizep1y
SUB AX,DX
CMP AX,ShipSizep1y+3
JNC BULL_CHECK_REFL
mov fl,01h
CALL DECP2HEALTH
JMP DEL_BUL_LEFT
BULL_CHECK_REFL:
CMP GAME_LEVEL,1
JNZ BULL_CHECK_OTHERS ; TO CHECK LEVEL ONE
; 3.CONSTANT Reflector
; TODO: -for me- Add comments
MOV AX,CX
ADD AX,buW
INC AX
CMP AX,REFfristX
JNZ BULL_CHECK_OTHERS
MOV AX,REFfristY
ADD AX,REFLECTORlen
SUB AX,DX
CMP AX,REFLECTORlen+3
JNC BULL_CHECK_OTHERS
JMP INV_BULL
BULL_CHECK_OTHERS:
;*******************************************************
;ROCKET CHECKS
;*******************************************************
BULL_CHECK_Rocket:
CMP ROCKET_ON,0
JZ CHECK_POWER_UP
; CMP ROCKET_XFLAG,0
; JZ BULL_CHECK_HELTHROCKRIGHT
BULL_CHECK_HELTROCKLEFT:
MOV AX,CX
ADD AX,buW
INC AX
CMP AX,ROCKETL_fx
JE FOUND_X_ROCK_LEFT
CMP AX,ROCKETR_fx
JE FOUND_X_ROCK_RIGHT
JMP CHECK_POWER_UP
FOUND_X_ROCK_LEFT:
MOV ROCKET_XFLAG,0
JMP SEARCH_ROCK_Y
FOUND_X_ROCK_RIGHT:
MOV ROCKET_XFLAG,1
SEARCH_ROCK_Y:
MOV AX,ROCKET_fy
ADD AX,ROCKET_LEN
SUB AX,DX
CMP AX,ROCKET_LEN+3
JNC CHECK_POWER_UP
CMP ROCKET_COLOR,0DH
JNZ DELETE_ROCK_ONLYL
JMP INV_BULL
DELETE_ROCK_ONLYL:
JMP DEL_BUL_LEFT
;*******************************************************
;POWER UP CHECKS
;*******************************************************
CHECK_POWER_UP:
CMP POWERUP_ON,0
JZ MOVE_BULLET_LEFT
CMP POWERUP_L_IS_DRAWN,1
JNZ BULL_CHECK_POWERUPRIGHT
MOV AX,CX
ADD AX,buW
INC AX
CMP AX,POWERUPL_fx
JNE BULL_CHECK_POWERUPRIGHT
MOV POWERUP_XFLAG,0
JMP SEARCH_POWERUP_Y
BULL_CHECK_POWERUPRIGHT:
CMP POWERUP_R_IS_DRAWN,1
JNZ MOVE_BULLET_LEFT
MOV AX,CX
ADD AX,buW
INC AX
CMP AX,POWERUPR_fx
JNE MOVE_BULLET_LEFT
MOV POWERUP_XFLAG,1
SEARCH_POWERUP_Y:
MOV AX,POWERUP_fy
ADD AX,POWERUP_LEN
SUB AX,DX
CMP AX,POWERUP_LEN+3
JNC MOVE_BULLET_LEFT
CALL POWER_UP_CHECK_TYPE_SH1
DELETE_POWERUP_ONLY
JMP DEL_BUL_LEFT
; Call MVBULL, it moves the left bullet and stores the new position in [SI]
MOVE_BULLET_LEFT:
CALL MVBULL
JMP END_BUL_LP
; Branch for left bullet deletion
DEL_BUL_LEFT:
DEC p1_bulls
JMP DEL_BUL
R_MV:
; Don't forget that we store the type of the bullet in the MSB of YPos
; but we don't want this to affect our drawing
; so we must make sure it's 0 before drawing or deleting
AND DX, 7FFFH
;***************************************************************************
; RIGHT BULLET CHECKS GOES HERE
;***************************************************************************
; 1. End of screen
CMP CX, 00D
JE DEL_BUL_RIGHT
; 2. Ship
; TODO: -for me- Add comments
MOV AX,CX
DEC AX
CMP AX,sh1p2ENDx
JNZ BULR_CHECK_REFL
MOV AX,sh1p1fy
ADD AX,ShipSizep1y
SUB AX,DX
CMP AX,ShipSizep1y+3
JNC BULR_CHECK_REFL
mov fr,01h
CALL DECP1HEALTH
JMP DEL_BUL_RIGHT
BULR_CHECK_REFL:
CMP GAME_LEVEL,1
JNZ BULR_CHECK_OTHERS ; BECOUSE LEVEL ONE ONLY HAS CONSTANT REFLECTOR
; 3. CONSTANT Reflector
; TODO: -for me- Add comments
CMP CX,REFendX
JNE BULR_CHECK_OTHERS
MOV AX,REFfristY
ADD AX,REFLECTORlen
SUB AX,DX
CMP AX,REFLECTORlen+3
JNC BULR_CHECK_OTHERS
JMP INV_BULR
BULR_CHECK_OTHERS:
;*******************************************************
; CHECK ROCKET
;*******************************************************
BULL_CHECK_Rocket1:
CMP ROCKET_ON,0
JZ CHECK_POWER_UP_R
BULR_CHECK_HELTHROCKLEFT:
MOV AX,CX
DEC AX
CMP AX,ROCKETL_Ex
JZ R_FOUND_X_ROCK_LEFT
CMP AX,ROCKETR_Ex
JZ R_FOUND_X_ROCK_RIGHT
JMP CHECK_POWER_UP_R
R_FOUND_X_ROCK_LEFT:
MOV ROCKET_XFLAG,0
JMP R_SEARCH_ROCK_Y
R_FOUND_X_ROCK_RIGHT:
MOV ROCKET_XFLAG,1
R_SEARCH_ROCK_Y:
MOV AX,ROCKET_fy
ADD AX,ROCKET_LEN
SUB AX,DX
CMP AX,ROCKET_LEN+3
JNC CHECK_POWER_UP_R
CMP ROCKET_COLOR,0DH
JNZ DELETE_ROCK_ONLYr
JMP INV_BULR
DELETE_ROCK_ONLYr:
JMP DEL_BUL_RIGHT
;*******************************************************
; CHECK POWERUP
;*******************************************************
CHECK_POWER_UP_R:
CMP POWERUP_ON,0
JZ MOVE_BULLET_RIGHT
CMP POWERUP_L_IS_DRAWN,1
JNZ BULR_CHECK_POWERUPRIGHT
MOV AX,CX
DEC AX
CMP AX,POWERUPL_Ex
JNE BULR_CHECK_POWERUPRIGHT
MOV POWERUP_XFLAG,0
JMP R_SEARCH_POWERUP_Y
BULR_CHECK_POWERUPRIGHT:
CMP POWERUP_R_IS_DRAWN,1
JNZ MOVE_BULLET_RIGHT
MOV AX,CX
DEC AX
CMP AX,POWERUPR_Ex
JNE MOVE_BULLET_RIGHT
MOV POWERUP_XFLAG,1
R_SEARCH_POWERUP_Y:
MOV AX,POWERUP_fy
ADD AX,POWERUP_LEN
SUB AX,DX
CMP AX,POWERUP_LEN+3
JNC MOVE_BULLET_RIGHT
CALL POWER_UP_CHECK_TYPE_SH2
DELETE_POWERUP_ONLY
JMP DEL_BUL_RIGHT
MOVE_BULLET_RIGHT:
; Call MVBULR, it moves the left bullet and stores the new position in [SI]
CALL MVBULR
JMP END_BUL_LP
; Branch for right bullet deletion
DEL_BUL_RIGHT:
DEC p2_bulls
DEL_BUL:
CALL DELBUL
CALL changeColor
JMP END_BUL_LP_WITHOUT_INC
;Increment SI by 4 to get a new bullet position
END_BUL_LP:
ADD SI,4
END_BUL_LP_WITHOUT_INC:
JMP BUL_START_LB
; Invert Left Bullet Branch
INV_BULL:
CALL INVBUL
CALL MVBULR
JMP END_BUL_LP
; Invert Right Bullet Branch
INV_BULR:
CALL INVBUL
CALL MVBULL
JMP END_BUL_LP
; 7: Sometimes we don't need to increment SI, e.g. after deleting a bullet due to the way we do deletion by shifting
BULL_OUT_LB: RET
MVBULLSPROC ENDP
;*******************************************
; **** MOVE LEFT BULLET FUNCTION ***************
; **** Also saves the new position to memory
; * USES : CX , DX, DI
; * PARAMS : X_START => CX, Y_START => DX,
; : X_Store => DI
; *****************************************
MVBULL PROC
; Black the first coloumn of the bullet
DRWPX 00H
INC DX
DRWPX 00H
INC DX
DRWPX 00H
; Save the new buX in memory
INC CX
MOV [SI],CX
; Set the position after the end of the bullet
ADD CX,13H
; White a new column after the end
DRWPX 0FH
DEC DX
DRWPX 0FH
DEC DX
DRWPX 0FH
RET
MVBULL ENDP
;*******************************************
; **** MOVE RIGHT BULLET FUNCTION ***************
; **** Also saves the new position to memory
; * USES : CX , DX, DI
; * PARAMS : X_END => CX, Y_END => DX,
; : X_Store => DI
; *****************************************
MVBULR PROC
; Save the new buX in memory
DEC CX
MOV [SI],CX
; White a new coloumn before the start
DRWPX 0FH
INC DX
DRWPX 0FH
INC DX
DRWPX 0FH
; Set the position at the end of the bullet
ADD CX,15H
; Black the last column of the bullet
DRWPX 00H
DEC DX
DRWPX 00H
DEC DX
DRWPX 00H
RET
MVBULR ENDP