SecondReality/GLENZ/NEW.ASM
2017-09-24 01:45:36 +02:00

418 lines
6.4 KiB
NASM

;!!!!!! TRANSPARENT NEW COPPER !!!!!!
public __ndebug1
__ndebug1 dw 0
NROWS equ 256
MAXLINES equ 512
ndp0 dw 0 ;toggling pointer inside newdata1
ndp dw 0 ;pointer inside newdata1
nec dw 0 ;pointer to next free in ne
nlc dw 0 ;items in horizontal list
ALIGN 4
nep dw NROWS dup(0)
ALIGN 4
ne db MAXLINES dup(16 dup(0))
NE_X equ 0 ;dd
NE_Y1 equ 4 ;dw
NE_Y2 equ 6 ;dw
NE_COLOR equ 8 ;dw
NE_NEXT equ 10 ;dw
NE_DX equ 12 ;dd
ALIGN 4
nl db 256 dup(0)
ng_init PROC NEAR
mov cs:nec,OFFSET ne
mov ax,cs:ndp0
xor ax,8000h
mov cs:ndp0,ax
mov cs:ndp,ax
mov cx,NROWS/2
mov ax,cs
mov es,ax
xor eax,eax
mov di,OFFSET nep
rep stosd
mov ax,SEG newdata1
mov ds,ax
cmp word ptr ds:[0],0
jne @@1
mov word ptr ds:[0],-1
@@1: cmp word ptr ds:[8000h],0
jne @@2
mov word ptr ds:[8000h],-1
@@2: ret
ng_init ENDP
ALIGN 2
yrow dw 0
yrowad dw 0
siend dw 0
fillmacro MACRO
local l1,l2
jcxz l2
push ax
l1: mov ah,al
or ah,fs:[di]
mov es:[di],ah
inc di
loop l1
pop ax
l2: ENDM
ng_pass3 PROC NEAR
mov ax,SEG newdata1
mov ds,ax
mov ax,0a000h
mov es,ax
mov ax,SEG _bgpic
mov fs,ax
xor di,di
mov si,cs:ndp0
mov bx,si
xor bx,8000h
xor ax,ax
;si=new bx=last
;cx=newpos dx=lastpos
;al=newcol ah=lastcol
mov edx,ds:[bx]
add bx,4
mov ecx,ds:[si]
add si,4
;
@@21: cmp dx,cx
jb @@23
je @@22
;cx<dx
cmp al,ah
je @@31
push cx
sub cx,di
;cmp cx,4
;jae @@r1
;rep stosb
fillmacro
pop cx
@@31: mov di,cx
shr ecx,16
xor al,cl
mov ecx,ds:[si]
add si,4
jmp @@21
@@r1: push ax
mov ah,al
test di,1
jz @@r11
dec cx
stosb
@@r11: shr cx,1
rep stosw
adc cx,cx
rep stosb
pop ax
pop cx
jmp @@31
@@22: ;cx=dx
cmp cx,-1
je @@20
@@23: ;dx<cx
cmp al,ah
je @@32
push cx
mov cx,dx
sub cx,di
;cmp cx,4
;jae @@r2
;rep stosb
fillmacro
pop cx
@@32: mov di,dx
shr edx,16
xor ah,dl
mov edx,ds:[bx]
add bx,4
jmp @@21
@@r2: push ax
mov ah,al
test di,1
jz @@r21
dec cx
stosb
@@r21: shr cx,1
rep stosw
adc cx,cx
rep stosb
pop ax
pop cx
jmp @@32
@@20: ret
mov ax,0a000h
mov es,ax
mov ax,SEG newdata1
mov ds,ax
xor si,si
xor di,di
xor ax,ax
mov dx,cs:ndp
@@1: mov cx,ds:[si]
sub cx,di
rep stosb
xor al,ds:[si+2]
add si,4
cmp si,dx
jb @@1
ret
ng_pass3 ENDP
ng_pass2 PROC NEAR
mov bp,OFFSET nep
mov di,OFFSET nl
mov cx,200 ;NROWS
mov cs:yrow,0
mov cs:yrowad,0
@@1: push cx
;di=pointer to this row list end
;bp=pointer to nep
;add new items this row
mov bx,cs:[bp]
jmp @@3
@@2: mov cs:[di],bx
add di,2
mov bx,cs:[bx+NE_NEXT]
@@3: cmp bx,0
jne @@2
;sort this row (insertion sort)
push bp
push di
mov bp,di
mov si,OFFSET nl+2
jmp @@4
@@5: ;for(k=1;k<listc;k++) { // k=SI
mov bx,cs:[si] ;bx=list[k]
mov dx,bx ;dx=i
mov eax,cs:[bx+NE_X] ;eax=x
mov di,si
sub di,2 ;di=j
jmp @@6
;;;for(j=k-1;j>=0 && x<e[list[j]].x;j--) {
@@9: mov cs:[di+2],bx ;bx=cs:di
sub di,2
@@6: cmp di,OFFSET nl
jge @@8
jmp @@7
@@8: mov bx,cs:[di]
cmp eax,cs:[bx+NE_X]
jl @@9
@@7: ;;;}
mov cs:[di+2],dx
add si,2
@@4: cmp si,bp
jb @@5
;}
pop di
;bp=nl end
;process list & kill finished lines
mov cs:siend,bp
mov ax,SEG newdata1
mov fs,ax
mov bp,cs:ndp
mov dx,cs:yrow
mov cx,8000h
mov si,OFFSET nl
mov di,si
jmp @@10
@@11: mov bx,cs:[si]
cmp dx,cs:[bx+NE_Y2]
jge @@12
mov cs:[di],bx
add di,2
mov eax,cs:[bx+NE_X]
push eax
add eax,cs:[bx+NE_DX]
;sub dword ptr cs:[bx+NE_DX],500
mov cs:[bx+NE_X],eax
pop eax
shr eax,16
;clip X
cmp ax,319
jle @@15
mov ax,319
@@15: cmp ax,1
jge @@16
mov ax,1
@@16: ;
cmp cx,ax
jne @@14
;same x pos
mov ax,cs:[bx+NE_COLOR]
xor fs:[bp-2],ax
jmp @@12
@@14: ;new x pos
add ax,cs:yrowad
mov fs:[bp+0],ax
mov ax,cs:[bx+NE_COLOR]
mov fs:[bp+2],ax
add bp,4
mov cx,ax
@@12: add si,2
@@10: cmp si,cs:siend
jb @@11
mov cs:ndp,bp
pop bp
pop cx
inc cs:yrow
add cs:yrowad,320
add bp,2
loop @@1
mov bx,cs:ndp
mov word ptr fs:[bx+0],63999
mov word ptr fs:[bx+2],0
add bx,4
mov word ptr fs:[bx+0],-1
mov word ptr fs:[bx+2],0
add bx,4
mov cs:ndp,bx
ret
ng_pass2 ENDP
tmp_firstvx dw 0
tmp_color dw 0
public __newgroup
__newgroup PROC FAR
;es:di=polygroup
;sides,color,x,y,x,y,x,y,...
;sides=0=end
cmp ax,0
jne @@ng1
call ng_init
ret
@@ng1: cmp ax,1
je @@ng2
setborder 2
call ng_pass2
setborder 3
call ng_pass3
ret
@@ng2: setborder 1
;add polygons to list
mov bp,cs:nec
@@2: mov cx,es:[di] ;sides
cmp cx,0
je @@1
mov ax,es:[di+2] ;color
mov cs:tmp_color,ax
mov si,di
add di,4
mov cs:tmp_firstvx,di
@@3: add si,4
add di,4
cmp cx,1
jne @@4
mov di,cs:tmp_firstvx
@@4: push cx
;dx=color, si->start, di->end
mov ax,cs:tmp_color
mov cs:[bp+NE_COLOR],ax
mov bx,es:[si+2] ;y1
mov cx,es:[di+2] ;y2
cmp bx,cx
jg @@i1 ;y1>y2
mov ax,es:[si+0] ;x1
mov dx,es:[di+0] ;x2
jmp @@i0
@@i1: xchg bx,cx
mov ax,es:[di+0] ;x1
mov dx,es:[si+0] ;x2
@@i0: ;ax,bx=xy1 dx,cx=xy2
@@i9: mov cs:[bp+NE_Y1],bx
mov cs:[bp+NE_Y2],cx
mov word ptr cs:[bp+NE_X],0
mov cs:[bp+NE_X+2],ax
neg ax
add ax,dx
shl eax,16
cdq
sub cx,bx
;cx=y2-y1,edx:eax=(x2-x1)<<16
cmp cx,0
je @@n1 ;skip horizontal lines
movzx ecx,cx
idiv ecx
mov cs:[bp+NE_DX],eax
;!!!if y1<0, clip
cmp bx,0
jge @@nc
mov dx,cs:[bp+NE_Y2]
cmp dx,0
jle @@n1
neg bx
movzx ebx,bx
imul ebx
add cs:[bp+NE_X],eax
xor bx,bx
mov cs:[bp+NE_Y1],bx
@@nc: ;!!!
shl bx,1
mov ax,cs:nep[bx]
or ax,ax
jnz @@j1
;first on this row
mov cs:nep[bx],bp
mov word ptr cs:[bp+NE_NEXT],0
jmp @@j0
@@j1: ;add to this row
;scan if already exists
push ax
push si
mov si,ax
jmp @@h11
@@h1: mov si,cs:[si+NE_NEXT]
@@h11: mov ax,cs:[bp+NE_Y2]
cmp ax,cs:[si+NE_Y2]
jne @@h2
mov eax,cs:[bp+NE_X]
cmp eax,cs:[si+NE_X]
jne @@h2
mov eax,cs:[bp+NE_DX]
cmp eax,cs:[si+NE_DX]
jne @@h2
;duplicate line SI
mov al,cs:[bp+NE_COLOR]
xor cs:[si+NE_COLOR],al
pop si
pop ax
jmp @@n1
@@h2: cmp si,0
jne @@h1 ;end of list
@@h3: pop si
pop ax
mov cs:nep[bx],bp
mov word ptr cs:[bp+NE_NEXT],ax
@@j0: add bp,16
@@n1: ;next
pop cx
loop @@3
add si,4
mov di,si
jmp @@2
@@1: mov cs:nec,bp
sub bp,OFFSET ne
shr bp,4
mov cs:__ndebug1,bp
ret
__newgroup ENDP