--- /dev/null
+;-----------------------------------------------------------\r
+;\r
+; MXPI.ASM - Stretch image\r
+; Copyright (c) 1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN PRO\r
+NOWARN RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC mxStretchImage\r
+\r
+EXTRN subClipBox : NEAR\r
+\r
+MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
+ ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
+\r
+EXTRN mx_VideoSegment : WORD\r
+EXTRN mx_BytesPerLine : WORD\r
+\r
+mxTable LABEL WORD ; Raster ops\r
+ DW subMove\r
+ DW subAnd\r
+ DW subOr\r
+ DW subXor\r
+ DW subTrans\r
+ DW subAdd\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Stretches and copies a "raw" image from memory to screen.\r
+;\r
+; Input:\r
+; Image = pointer to image\r
+; X, Y = coordinates of destination\r
+; Width = width of image in pixels\r
+; Height = height of image in pixels\r
+; NewWidth = new width of image in pixels\r
+; NewHeight = new height of image in pixels\r
+; Op = raster op (OP_xxx)\r
+; Output:\r
+; none\r
+;\r
+mxStretchImage PROC FAR\r
+ ARG Op:WORD, \\r
+ NewHeight:WORD, \\r
+ NewWidth:WORD, \\r
+ Height:WORD, \\r
+ Width:WORD, \\r
+ Y:WORD, \\r
+ X:WORD, \\r
+ Image:DWORD = ARG_SIZE\r
+ LOCAL PixelOffset:WORD, \\r
+ MoveFunction:WORD, \\r
+ ReadPlane:BYTE, \\r
+ OpInfo:BYTE, \\r
+ WidthStep:DWORD, \\r
+ HeightStep:DWORD, \\r
+ ImageLo:WORD, \\r
+ WritePlane:BYTE = AUTO_SIZE\r
+ ASSUME ds:NOTHING\r
+ .enter AUTO_SIZE\r
+ .push ds, si, es, di\r
+\r
+; Get width stretch factor\r
+ IF USE386 EQ TRUE\r
+ movzx edx, [Width]\r
+ xor eax, eax\r
+ movzx ebx, [NewWidth]\r
+ shl ebx, 16\r
+ idiv ebx\r
+ mov [WidthStep], eax\r
+ ELSE\r
+ xor dx, dx ; Width stretch factor\r
+ mov ax, [Width]\r
+ mov bx, [NewWidth]\r
+ div bx\r
+ mov WORD PTR WidthStep[2], ax\r
+ xor ax, ax\r
+ div bx\r
+ mov WORD PTR WidthStep[0], ax\r
+ ENDIF\r
+; Get height stretch factor\r
+ IF USE386 EQ TRUE\r
+ movzx edx, [Height]\r
+ xor eax, eax\r
+ movzx ebx, [NewHeight]\r
+ shl ebx, 16\r
+ idiv ebx\r
+ mov [HeightStep], eax\r
+ ELSE\r
+ xor dx, dx\r
+ mov ax, [Height]\r
+ mov bx, [NewHeight]\r
+ div bx\r
+ mov WORD PTR HeightStep[2], ax\r
+ xor ax, ax\r
+ div bx\r
+ mov WORD PTR HeightStep[0], ax\r
+ ENDIF\r
+\r
+; Clip image\r
+ mov bx, [X]\r
+ mov ax, [Y]\r
+ mov cx, [NewWidth]\r
+ mov dx, [NewHeight]\r
+ call subClipBox\r
+ jc @@Exit ; Full clipped\r
+ mov [NewWidth], cx\r
+ mov [NewHeight], dx\r
+ sub [X], bx\r
+ sub [Y], ax\r
+\r
+; Get pixel address\r
+ mul [mx_BytesPerLine]\r
+ mov di, bx\r
+ shr di, 1\r
+ shr di, 1\r
+ add di, ax\r
+ mov [PixelOffset], di\r
+ mov es, [mx_VideoSegment] ; ES:DI points to pixel\r
+ and bl, 03h\r
+ mov [ReadPlane], bl ; Set read plane\r
+ mov cl, bl\r
+ mov al, 00010001b\r
+ shl al, cl\r
+ mov [WritePlane], al ; Set write plane\r
+\r
+; Relocate image origin if previously clipped\r
+ mov ax, [Y]\r
+ test ax, ax\r
+ jz @@OriginYDone\r
+ IF USE386 EQ TRUE\r
+ shl eax, 16\r
+ imul [HeightStep]\r
+ mov ax, [Width]\r
+ mul dx\r
+ ELSE\r
+ mov bx, ax\r
+ mul WORD PTR HeightStep[0]\r
+ mov cx, dx\r
+ mov ax, bx\r
+ mul WORD PTR HeightStep[2]\r
+ add ax, cx\r
+ mul [Width]\r
+ ENDIF\r
+ add WORD PTR [Image], ax\r
+@@OriginYDone:\r
+ mov ax, [X]\r
+ test ax, ax\r
+ jz @@OriginXDone\r
+ IF USE386 EQ TRUE\r
+ shl eax, 16\r
+ imul [WidthStep]\r
+ add WORD PTR [Image], dx\r
+ ELSE\r
+ mov bx, ax\r
+ mul WORD PTR WidthStep[0]\r
+ mov cx, dx\r
+ mov ax, bx\r
+ mul WORD PTR WidthStep[2]\r
+ add ax, cx\r
+ add WORD PTR [Image], ax\r
+ ENDIF\r
+@@OriginXDone:\r
+ mov ax, WORD PTR HeightStep[2]\r
+ mul [Width]\r
+ mov WORD PTR HeightStep[2], ax\r
+\r
+; Install move function\r
+ mov bx, [Op]\r
+ mov [OpInfo], bh ; Remember additional info if needed\r
+ xor bh, bh\r
+ cmp bl, OP_ADD\r
+ jbe @@SetMoveFunction\r
+ xor bl, bl\r
+@@SetMoveFunction:\r
+ shl bx, 1\r
+ mov ax, mxTable[bx]\r
+ mov [MoveFunction], ax\r
+\r
+; Put image\r
+ mov ds, WORD PTR Image[2]\r
+ xor ax, ax\r
+ mov [ImageLo], ax\r
+@@Loop:\r
+ mov si, WORD PTR Image[0] ; Get pointer to image\r
+ mov ah, [WritePlane]\r
+ and ah, 0Fh\r
+ mov al, 02h\r
+ mov dx, TS\r
+ out dx, ax ; Select write plane\r
+ mov ah, [ReadPlane]\r
+ and ah, 03h\r
+ mov al, 04h\r
+ mov dx, GDC\r
+ out dx, ax ; Select read plane\r
+ mov cx, [NewHeight]\r
+ mov di, [PixelOffset] ; ES:DI points to video memory\r
+ mov ah, [OpInfo] ; Additional raster op info\r
+ xor bx, bx\r
+ mov dx, [mx_BytesPerLine]\r
+ call [MoveFunction] ; Draw column\r
+ inc [ReadPlane] ; Next read plane\r
+ rol [WritePlane], 1 ; Next write plane\r
+ adc [PixelOffset], 0 ; Update video offset if needed\r
+ mov dx, WORD PTR WidthStep[0]\r
+ mov ax, WORD PTR WidthStep[2]\r
+ add [ImageLo], dx\r
+ adc WORD PTR Image[0], ax ; Next image column\r
+ dec [NewWidth]\r
+ jnz @@Loop ; Repeat for all columns\r
+\r
+@@Exit:\r
+ xor ax, ax\r
+ .pop ds, si, es, di\r
+ .leave ARG_SIZE\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Move functions, on entry:\r
+; AH = additional raster op info (e.g. transparent color)\r
+; BX = 0,\r
+; CX = pixel count,\r
+; DX = mx_BytesPerLine.\r
+;\r
+subMove PROC NEAR\r
+@@Loop: mov al, ds:[si]\r
+ mov es:[di], al\r
+ add di, dx\r
+ dec cx\r
+ jz @@Exit\r
+ add si, WORD PTR HeightStep[2]\r
+ add bx, WORD PTR HeightStep[0]\r
+ jnc @@Loop\r
+ add si, [Width]\r
+ jmp @@Loop\r
+@@Exit: ret\r
+subMove ENDP\r
+;\r
+subAnd PROC NEAR\r
+@@Loop: mov al, ds:[si]\r
+ and es:[di], al\r
+ add di, dx\r
+ dec cx\r
+ jz @@Exit\r
+ add si, WORD PTR HeightStep[2]\r
+ add bx, WORD PTR HeightStep[0]\r
+ jnc @@Loop\r
+ add si, [Width]\r
+ jmp @@Loop\r
+@@Exit: ret\r
+subAnd ENDP\r
+;\r
+subOr PROC NEAR\r
+@@Loop: mov al, ds:[si]\r
+ or es:[di], al\r
+ add di, dx\r
+ dec cx\r
+ jz @@Exit\r
+ add si, WORD PTR HeightStep[2]\r
+ add bx, WORD PTR HeightStep[0]\r
+ jnc @@Loop\r
+ add si, [Width]\r
+ jmp @@Loop\r
+@@Exit: ret\r
+subOr ENDP\r
+;\r
+subXor PROC NEAR\r
+@@Loop: mov al, ds:[si]\r
+ xor es:[di], al\r
+ add di, dx\r
+ dec cx\r
+ jz @@Exit\r
+ add si, WORD PTR HeightStep[2]\r
+ add bx, WORD PTR HeightStep[0]\r
+ jnc @@Loop\r
+ add si, [Width]\r
+ jmp @@Loop\r
+@@Exit: ret\r
+subXor ENDP\r
+;\r
+subTrans PROC NEAR\r
+@@Loop: mov al, ds:[si]\r
+ cmp al, ah\r
+ je @@Skip\r
+ mov es:[di], al\r
+@@Skip:\r
+ add di, dx\r
+ dec cx\r
+ jz @@Exit\r
+ add si, WORD PTR HeightStep[2]\r
+ add bx, WORD PTR HeightStep[0]\r
+ jnc @@Loop\r
+ add si, [Width]\r
+ jmp @@Loop\r
+@@Exit: ret\r
+subTrans ENDP\r
+;\r
+subAdd PROC NEAR\r
+@@Loop: mov al, ds:[si]\r
+ add es:[di], al\r
+ add di, dx\r
+ dec cx\r
+ jz @@Exit\r
+ add si, WORD PTR HeightStep[2]\r
+ add bx, WORD PTR HeightStep[0]\r
+ jnc @@Loop\r
+ add si, [Width]\r
+ jmp @@Loop\r
+@@Exit: ret\r
+subAdd ENDP\r
+\r
+mxStretchImage ENDP\r
+\r
+MX_TEXT ENDS\r
+END\r