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