]> 4ch.mooo.com Git - 16.git/blobdiff - 16/x_/mxcl.asm
wwww
[16.git] / 16 / x_ / mxcl.asm
diff --git a/16/x_/mxcl.asm b/16/x_/mxcl.asm
new file mode 100755 (executable)
index 0000000..aaa0bac
--- /dev/null
@@ -0,0 +1,151 @@
+;-----------------------------------------------------------\r
+;\r
+; MXCL.ASM - Bresenham circle\r
+; Copyright (c) 1993,1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN    PRO\r
+NOWARN  RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC  mxCircle\r
+\r
+MX_TEXT         SEGMENT USE16 PARA PUBLIC 'CODE'\r
+                ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
+\r
+EXTRN   mx_BytesPerLine : WORD\r
+EXTRN   mx_VideoSegment : WORD\r
+EXTRN   mx_ClipX1       : WORD\r
+EXTRN   mx_ClipY1       : WORD\r
+EXTRN   mx_ClipX2       : WORD\r
+EXTRN   mx_ClipY2       : WORD\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Draws a circle using the Bresenham algorithm.\r
+;\r
+; Input:\r
+;       XC, YC  = center coordinates\r
+;       Radius  = circle radius\r
+;       Color   = circle color\r
+; Output:\r
+;       none\r
+; Note:\r
+;       computes only points in the first octant, all other\r
+;       points are obtained by symmetry.\r
+;\r
+mxCircle        PROC FAR\r
+        ARG     Color:BYTE:2,           \\r
+                Radius:WORD,            \\r
+                YC:WORD,                \\r
+                XC:WORD                 = ARG_SIZE\r
+        LOCAL   Delta:WORD              = AUTO_SIZE\r
+        .enter  AUTO_SIZE\r
+        .push   ds, si, di\r
+\r
+        xor     si, si                  ; X\r
+        mov     di, [Radius]            ; Y\r
+        mov     ax, 3\r
+        sub     ax, di\r
+        sub     ax, di\r
+        mov     [Delta], ax             ; Delta = 3-R*2\r
+\r
+        mov     ds, [mx_VideoSegment]\r
+\r
+@@Loop:\r
+        cmp     si, di                  ;\r
+        jg      @@Done                  ; Exit when X > Y\r
+; Draw points\r
+        mov     ax, si\r
+        mov     bx, di\r
+        call    @@subPutPixel\r
+        mov     ax, si\r
+        neg     ax\r
+        mov     bx, di\r
+        call    @@subPutPixel\r
+        mov     ax, si\r
+        mov     bx, di\r
+        neg     bx\r
+        call    @@subPutPixel\r
+        mov     ax, si\r
+        neg     ax\r
+        mov     bx, di\r
+        neg     bx\r
+        call    @@subPutPixel\r
+        mov     ax, di\r
+        mov     bx, si\r
+        call    @@subPutPixel\r
+        mov     ax, di\r
+        neg     ax\r
+        mov     bx, si\r
+        call    @@subPutPixel\r
+        mov     ax, di\r
+        mov     bx, si\r
+        neg     bx\r
+        call    @@subPutPixel\r
+        mov     ax, di\r
+        neg     ax\r
+        mov     bx, si\r
+        neg     bx\r
+        call    @@subPutPixel\r
+; Moves coordinates to next point\r
+        mov     ax, [Delta]\r
+        test    ax, ax\r
+        jl      @@Next\r
+        mov     ax, di\r
+        .shl    ax, 2\r
+        sub     ax, 4\r
+        sub     [Delta], ax\r
+        dec     di\r
+@@Next:\r
+        mov     ax, si\r
+        .shl    ax, 2\r
+        add     ax, 6\r
+        add     [Delta], ax\r
+        inc     si\r
+        jmp     @@Loop\r
+\r
+@@Done:\r
+        xor     ax, ax\r
+        .pop    ds, si, di\r
+        .leave  ARG_SIZE\r
+\r
+;---------------------------------------\r
+; Put pixel function.\r
+; Input:\r
+;       BX      = X coordinate (relative to center)\r
+;       AX      = Y coordinate (relative to center)\r
+;       DS      = video segment\r
+@@subPutPixel:\r
+        add     bx, [XC]                ; Get absolute coordinates\r
+        add     ax, [YC]\r
+\r
+        cmp     bx, [mx_ClipX1]         ; Clip pixel\r
+        jl      @@subExit\r
+        cmp     bx, [mx_ClipX2]\r
+        jg      @@subExit\r
+        cmp     ax, [mx_ClipY1]\r
+        jl      @@subExit\r
+        cmp     ax, [mx_ClipY2]\r
+        jg      @@subExit\r
+\r
+        mul     [mx_BytesPerLine]       ; Get pixel offset\r
+        mov     cx, bx                  ; Save X coordinate\r
+        .shr    bx, 2\r
+        add     bx, ax                  ; DS:BX = pixel offset\r
+\r
+        and     cl, 3                   ; Set write plane\r
+        mov     ax, 0102h\r
+        shl     ah, cl\r
+        mov     dx, TS\r
+        out     dx, ax\r
+\r
+        mov     al, [Color]             ; Write pixel\r
+        mov     ds:[bx], al\r
+\r
+@@subExit:\r
+        retn\r
+mxCircle        ENDP\r
+\r
+MX_TEXT         ENDS\r
+END\r