]> 4ch.mooo.com Git - 16.git/blobdiff - 16/xw/mxcr.asm
wwww
[16.git] / 16 / xw / mxcr.asm
diff --git a/16/xw/mxcr.asm b/16/xw/mxcr.asm
new file mode 100755 (executable)
index 0000000..ca1fa7b
--- /dev/null
@@ -0,0 +1,380 @@
+;-----------------------------------------------------------\r
+;\r
+; MXCR.ASM - Clip functions\r
+; Copyright (c) 1993,1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN    PRO\r
+NOWARN  RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC  mxSetSysClipRegion\r
+PUBLIC  mxGetClipRegion\r
+PUBLIC  mxSetClipRegion\r
+PUBLIC  mxSetClip\r
+PUBLIC  mxGetClip\r
+\r
+PUBLIC  subClipBox\r
+PUBLIC  subClipImage\r
+\r
+PUBLIC  mx_ClipX1\r
+PUBLIC  mx_ClipY1\r
+PUBLIC  mx_ClipX2\r
+PUBLIC  mx_ClipY2\r
+\r
+MX_TEXT         SEGMENT USE16 PARA PUBLIC 'CODE'\r
+                ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
+\r
+EXTRN   mx_CodeSegment  : WORD\r
+\r
+mx_ClipX1       DW      ?               ; Clip coordinates\r
+mx_ClipY1       DW      ?\r
+mx_ClipX2       DW      ?\r
+mx_ClipY2       DW      ?\r
+\r
+mx_SysClipX1    DW      ?               ; System clip coordinates\r
+mx_SysClipY1    DW      ?               ; (active when mx_ClipStatus is FALSE)\r
+mx_SysClipX2    DW      ?\r
+mx_SysClipY2    DW      ?\r
+\r
+mx_UserClipX1   DW      ?               ; User clip coordinates\r
+mx_UserClipY1   DW      ?               ; (active when mx_ClipStatus is TRUE)\r
+mx_UserClipX2   DW      ?\r
+mx_UserClipY2   DW      ?\r
+\r
+mx_ClipStatus   DB      ?\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Toggles clipping between user and system regions.\r
+;\r
+; Input:\r
+;       ClipStatus      = TRUE (FALSE) to enable (disable) clipping\r
+; Output:\r
+;       AX      = old clip status\r
+;\r
+mxSetClip       PROC    FAR\r
+        ARG     ClipStatus:BYTE:2       = ARG_SIZE\r
+        ASSUME  ds:NOTHING\r
+        .enter  0\r
+        .push   ds\r
+        mov     ds, [mx_CodeSegment]\r
+        ASSUME  ds:MX_TEXT\r
+\r
+        mov     ax, [mx_UserClipX1]\r
+        mov     bx, [mx_UserClipY1]\r
+        mov     cx, [mx_UserClipX2]\r
+        mov     dx, [mx_UserClipY2]\r
+        cmp     [ClipStatus], TRUE\r
+        je      @@Done\r
+        mov     ax, [mx_SysClipX1]\r
+        mov     bx, [mx_SysClipY1]\r
+        mov     cx, [mx_SysClipX2]\r
+        mov     dx, [mx_SysClipY2]\r
+@@Done:\r
+        mov     [mx_ClipX1], ax\r
+        mov     [mx_ClipY1], bx\r
+        mov     [mx_ClipX2], cx\r
+        mov     [mx_ClipY2], dx\r
+\r
+        mov     al, [ClipStatus]\r
+        xchg    al, [mx_ClipStatus]\r
+        xor     ah, ah\r
+\r
+        .pop    ds\r
+        .leave  ARG_SIZE\r
+mxSetClip       ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Returns the current clipping status.\r
+;\r
+; Input:\r
+;       none\r
+; Output:\r
+;       TRUE (FALSE) if clipping enabled (disabled)\r
+;\r
+mxGetClip       PROC    FAR\r
+        ASSUME  ds:NOTHING\r
+        mov     al, [mx_ClipStatus]\r
+        xor     ah, ah\r
+        ret\r
+mxGetClip       ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Sets the system clip region and disables user clipping.\r
+;\r
+; Input:\r
+;       Width   = width in pixels of clip region\r
+;       Height  = height in pixels of clip region\r
+; Output:\r
+;       old clip status.\r
+;\r
+mxSetSysClipRegion      PROC    FAR\r
+        ARG     Height:WORD,            \\r
+                Width:WORD              = ARG_SIZE\r
+        ASSUME  ds:NOTHING\r
+        .enter  0\r
+        .push   ds\r
+        mov     ds, [mx_CodeSegment]\r
+        ASSUME  ds:MX_TEXT\r
+\r
+        xor     ax, ax                  ; Sys clip region always starts at (0,0)\r
+        mov     [mx_SysClipX1], ax\r
+        mov     [mx_SysClipY1], ax\r
+        mov     ax, [Width]\r
+        dec     ax\r
+        mov     [mx_SysClipX2], ax\r
+        mov     ax, [Height]\r
+        dec     ax\r
+        mov     [mx_SysClipY2], ax\r
+\r
+    IF USE286 EQ TRUE\r
+        push    FALSE\r
+    ELSE\r
+        mov     ax, FALSE\r
+        push    ax\r
+    ENDIF\r
+        call    mxSetClip\r
+\r
+        .pop    ds\r
+        .leave  ARG_SIZE\r
+mxSetSysClipRegion      ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Sets the clip region.\r
+;\r
+; Input:\r
+;       X, Y    = coordinates of top left corner of clip region\r
+;       Width   = width in pixels of clip region\r
+;       Height  = height in pixels of clip region\r
+; Output:\r
+;       none (no checking on parameters)\r
+;\r
+mxSetClipRegion PROC    FAR\r
+        ARG     Height:WORD,            \\r
+                Width:WORD,             \\r
+                Y:WORD,                 \\r
+                X:WORD                  = ARG_SIZE\r
+        ASSUME  ds:NOTHING\r
+        .enter  0\r
+        .push   ds\r
+        mov     ds, [mx_CodeSegment]\r
+        ASSUME  ds:MX_TEXT\r
+\r
+        mov     ax, [X]\r
+        mov     [mx_UserClipX1], ax\r
+        mov     ax, [Y]\r
+        mov     [mx_UserClipY1], ax\r
+        mov     ax, [Width]\r
+        add     ax, [X]\r
+        dec     ax\r
+        mov     [mx_UserClipX2], ax\r
+        mov     ax, [Height]\r
+        add     ax, [Y]\r
+        dec     ax\r
+        mov     [mx_UserClipY2], ax\r
+\r
+        mov     al, [mx_ClipStatus]\r
+        cmp     al, TRUE\r
+        jne     @@Exit\r
+        push    ax\r
+        call    mxSetClip\r
+\r
+@@Exit:\r
+        xor     ax, ax\r
+        .pop    ds\r
+        .leave  ARG_SIZE\r
+mxSetClipRegion ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Returns the current user clip region.\r
+;\r
+; Input:\r
+;       X, Y    = pointers to integer coordinates of top left corner\r
+;       Width   = pointer to word width of clip region\r
+;       Height  = pointer to word height of clip region\r
+; Output:\r
+;       AX      = current clip status\r
+;\r
+mxGetClipRegion PROC    FAR\r
+        ARG     Height:DWORD,           \\r
+                Width:DWORD,            \\r
+                Y:DWORD,                \\r
+                X:DWORD                 = ARG_SIZE\r
+        ASSUME  ds:NOTHING\r
+        .enter  0\r
+        .push   es, di\r
+\r
+        mov     ax, [mx_UserClipX1]\r
+        les     di, [X]\r
+        mov     es:[di], ax\r
+        mov     ax, [mx_UserClipY1]\r
+        les     di, [Y]\r
+        mov     es:[di], ax\r
+\r
+        mov     ax, [mx_UserClipX2]\r
+        sub     ax, [mx_UserClipX1]\r
+        inc     ax\r
+        les     di, [Width]\r
+        mov     es:[di], ax\r
+        mov     ax, [mx_UserClipY2]\r
+        sub     ax, [mx_UserClipY1]\r
+        inc     ax\r
+        les     di, [Height]\r
+        mov     es:[di], ax\r
+\r
+        mov     al, [mx_ClipStatus]\r
+        xor     ah, ah\r
+        .pop    es, di\r
+        .leave  ARG_SIZE\r
+mxGetClipRegion ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Internal use: checks the coordinates of a rectangle against\r
+; the active clip region.\r
+; This function assumes that a "raw" image has to be clipped,\r
+; so it returns in SI the number of "raw" bytes to skip if\r
+; X, Y were clipped.\r
+;\r
+; Input:\r
+;       BX, AX  = X, Y coordinates of rectangle (signed)\r
+;       CX      = box width\r
+;       DX      = box height\r
+; Output:\r
+;       CF      = set if rectangle is full clipped\r
+;       BX, AX  = new X, Y coordinates of rectangle\r
+;       CX, DX  = clipped width and height\r
+;       SI      = number of bytes to skip before copying a buffer\r
+;       DI destroyed\r
+;\r
+subClipImage    PROC    NEAR\r
+        ASSUME  ds:NOTHING\r
+        xor     si, si\r
+\r
+; Check clip height\r
+        mov     di, [mx_ClipY1]\r
+        cmp     ax, di\r
+        jge     @@CheckBottom\r
+        sub     di, ax                  ; Number of lines to clip\r
+        sub     dx, di                  ; New box height\r
+        jle     @@Exit\r
+        mov     ax, di\r
+        mov     di, dx                  ; Save box height into DI\r
+        mul     cx                      ; DX:AX = number of bytes to skip\r
+        mov     si, ax\r
+        mov     dx, di                  ; Restore box height\r
+        mov     ax, [mx_ClipY1]\r
+@@CheckBottom:\r
+        mov     di, [mx_ClipY2]\r
+        cmp     ax, di\r
+        jg      @@Exit\r
+        inc     di\r
+        sub     di, dx\r
+        sub     di, ax\r
+        jge     @@DoneHeight            ; None, continue\r
+        add     dx, di                  ; Clip lines\r
+@@DoneHeight:\r
+\r
+; Check clip width\r
+@@CheckLeft:\r
+        mov     di, [mx_ClipX1]\r
+        cmp     bx, di\r
+        jge     @@CheckRight\r
+        sub     di, bx                  ; Number of columns to clip left\r
+        sub     cx, di\r
+        jle     @@Exit\r
+        add     si, di                  ; Update skip count\r
+        mov     bx, [mx_ClipX1]\r
+@@CheckRight:\r
+        mov     di, [mx_ClipX2]\r
+        cmp     bx, di\r
+        jg      @@Exit\r
+        inc     di\r
+        sub     di, bx\r
+        sub     di, cx\r
+        jge     @@DoneWidth             ; None, exit\r
+        add     cx, di                  ; New box width\r
+@@DoneWidth:\r
+\r
+; Set return flag and exit\r
+@@Done:\r
+        clc\r
+        ret\r
+@@Exit:\r
+        stc\r
+        ret\r
+subClipImage    ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Internal use: checks the coordinates of a rectangle against\r
+; the active clip region.\r
+;\r
+; Input:\r
+;       BX, AX  = X, Y coordinates of rectangle (signed)\r
+;       CX      = box width\r
+;       DX      = box height\r
+; Output:\r
+;       CF      = set if rectangle is full clipped\r
+;       BX, AX  = new X, Y coordinates of rectangle\r
+;       CX, DX  = clipped width and height\r
+;       DI destroyed\r
+;\r
+subClipBox      PROC    NEAR\r
+        ASSUME  ds:NOTHING\r
+\r
+; Check clip height\r
+        mov     di, [mx_ClipY1]\r
+        cmp     ax, di\r
+        jge     @@CheckBottom\r
+        sub     di, ax                  ; Number of lines to clip\r
+        sub     dx, di                  ; New box height\r
+        jle     @@Exit\r
+        mov     ax, [mx_ClipY1]\r
+@@CheckBottom:\r
+        mov     di, [mx_ClipY2]\r
+        cmp     ax, di\r
+        jg      @@Exit\r
+        inc     di\r
+        sub     di, dx\r
+        sub     di, ax                  ; Clipped some point?\r
+        jge     @@DoneHeight            ; No, continue\r
+        add     dx, di                  ; Clip lines (DI is negative)\r
+@@DoneHeight:\r
+\r
+; Check clip width\r
+@@CheckLeft:\r
+        mov     di, [mx_ClipX1]\r
+        cmp     bx, di\r
+        jge     @@CheckRight\r
+        sub     di, bx                  ; Number of columns to clip left\r
+        sub     cx, di\r
+        jle     @@Exit\r
+        mov     bx, [mx_ClipX1]\r
+@@CheckRight:\r
+        mov     di, [mx_ClipX2]\r
+        cmp     bx, di\r
+        jg      @@Exit\r
+        inc     di\r
+        sub     di, bx\r
+        sub     di, cx                  ; Clipped some point?\r
+        jge     @@DoneWidth             ; No, exit\r
+        add     cx, di                  ; New box width (DI is negative)\r
+@@DoneWidth:\r
+\r
+; Set return flag and exit\r
+@@Done:\r
+        clc\r
+        ret\r
+@@Exit:\r
+        stc\r
+        ret\r
+subClipBox      ENDP\r
+\r
+MX_TEXT         ENDS\r
+END\r