locals
.model large,c
.386

.code

extrn virtualvga:dword

public kompasm
public entkompasm
public showpal
public copyvga
public pixel
public putsprite_clipcoord_transparent
public putsprite__clipcoord
public putsprite_clipcoord_
public hline_clip
public lineintern



hline_clip proc far
arg dest:dword,x1:word,x2:word,y:word,farbe:byte

push di
les di,dest

mov ax,y
add ax,es:di+4
cmp ax,0
jl garnicht
cmp ax,es:di+8
jge garnicht
mov y,ax

mov bx,x1
add bx,es:di+2
cmp bx,es:di+6
jge garnicht

mov cx,x2
add cx,es:di+2
cmp cx,0
jl garnicht

cmp bx,0
jge noclip
xor bx,bx
noclip:

cmp cx,es:di+6
jl noclip2
mov cx,es:di+6
dec cx
noclip2:
sub cx,bx

mov ax,es:di+6
mul y
add di,ax
add di,bx
add di,10

mov al,farbe
cld
rep stosb

garnicht:

pop di

ret
hline_clip endp


lineintern proc far
	arg dest:dword,x1:word,y1:word,x2:word,y2:word,breitex:word,farbe:byte
	local yr:byte
	local xr:word
	local ganzzahl:word
	local byteganzzahl:byte
	local zeilenadder:word
	local dirflag:word

	push ds
	push di
	push si

	;es:di auf Startpunkt
	les di,dest
	mov ax,breitex
	mul y1
	add ax,x1
	add di,ax


	mov ax,x2
	cmp ax,x1
	jb falschrum
		;x2>x1
		;xr=x2-x1+1
		;mov ax,x2 ist schon in ax !!!!
		inc ax
		sub ax,x1
		mov xr,ax
		cld													;// Setze DF auf 0
		mov dirflag,1
		jmp nicetoseeyou
	falschrum:
		;x2<x1
		;xr=x1-x2+1
		mov ax,x1
		inc ax
		sub ax,x2
		mov xr,ax
		std													;// Setze DF auf 1
		mov dirflag,-1
	nicetoseeyou:

	mov ax,y1
	cmp ax,y2
	jb ivquadrant
		; IQuadrant
		;yr=y1-y2+1
		;mov ax,y1 ist schon in ax !!!
		inc al
		sub ax,y2
		mov yr,al
		xor bx,bx
		sub bx,breitex
		mov breitex,bx
		jmp cometogether
	ivquadrant:
		;IV Quadrant
		;yr=y2-y1+1
		mov ax,y2
		sub ax,y1
		inc al
		mov yr,al
	cometogether:

;	xor ah,ah 	yr ist schon in ax !!
;	mov al,yr
	cmp ax,xr
	ja norep
		;*********************************************** REP möglich
		;ganzzahl=xr div yr
		mov ax,xr
		xor bh,bh
		mov bl,yr
		xor dx,dx
		div bx
		mov ganzzahl,ax

		;rest=xr mod yr
		mov bh,dl

		;aktrest=0
		xor bl,bl

		;anzahl=xr
		mov dx,xr

		;ah=yr-Rest
		mov ah,yr
		sub ah,bh

		;al=farbe
		mov al,farbe

		;********************************************* Registerbelegung:
		;bh: Rest
		;bl: Aktrest
		;ah: yr - Rest
		;al: Farbe
		;cx: Anzahl zu schreibender Bytes in dieser Zeile
		;dx: Anzahl zu schreibender Bytes gesamt
		again:
			mov cx,ganzzahl
			cmp bl,ah
			jb restzuklein
				inc cx
				sub bl,yr
			restzuklein:
			add bl,bh
			sub dx,cx
			rep stosb
			add di,breitex
			or dx,dx
		jnz again
		jmp fertig


	;*********************************************** Kein REP möglich
	norep:
		;byteganzzahl=yr div xr
		;xor ah,ah  ;yr schon in ax(al)
		;mov al,yr
		mov bx,xr
		div bl		;xr<=yr!!!!!
		mov byteganzzahl,al

		;rest=xr mod yr
		;xor bh,bh xr<=yr => xr<255 !!!
		mov bl,ah

		;aktrest=0
		xor dx,dx

		;anzahl=yr
		mov ah,yr

		;al=farbe
		mov al,farbe

		;ch=0
		xor ch,ch
		;********************************************* Registerbelegung:
		;bx: Rest
		;dx: Aktrest
		;ah: Anzahl zu schreibender Bytes gesamt
		;al: Farbe
		;cl: Anzahl zu schreibender Bytes in dieser Spalte
		dowhile:
			mov cl,byteganzzahl
			add dx,bx
			cmp dx,xr
			jb restzukleinnorep
				sub dx,xr
				inc cl
			restzukleinnorep:
			sub ah,cl
			repeat:
				mov es:[di],al
				add di,breitex
			loop repeat
			add di,dirflag
			or ah,ah
		jnz dowhile

	fertig:
	pop si
	pop di
	pop ds

	ret
lineintern endp




pixel proc far
arg p:dword,x:word,y:word,col:byte

les bx,p

mov ax,x
add ax,es:[bx+2]
mov x,ax

mov ax,y
add ax,es:[bx+4]
mov y,ax

mov ax,es:[bx+6]
imul word ptr y
add ax,x
add bx,ax
add bx,10
mov al,col
mov es:[bx],al
ret
pixel endp



kompasm proc far
arg anzbytes:dword,dest:dword,source:dword
push ds
push si
push di

cld
lds si,source
les di,dest

lodsb
xor ecx,ecx
dec anzbytes
mov bx,offset @endofcompress

@againdot:
mov ah,ds:si
inc si
inc cl
dec anzbytes
cmp ah,al
jne short @compressme
cmp cl,63
je short @compressme
@endofcompress:
cmp anzbytes,0
jnz short @againdot
mov bx,offset @endekompasm
inc cl

@compressme:
cmp cl,2
ja short @realcompressed
cmp al,192
jae short @realcompressed
@agaj:
stosb
loop @agaj
mov al,ah
jmp bx
@realcompressed:
or cl,192
mov es:di,cl
mov es:di+1,al
add di,2
xor cl,cl
mov al,ah
jmp bx

@endekompasm:

sub di,word ptr dest
mov ax,di

pop di
pop si
pop ds
ret
kompasm endp




entkompasm proc far
arg anzbytes:dword,dest:dword,source:dword

push ds
push si
push di

cld
les di,dest
lds si,source

xor ecx,ecx

mov edx,anzbytes

@nextbytes:
mov cl,ds:si
inc si
cmp cl,192
jae short @compressed
mov es:di,cl
inc di
@loopnow:
dec edx
jnz @nextbytes

pop di
pop si
pop ds

ret
entkompasm endp
@compressed:
dec edx
and cl,111111b
mov al,ds:si
inc si
@againselb:
mov es:di,al
inc di
loop @againselb
jmp @loopnow

showpal proc far
arg pal:dword
push ds
push si
xor al,al
mov dx,03c8h
out dx,al
inc dx
lds si,pal
cld
mov cx,768
rep outsb
pop si
pop ds
ret
showpal endp

copyvga proc far
push ds
push si
push di
cld
lds si,ds:virtualvga
add si,10
mov ax,0a000h
mov es,ax
xor di,di

mov bl,200
@@aggainww:
mov cx,128
rep movsw
add di,64
dec bl
jnz @@aggainww

pop di
pop si
pop ds
ret
copyvga endp




;//**********************************************************************
;//**********************************************************************
;//***********************  HIER ALLE MEGA SPRITE ROUTINEN  *************
;//**********************************************************************
;//**********************************************************************
;//**********************************************************************

;//Dieser Block muß defined sein für Aufruf von realspriteputter
r_xpos1 dw 0
r_ypos1 dw 0
r_xpos2 dw 0
r_ypos2 dw 0
r_xanz dw 0
r_yanz dw 0
; ds:si ist source
; es:di ist dest

;//Interne verwendung...
r_sourceadder dw 0
r_destadder dw 0

destclipper proc near
;//** DESTINATION CLIPPING
;//XANZ CLIPPING
mov ax,word ptr es:[di+6]
sub ax,r_xpos2
jle short destclipped
cmp r_xanz,ax
jle short @nc1
mov r_xanz,ax
@nc1:

;//YANZ CLIPPING
mov ax,word ptr es:[di+8]
sub ax,r_ypos2
jle short destclipped
cmp r_yanz,ax
jle short @nc2
mov r_yanz,ax
@nc2:

;//X2 CLIPPING
mov ax,r_xpos2
cmp ax,0
jge short @nc3
sub r_xpos1,ax
add r_xanz,ax
jle short destclipped
mov r_xpos2,0
@nc3:

;//Y2 CLIPPING
mov ax,r_ypos2
cmp ax,0
jge short @nc4
sub r_ypos1,ax
add r_yanz,ax
jle short destclipped
mov r_ypos2,0
@nc4:
clc
retn
destclipped:
stc
retn
destclipper endp


sourceclipper proc near
;//** SOURCE CLIPPING
;//XANZ CLIPPING
mov ax,word ptr [si+6]
sub ax,r_xpos1
jle short sourceclipped
cmp r_xanz,ax
jle short @nc5
mov r_xanz,ax
@nc5:

;//YANZ CLIPPING
mov ax,word ptr [si+8]
sub ax,r_ypos1
jle short sourceclipped
cmp r_yanz,ax
jle short @nc6
mov r_yanz,ax
@nc6:

;//X2 CLIPPING
mov ax,r_xpos1
cmp ax,0
jge short @nc7
sub r_xpos2,ax
add r_xanz,ax
jle short sourceclipped
mov r_xpos1,0
@nc7:

;//Y2 CLIPPING
mov ax,r_ypos1
cmp ax,0
jge short @nc8
sub r_ypos2,ax
add r_yanz,ax
jle short sourceclipped
mov r_ypos1,0
@nc8:
clc
retn
sourceclipped:
stc
retn
sourceclipper endp


dest_transsource proc near
;//Destpointer anpassen
mov ax,word ptr es:[di+6]
mov r_destadder,ax
mul word ptr r_ypos2
add ax,r_xpos2
add ax,10
add di,ax

;//Sourcepointer anpassen
mov ax,word ptr [si+6]
mov r_sourceadder,ax
mul	word ptr r_ypos1
add ax,r_xpos1
add ax,10
mov dx,ax
mov ah,[si+1] ;//transcolor
add si,dx

nextzeilerealputter:
xor bx,bx
mov cx,r_xanz

nextzeichenrealputter:
mov al,[si+bx]
cmp al,ah
je short it_was_hidden
mov es:[di+bx],al
it_was_hidden:
inc bx
loop nextzeichenrealputter

add si,r_sourceadder
add di,r_destadder

dec r_yanz
jnz short nextzeilerealputter

retn
dest_transsource endp




dest_source proc near
;//Destpointer anpassen
mov ax,word ptr es:[di+6]
mov bx,ax
sub bx,r_xanz
mov r_destadder,bx
mul word ptr r_ypos2
add ax,r_xpos2
add ax,10
add di,ax

;//Sourcepointer anpassen
mov ax,word ptr [si+6]
mov bx,ax
sub bx,r_xanz
mov r_sourceadder,bx
mul	word ptr r_ypos1
add ax,r_xpos1
add ax,10
add si,ax

nextzeilerealputterq:
mov cx,r_xanz

rep movsb

add si,r_sourceadder
add di,r_destadder

dec r_yanz
jnz short nextzeilerealputterq

retn
dest_source endp




putsprite_clipcoord_transparent proc far
arg dest:dword,x:word,y:word,source:dword

push ds
push si
push di

lds si,source
les di,dest

mov dword ptr r_xpos1,0

mov ax,x
sub ax,[si+2]
add ax,es:[di+2]
mov r_xpos2,ax

mov ax,y
sub ax,[si+4]
add ax,es:[di+4]
mov r_ypos2,ax

mov ax,[si+6]
mov r_xanz,ax
mov ax,[si+8]
mov r_yanz,ax
call near ptr destclipper
jc short @@hidden
call near ptr dest_transsource
@@hidden:
pop di
pop si
pop ds

ret
putsprite_clipcoord_transparent endp


putsprite_clipcoord_ proc far
arg dest:dword,x:word,y:word,source:dword

push ds
push si
push di

lds si,source
les di,dest

mov dword ptr r_xpos1,0

mov ax,x
sub ax,[si+2]
add ax,es:[di+2]
mov r_xpos2,ax

mov ax,y
sub ax,[si+4]
add ax,es:[di+4]
mov r_ypos2,ax

mov ax,[si+6]
mov r_xanz,ax
mov ax,[si+8]
mov r_yanz,ax
call near ptr destclipper
jc short @@hidden
call near ptr dest_source
@@hidden:
pop di
pop si
pop ds

ret
putsprite_clipcoord_ endp





putsprite__clipcoord proc far
arg dest:dword,source:dword,x:word,y:word

push ds
push si
push di

lds si,source
les di,dest

mov dword ptr r_xpos2,0

mov ax,x
add ax,[si+2]
sub ax,es:[di+2]
mov r_xpos1,ax

mov ax,y
add ax,[si+4]
sub ax,es:[di+4]
mov r_ypos1,ax

mov ax,es:[di+6]
mov r_xanz,ax
mov ax,es:[di+8]
mov r_yanz,ax
call near ptr sourceclipper
jc short @@hidden
call near ptr dest_source
@@hidden:
pop di
pop si
pop ds

ret
putsprite__clipcoord endp





end
