; Sample of adding a shape of triangle drawn on a graphics screen
;----------------------------------------------------------------
; 1. Copied the graphicsmouse, drawsq proc and te drawline + changes as follows:

; Changes made to the original: drawline - made the line length a parameter, so I could
;                                          use it also for the triangle. That's why I added
;                                          also the push bp, move b,sp and pop bp at the end
;                                          (our mechanism of transferring parameters)
;
; 2. Added: drawtriangle which includes calling to:  drawdiagright,  drawdiagleft and drawline (new)
;
;    Of course I could have made the drawdiag one proc which receives another parameter for direction
;    (going left or going right, saving me from writing 2 procs one for left and the other for right,
;    but I wanted to be more clear with the example.
;
;  Pay attention that in both drawtriangle and drawsq I use cx and dx as te starting coordinates (x,y)
;  for drawing the shape (upper-left for the square and the top tip of the triangle), this is why I
;  save them before and restore after (good habit) lines 69-72 , 85-88 in drawsq  99-102 , 124-127 in
;  drawtriangle. 
;
;-----------------------------------------------------------------------------------------------------

IDEAL
MODEL small
STACK 100h
;-----------------------------------------------------------------------------------------------------
DATASEG
red           equ  4 
pink          equ  13
sqsz          equ  10 
trside        equ  15
x             dw    ?
y             dw    ? 
xtr           dw    ?                    ; Starting x-coordinate for the triangle top 
ytr           dw    ?                    ; Starting y-coordinate for the triangle top 
;-----------------------------------------------------------------------------------------------------
CODESEG
proc          graphicsmouse              ; Enter graphics mode, initial and show the mouse
              push ax
              mov  ax,13h
              int  10h             
              mov  ax,0h
              int  33h
              mov  ax,1h
              int  33h 
              pop  ax
              ret 
endp          graphicsmouse
;-----------------------------------------------------------------------------------------------------
proc          drawline                     ;draw individual line length of the parameter starting at
                                           ;location (cx,dx)  Xpixel = cx  Ypixel = dx
              push bp
              mov  bp,sp               
              push bx
              mov  bx,[bp+4]               ;line length (added to the original drawline)
nextpix:      mov  ah,0ch  
              int  10h 
              inc  cx
              dec  bx
              cmp  bx,0
              jnz  nextpix
              pop  bx
              pop  bp
              ret  2  
endp          drawline  
;-----------------------------------------------------------------------------------------------------             
proc          drawsq                       ; 1 parameter - color
              push bp
              mov  bp,sp 
;Save registers state               
              push ax
              push bx
              push cx
              push dx               
              mov  al,[bp+4]               ; color
              mov  bx,sqsz
              mov  cx,[x]
              mov  dx,[y]
lineloop:     push sqsz              
              call drawline
              inc  dx
              mov  cx,[x]
              dec  bx
              cmp  bx,0
              jnz  lineloop                ;loop on lines, creates the square.
;Restore registers
			  pop  dx
			  pop  cx
			  pop  bx
			  pop  ax 
			  pop  bp
			  ret  2
endp          drawsq
;-----------------------------------------------------------------------------------------------------
proc          drawtriangle  
; does that by drawing a diagonal line to the right-down of the starting pixel, than a diagonal
; to te left-bottom, and finally the bottom closing horizontal line.
              push bp
              mov  bp,sp 
;Save registers state               
              push ax
              push bx
              push cx
              push dx               
              mov  al,[bp+4]               ; color
              mov  bx,trside 
              mov  cx,[xtr]                ; starting pixel for the line is in (cx,dx).
              mov  dx,[ytr]
              push trside
              call drawdiagright
              mov  cx,[xtr]                ; starting pixel for the line is in (cx,dx).
              mov  dx,[ytr]
              push trside
              call drawdiagleft
; calculate the starting pixel for the horizontal line closing the triangle               
              mov  cx,[xtr]
              sub  cx,trside
              mov  dx,[ytr]
              add  dx,trside
              mov  ax,trside
              add  ax,ax                    ; The horizontal closing line is double the diagonal size. 
              push ax
              mov  al,[bp+4]                ; color (again), because ax was destroyed by the previous              
              call drawline                 ; few lines, so we put the color back to al.
			  pop  dx
			  pop  cx
			  pop  bx
			  pop  ax 
			  pop  bp                           
              ret  2                           
endp          drawtriangle
;-----------------------------------------------------------------------------------------------------
proc          drawdiagright
              push bp
              mov  bp,sp 
              push ax
              mov  bx,[bp+4]               ; size of diagonal.
nextrpix:     mov  ah,0ch  
              int  10h 
              inc  cx
              inc  dx
              dec  bx
              cmp  bx,0
              jnz  nextrpix
              pop  ax
              pop  bp
              ret  2                                           
endp          drawdiagright  
;-----------------------------------------------------------------------------------------------------
proc          drawdiagleft
              push bp
              mov  bp,sp
              push ax 
              mov  bx,[bp+4]
nextlpix:     mov  ah,0ch  
              int  10h 
              dec  cx
              inc  dx
              dec  bx
              cmp  bx,0
              jnz  nextlpix
              pop  ax 
              pop  bp
              ret  2                                           
endp          drawdiagleft  
;-----------------------------------------------------------------------------------------------------
start:
;       Simply drawing one square and one rectangle in screen places I chose arbitrarily.
;
              mov ax, @data
              mov ds, ax
              mov [x], 40
              mov [y], 80
              call graphicsmouse
              push red 
              call drawsq               ;Draw a square with x,y top-left pixel , size sqsz.
              push pink
              mov [xtr], 100
              mov [ytr], 150              
              call drawtriangle         ;Draw a triangle with its top tip at xtr,ytr
exit:
              mov ax, 4c00h
              int 21h
END           start 