-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraphics.inc
1757 lines (1499 loc) · 40.7 KB
/
graphics.inc
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
; ----------------------------
; Graphics API
; Available functions:
; - LoadSpriteGlobe
; - UnloadSpriteGlobe
; - SetTransparentColor
; - LoadSprite
; - DrawSprite
; - LoadSpriteGlobePalette
; - FillScreen
; - DrawPoint
; - DrawRect
; - DrawLine
; - DrawPalette
; - CheckLineAndBMPCollision
; - CheckRectAndBMPCollision
; - CheckPointAndBMPCollision
;
; Made by K9Dev / Ilai K
; ----------------------------
; #####################################
;
; Function Name: LoadSpriteGlobe (PUBLIC)
; Description: Load the sprite globe file and put the handle into GAPI_globe_file_handle
; Input:
; - [STACK] Globe image width
; - [STACK] Globe image height
; - [STACK] Globe file path (asciiz)
; Output:
; - [REG] AX = 0 if no error, otherwise error code
;
; #####################################
GAPI_ARG_globe_width equ [bp+8]
GAPI_ARG_globe_height equ [bp+6]
GAPI_ARG_globe_path equ [bp+4]
proc LoadSpriteGlobe
push bp
mov bp, sp
; Update the globe width and height
mov ax, GAPI_ARG_globe_width
mov [GAPI_globe_width], ax
mov ax, GAPI_ARG_globe_height
mov [GAPI_globe_height], ax
push dx
; Open the globe file, get the handle
mov ah, 3Dh
mov al, 00h ; readonly
mov dx, GAPI_ARG_globe_path
int 21h
pop dx
; If errors, keep the error code in AX
jc @@ret
; If no errors, save the file handle and put 0 in AX (no error)
mov [GAPI_globe_file_handle], ax
mov ax, 0
@@ret:
mov sp, bp
pop bp
ret 6
endp LoadSpriteGlobe
; #####################################
;
; Function Name: UnloadSpriteGlobe (PUBLIC)
; Description: Close the sprite globe file handle
; Input: None
; Output:
; - [REG] AX = 0 if no error, otherwise error code
;
; #####################################
proc UnloadSpriteGlobe
push bx
; Close the file handle
mov ah, 3Eh
mov bx, [GAPI_globe_file_handle]
int 21h
pop bx
; If errors, keep the error code in AX
jc @@ret
; If no errors, save the file handle and put 0 in AX (no error)
mov ax, 0
@@ret:
ret
endp UnloadSpriteGlobe
; #####################################
;
; Function Name: _SetFilePointer (LOCAL)
; Description: Set the pointer of the file to a specified position
; Input:
; - [STACK] File handle (expected to be read)
; - [STACK] Number of bytes to move the pointer from its current position (HIGH)
; - [STACK] Number of bytes to move the pointer from its current position (LOW)
; Output:
; - [REG] AX = 0 if no error, otherwise error code
;
; #####################################
GAPI_ARG_handle equ [bp+8]
GAPI_ARG_pointer_offHIGH equ [bp+6]
GAPI_ARG_pointer_offLOW equ [bp+4]
proc _SetFilePointer
push bp
mov bp, sp
push bx
push dx
push cx
; Set the file pointer to `GAPI_ARG_pointer_off`
mov ah, 42h
mov al, 00h
mov bx, GAPI_ARG_handle
mov dx, GAPI_ARG_pointer_offLOW
mov cx, GAPI_ARG_pointer_offHIGH
int 21h
jc @@ret
mov ax, 0
@@ret:
pop cx
pop dx
pop bx
mov sp, bp
pop bp
ret 6
endp _SetFilePointer
; #####################################
;
; Function Name: _AdvanceFilePointer (LOCAL)
; Description: Set the pointer of the file to a specified position
; Input:
; - [STACK] File handle (expected to be read)
; - [STACK] Number of bytes to move the pointer from its current position
; Output:
; - [REG] AX = 0 if no error, otherwise error code
;
; #####################################
GAPI_ARG_handle equ [bp+6]
GAPI_ARG_pointer_off equ [bp+4]
proc _AdvanceFilePointer
push bp
mov bp, sp
push bx
push dx
push cx
; Move file pointer `GAPI_ARG_pointer_off` bytes
mov ah, 42h
mov al, 01h
mov bx, GAPI_ARG_handle
xor cx, cx
mov dx, GAPI_ARG_pointer_off
int 21h
jc @@ret
mov ax, 0
@@ret:
pop cx
pop dx
pop bx
mov sp, bp
pop bp
ret 4
endp _AdvanceFilePointer
; #####################################
;
; Function Name: SetTransparentColor (PUBLIC)
; Description: Sets the color to ignore when drawing the sprite (finds the color index in the palette)
; Input:
; - [STACK] The X position of the color in the BMP
; - [STACK] The Y position of the color in the BMP
; Output:
; - [REG] AX = 0 if no error, otherwise error code
;
; #####################################
GAPI_ARG_transX equ [word bp+6]
GAPI_ARG_transY equ [word bp+4]
proc SetTransparentColor
push bp
mov bp, sp
push ax
push bx
push cx
push dx
; Calculate offset (DX:AX)
mov ax, GAPI_ARG_transY
mov bx, [GAPI_globe_width]
xor dx, dx
mul bx
add ax, GAPI_ARG_transX
adc dx, 0
; Skip the BMP header and palette
mov bx, 54 + 400h ; header + palette
add ax, bx
adc dx, 0
; Set the pointer
push [GAPI_globe_file_handle]
push dx
push ax
call _SetFilePointer
cmp ax, 0
jne @@ret
; Read the color
mov ah, 3Fh
mov bx, [GAPI_globe_file_handle]
mov cx, 1
mov dx, offset GPAI_transparent_clr_id
int 21h
jc @@ret
mov ax, 0
@@ret:
pop dx
pop cx
pop bx
pop ax
pop bp
ret 4
endp SetTransparentColor
; #####################################
;
; Function Name: LoadSprite (PUBLIC)
; Description: Copy all data of a sprite (area from BMP) to a variable
; Input:
; - [STACK] The X position of the sprite (left) in the BMP
; - [STACK] The Y position of the sprite (top) in the BMP
; - [STACK] The width of the sprite
; - [STACK] The height of the sprite
; - [STACK] The offset to the variable that will store the sprite data
; Output:
; - [REG] AX = 0 if no error, otherwise error code
; Notes: The sprite data will be in the following format: w,h,x,y,byte offset
;
; #####################################
GAPI_ARG_sprite_x equ [word bp+12]
GAPI_ARG_sprite_y equ [word bp+10]
GAPI_ARG_sprite_width equ [word bp+8]
GAPI_ARG_sprite_height equ [word bp+6]
GAPI_ARG_sprite_data equ [word bp+4]
GAPI_LOC_offLOW equ [word bp-2]
GAPI_LOC_offHIGH equ [word bp-4]
GAPI_LOC_flippedY equ [word bp-6]
proc LoadSprite
push bp
mov bp, sp
sub sp, 6
; This function saves the sprite data in the following format: w,h,x,y,byte offset
; For later use.
push bx
push cx
push dx
push di
; Check if the sprite is too big
mov ax, GAPI_ARG_sprite_width
mov bx, GAPI_ARG_sprite_height
xor dx, dx
mul bl
cmp ax, 320*200
jbe @@noerr
; ERROR CODE (65h) -> Sprite too big
mov ax, 65h
jmp @@ret
@@noerr:
; Save Y before flipping
mov ax, GAPI_ARG_sprite_y
mov GAPI_LOC_flippedY, ax
; Get the byte offset of the sprite in the BMP
mov GAPI_LOC_offLOW, 54 + 400h ; header + palette
; Flip Y
mov ax, [GAPI_globe_height]
sub ax, GAPI_ARG_sprite_y
sub ax, GAPI_ARG_sprite_height
cmp ax, 0
jne @@fix
inc ax
@@fix:
mov GAPI_ARG_sprite_y, ax
; Calculate bytes to skip to get to sprite start position
mov ax, [GAPI_globe_width]
mov bx, GAPI_ARG_sprite_y
cmp GAPI_LOC_flippedY, 0 ; check before flip
je @@skp
dec bx
@@skp:
xor dx, dx
mul bx
add ax, GAPI_ARG_sprite_x
adc dx, 0 ; add carry
add GAPI_LOC_offLOW, ax
mov GAPI_LOC_offHIGH, dx
; Check if the sprite is out of the BMP (x)
mov ax, GAPI_ARG_sprite_x
add ax, GAPI_ARG_sprite_width
cmp ax, [GAPI_globe_width]
jg @@x_overflow_error
; Check if the sprite is out of the BMP (y)
mov ax, GAPI_LOC_flippedY
add ax, GAPI_ARG_sprite_height
cmp ax, [GAPI_globe_height]
jg @@y_overflow_error
; Save the sprite data
mov si, GAPI_ARG_sprite_data
mov ax, GAPI_ARG_sprite_x
mov [word ds:si], ax
mov ax, GAPI_ARG_sprite_y
mov [word ds:si+2], ax
mov ax, GAPI_ARG_sprite_width
mov [word ds:si+4], ax
mov ax, GAPI_ARG_sprite_height
mov [word ds:si+6], ax
mov ax, GAPI_LOC_offHIGH
mov [word ds:si+8], ax
mov ax, GAPI_LOC_offLOW
mov [word ds:si+10], ax
jmp @@cont
@@x_overflow_error:
; ERROR CODE (66h) -> X overflow
mov ax, 66h
jmp @@ret
@@y_overflow_error:
; ERROR CODE (67h) -> Y overflow
mov ax, 67h
jmp @@ret
@@cont:
mov ax, 0
@@ret:
pop di
pop dx
pop cx
pop bx
mov sp, bp
pop bp
ret 10
endp LoadSprite
; #####################################
;
; Function Name: DrawSprite (PUBLIC)
; Description: Draw a sprite on the screen
; Input:
; - [STACK] The x position to draw the sprite
; - [STACK] The y position to draw the sprite
; - [STACK] The offset to the variable that stores the sprite data
; Output: None
; Notes: The sprite data will be in the following format: x,y,w,h,byte offset
;
; #####################################
GAPI_ARG_draw_x equ [word bp+8]
GAPI_ARG_draw_y equ [word bp+6]
GAPI_ARG_draw_data equ [word bp+4]
GAPI_LOC_spriteX equ [word bp-2]
GAPI_LOC_spriteY equ [word bp-4]
GAPI_LOC_spriteW equ [word bp-6]
GAPI_LOC_spriteH equ [word bp-8]
GAPI_LOC_spriteOffLOW equ [word bp-10]
GAPI_LOC_spriteOffHIGH equ [word bp-12]
GAPI_LOC_padding equ [word bp-14]
proc DrawSprite
push bp
mov bp, sp
sub sp, 14
push bx
push cx
push dx
push di
push si
push es
; Make ES point to the video memory
mov ax, 0A000h
mov es, ax
; Get the sprite data
xor bx, bx
mov si, GAPI_ARG_draw_data
mov bx, [word ds:si]
mov GAPI_LOC_spriteX, bx
mov bx, [word ds:si+2]
mov GAPI_LOC_spriteY, bx
mov bx, [word ds:si+4]
mov GAPI_LOC_spriteW, bx
mov bx, [word ds:si+6]
mov GAPI_LOC_spriteH, bx
mov bx, [word ds:si+8]
mov GAPI_LOC_spriteOffHIGH, bx
mov bx, [word ds:si+10]
mov GAPI_LOC_spriteOffLOW, bx
; Prepare the video memory offset (DI -> video memory index) | start from end because Y is flipped
mov ax, GAPI_ARG_draw_y
mov bx, 320
xor dx, dx
mul bx
mov di, ax
mov ax, GAPI_LOC_spriteH
dec ax
xor dx, dx
mul bx
add di, ax
add di, GAPI_ARG_draw_x
; Advance the file pointer to the sprite data
push [GAPI_globe_file_handle]
push GAPI_LOC_spriteOffHIGH
push GAPI_LOC_spriteOffLOW
call _SetFilePointer
cmp ax, 0
jne @@ret
; Drawing from bottom to top
mov cx, GAPI_LOC_spriteH
@@line_loop:
push cx
; Read the line
xor ax, ax
mov ah, 3Fh
mov bx, [GAPI_globe_file_handle]
mov cx, 320
mov dx, offset GAPI_curr_bmp_line
int 21h
jc @@ret
; Draw the line
mov bx, offset GAPI_curr_bmp_line
mov cx, GAPI_LOC_spriteW
@@col_loop:
xor ax, ax
mov al, [bx]
cmp al, [GPAI_transparent_clr_id]
je @@skip_draw
mov [byte es:di], al
@@skip_draw:
inc bx
inc di
loop @@col_loop
; Move to the next line (Screen)
sub di, GAPI_LOC_spriteW ; Go back on drawn line
sub di, 320 ; Skip to the next line
; Advance pointer incase globe is bigger than 320
cmp [GAPI_globe_width], 320
jle @@skip_pointer
mov ax, [GAPI_globe_width]
sub ax, 320
push [GAPI_globe_file_handle]
push ax
call _AdvanceFilePointer
cmp ax, 0
jne @@ret
@@skip_pointer:
pop cx
loop @@line_loop
mov ax, 0
@@ret:
pop es
pop si
pop di
pop dx
pop cx
pop bx
mov sp, bp
pop bp
ret 6
endp DrawSprite
; #####################################
;
; Function Name: LoadSpriteGlobePalette (PUBLIC)
; Description: Load the sprite globe palette
; Input: None
; Output:
; - [REG] AX = 0 if no error, otherwise error code
;
; #####################################
proc LoadSpriteGlobePalette
push bx
push cx
push dx
push si
; Skip the BMP header
push [GAPI_globe_file_handle]
push 0
push 54 ; Skip header
call _SetFilePointer
cmp ax, 0
jne @@ret
; Load the palette
mov cx, 256
mov dx, 3C8h
mov al, 0
out dx, al
inc dx
@@copy_color:
push cx
; Read the palette
mov ax, 3F00h
mov bx, [GAPI_globe_file_handle]
mov cx, 4
mov dx, offset GPAI_globe_palette_clr
int 21h
jc @@ret
mov si, offset GPAI_globe_palette_clr
mov dx, 3C9h
mov al, [si+2] ; Red
shr al,2 ; divide by 4 (because of 6 bit color)
out dx,al
mov al, [si+1] ; Green.
shr al,2 ; divide by 4 (because of 6 bit color)
out dx,al
mov al, [si] ; Blue.
shr al,2 ; divide by 4 (because of 6 bit color)
out dx,al
pop cx
loop @@copy_color
mov ax, 0
@@ret:
pop si
pop dx
pop cx
pop bx
ret
endp LoadSpriteGlobePalette
; #####################################
;
; Function Name: FillScreen (PUBLIC)
; Description: Fill the screen with a single color
; Input:
; - [STACK] The color to fill the screen with
; Output: None
;
; #####################################
GAPI_ARG_color equ [byte bp+4]
proc FillScreen
push bp
mov bp, sp
push ax
push es
push di
push ax
push cx
; Make ES point to the video memory
mov ax, 0A000h
mov es, ax
; Loop over all pixels and set the color
mov cx, 320*200
@@loop:
mov al, GAPI_ARG_color
mov [es:di], al
inc di
loop @@loop
@@ret:
pop cx
pop ax
pop di
pop es
pop ax
mov sp, bp
pop bp
ret 2
endp FillScreen
; #####################################
;
; Function Name: CheckPointAndBMPCollision (PUBLIC)
; Description: Check if a point has colided with a sprite
; Input:
; - [STACK] The X position of the point
; - [STACK] The Y position of the point
; - [STACK] The X position of the sprite
; - [STACK] The Y position of the sprite
; - [STACK] The offset to the variable that stores the sprite data
; Output:
; - [REG] AX = 0 if no error, otherwise error code
; - [REG] DI = 1 if the point has colided with the sprite, otherwise 0
; Notes: The sprite data will be in the following format: x,y,w,h,byte offset
;
; #####################################
GAPI_ARG_point_x equ [word bp+12]
GAPI_ARG_point_y equ [word bp+10]
GAPI_ARG_sprite_x equ [word bp+8]
GAPI_ARG_sprite_y equ [word bp+6]
GAPI_ARG_sprite_data equ [word bp+4]
GAPI_LOC_spriteX equ [word bp-2]
GAPI_LOC_spriteY equ [word bp-4]
GAPI_LOC_spriteW equ [word bp-6]
GAPI_LOC_spriteH equ [word bp-8]
GAPI_LOC_spriteOffLOW equ [word bp-10]
GAPI_LOC_spriteOffHIGH equ [word bp-12]
GAPI_LOC_point_offset equ [word bp-14]
proc CheckPointAndBMPCollision
push bp
mov bp, sp
sub sp, 14
push bx
push cx
push dx
push si
; Calculate the video memory index for point
mov ax, GAPI_ARG_point_y
cmp ax, 0
je @@skp
dec ax
@@skp:
mov bx, 320
xor dx, dx
mul bx
add ax, GAPI_ARG_point_x
mov GAPI_LOC_point_offset, ax
; Get the sprite data
xor bx, bx
mov si, GAPI_ARG_draw_data
mov bx, [word ds:si]
mov GAPI_LOC_spriteX, bx
mov bx, [word ds:si+2]
mov GAPI_LOC_spriteY, bx
mov bx, [word ds:si+4]
mov GAPI_LOC_spriteW, bx
mov bx, [word ds:si+6]
mov GAPI_LOC_spriteH, bx
mov bx, [word ds:si+8]
mov GAPI_LOC_spriteOffHIGH, bx
mov bx, [word ds:si+10]
mov GAPI_LOC_spriteOffLOW, bx
; Calculate the video memory index for sprite
mov ax, GAPI_ARG_sprite_y
mov bx, 320
xor dx, dx
mul bx
mov di, ax
mov ax, GAPI_LOC_spriteH
dec ax
xor dx, dx
mul bx
add di, ax
add di, GAPI_ARG_sprite_x
; Advance the file pointer to the sprite data
push [GAPI_globe_file_handle]
push GAPI_LOC_spriteOffHIGH
push GAPI_LOC_spriteOffLOW
call _SetFilePointer
cmp ax, 0
jne @@ret
mov cx, GAPI_LOC_spriteH
@@line_loop:
push cx
; Read the line
xor ax, ax
mov ah, 3Fh
mov bx, [GAPI_globe_file_handle]
mov cx, [GAPI_globe_width]
mov dx, offset GAPI_curr_bmp_line
int 21h
jc @@ret
; Go through the line
mov cx, GAPI_LOC_spriteW
mov bx, offset GAPI_curr_bmp_line
@@col_loop:
xor ax, ax
; Get the color of the current pixel
mov al, [byte ds:bx]
; Check if the color is the transparent color
cmp al, [GPAI_transparent_clr_id]
je @@skip_touch
; Check if the point has colided with the sprite
mov ax, GAPI_LOC_point_offset
cmp ax, di
je @@colided
@@skip_touch:
inc bx
inc di
loop @@col_loop
; Move to the next line (Screen)
sub di, 320 ; skip currently drawn line and move to the next line
sub di, GAPI_LOC_spriteW
pop cx
loop @@line_loop
mov di, 0
mov ax, 0
jmp @@ret
@@colided:
mov di, 1
mov ax, 0
jmp @@ret
@@ret:
pop si
pop dx
pop cx
pop bx
mov sp, bp
pop bp
ret 10
endp CheckPointAndBMPCollision
; #####################################
;
; Function Name: CheckLineAndBMPCollision (PUBLIC)
; Description: Check if a line has colided with a sprite
; Input:
; - [STACK] The x1 position of the line
; - [STACK] The y1 position of the line
; - [STACK] The x2 position of the line
; - [STACK] The y2 position of the line
; - [STACK] The width of the line
; - [STACK] The sprite X position
; - [STACK] The sprite Y position
; - [STACK] The offset to the variable that stores the sprite data
; Output:
; - [REG] DI = 1 if the point has colided with the sprite, otherwise 0
;
; #####################################
GAPI_ARG_x1 equ [word bp+18]
GAPI_ARG_y1 equ [word bp+16]
GAPI_ARG_x2 equ [word bp+14]
GAPI_ARG_y2 equ [word bp+12]
GAPI_ARG_width equ [word bp+10]
GAPI_ARG_sprite_x equ [word bp+8]
GAPI_ARG_sprite_y equ [word bp+6]
GAPI_ARG_sprite_data equ [word bp+4]
GAPI_LOC_deltX equ [word bp-2]
GAPI_LOC_deltY equ [word bp-4]
GAPI_LOC_slope equ [word bp-6]
GAPI_LOC_error equ [word bp-8]
GAPI_LOC_y equ [word bp-10]
GAPI_LOC_x equ [word bp-12]
GAPI_LOC_ystep equ [word bp-14]
proc CheckLineAndBMPCollision
; Taken from https://github.com/anushaihalapathirana/Bresenham-line-drawing-algorithm/blob/master/src/index.js
push bp
mov bp, sp
sub sp, 14
push ax
push bx
push cx
push dx
push es
; dx = abs(x2 - x1)
mov ax, GAPI_ARG_x2
sub ax, GAPI_ARG_x1
push ax
call _AbsNum
mov GAPI_LOC_deltX, di
; dy = abs(y2 - y1)
mov ax, GAPI_ARG_y2
sub ax, GAPI_ARG_y1
push ax
call _AbsNum
mov GAPI_LOC_deltY, di
; GAPI_LOC_slope = dy > dx
mov ax, GAPI_LOC_deltY
cmp ax, GAPI_LOC_deltX
jg @@dyGreater
mov GAPI_LOC_slope, 0
jmp @@cont
@@dyGreater:
mov GAPI_LOC_slope, 1
@@cont:
; if GAPI_LOC_slope
mov ax, GAPI_LOC_slope
cmp ax, 0
je @@skip1
; x1, y1 = y1, x1
; x2, y2 = y2, x2
mov ax, GAPI_ARG_x1
mov bx, GAPI_ARG_y1
mov GAPI_ARG_x1, bx
mov GAPI_ARG_y1, ax
mov ax, GAPI_ARG_x2
mov bx, GAPI_ARG_y2
mov GAPI_ARG_x2, bx
mov GAPI_ARG_y2, ax
@@skip1:
; if x1 > x2
mov ax, GAPI_ARG_x1
cmp ax, GAPI_ARG_x2
jle @@skip2
; x1, x2 = x2, x1
; y1, y2 = y2, y1
mov ax, GAPI_ARG_x1
mov bx, GAPI_ARG_x2
mov GAPI_ARG_x1, bx
mov GAPI_ARG_x2, ax
mov ax, GAPI_ARG_y1
mov bx, GAPI_ARG_y2
mov GAPI_ARG_y1, bx
mov GAPI_ARG_y2, ax
@@skip2:
; dx = abs(x2 - x1)
mov ax, GAPI_ARG_x2
sub ax, GAPI_ARG_x1
push ax
call _AbsNum
mov GAPI_LOC_deltX, di
; dy = abs(y2 - y1)
mov ax, GAPI_ARG_y2
sub ax, GAPI_ARG_y1
push ax
call _AbsNum
mov GAPI_LOC_deltY, di
; GAPI_LOC_error = dx / 2 (round)
mov ax, GAPI_LOC_deltX
shr ax, 1
mov GAPI_LOC_error, ax
; y = y1
mov ax, GAPI_ARG_y1
mov GAPI_LOC_y, ax
; GAPI_LOC_ystep = 1 if y1 < y2 else -1
mov GAPI_LOC_ystep, 0
mov ax, GAPI_ARG_y1
cmp ax, GAPI_ARG_y2
je @@cont2
jl @@y1LessY2
mov GAPI_LOC_ystep, -1
jmp @@cont2
@@y1LessY2:
mov GAPI_LOC_ystep, 1
@@cont2:
; for x in range(x1, x2 + 1)
mov ax, GAPI_ARG_x1
mov cx, GAPI_LOC_deltX
inc cx
mov GAPI_LOC_x, ax
@@forX:
; coord = (y, x) if GAPI_LOC_slope else (x, y) -> draw
cmp GAPI_LOC_slope, 0
je @@c1
; Check if the current point has colided with the sprite
push GAPI_LOC_y
push GAPI_LOC_x
push GAPI_ARG_width
push GAPI_ARG_width
push GAPI_ARG_sprite_x
push GAPI_ARG_sprite_y
push GAPI_ARG_sprite_data
call CheckRectAndBMPCollision
cmp di, 0
je @@cont3
mov di, 1
jmp @@ret
jmp @@cont3
@@c1:
; Check if the current point has colided with the sprite
push GAPI_LOC_x
push GAPI_LOC_y
push GAPI_ARG_width
push GAPI_ARG_width
push GAPI_ARG_sprite_x
push GAPI_ARG_sprite_y
push GAPI_ARG_sprite_data
call CheckRectAndBMPCollision
cmp di, 0
je @@cont3
mov di, 1
jmp @@ret
@@cont3:
; GAPI_LOC_error -= dy
mov ax, GAPI_LOC_error
sub ax, GAPI_LOC_deltY
mov GAPI_LOC_error, ax
; if GAPI_LOC_error < 0
mov ax, GAPI_LOC_error
cmp ax, 0
jge @@skip3
; y += GAPI_LOC_ystep
mov ax, GAPI_LOC_y
cmp GAPI_LOC_ystep, 1
jl @@yStepNeg
inc ax
jmp @@cont4
@@yStepNeg:
dec ax
@@cont4:
mov GAPI_LOC_y, ax
; GAPI_LOC_error += dx
mov ax, GAPI_LOC_error
add ax, GAPI_LOC_deltX