;-----------------------------------------------------------------------------
; Gouraud Shading assembler modul
; Copyright (c) 1994,95 by J.E. Hoffmann
; All rights reserved
;----------------------------------------------------------------------------
  TITLE CxyGPOLY.ASM


  MODEL SMALL


  IDEAL
  NOJUMPS
  LOCALS @@



  INCLUDE "_VGAXASM.INC"


  STRUC TLine
    x     dw ?
    ddy   dw ?
    ddx   dw ?
    icx   dw ?
    error dw ?
    yTo   dw ?
    xTo   dw ?
    Col   dd ?
    icC   dd ?
  ENDS


  STRUC TEntry
    x     dw ?
    Col   dd ?
  ENDS


  DATASEG
    EXTRN _VirtualVSeg :Word
    EXTRN xSize        :Word

    yi     dw ?
    LL     TLine ?
    RL     TLine ?
    yMin   dw ?
    yMax   dw ?
    min    dw ?

    L      dw ?
    R      dw ?
    K      dw ?
    k1     TEntry ?
    k2     TEntry ?

    DeltaX dw ?
    Cic    dd ?



  CODESEG

  PUBLIC CxyShadedPoly

  P386N



;ננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננ
; CxyShadedPoly(P :PPoints; C :PBytes; Count :Word);
;ננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננננ
  PROC CxyShadedPoly FAR
       ARG Count:Word, C:DWord, P:DWord = @@return
       enter  0,0
       cld
       mov    [min],-1
       mov    [yMin],200
       mov    [yMax],-1

       xor    cx,cx
       les    si,[P]
       mov    bx,si
       inc    si
       inc    si
  @@11:
       mov    ax,[es:si]
       cmp    ax,[yMin]
       jnl    @@12
       mov    [yMin],ax
       mov    [min],cx
  @@12:
       mov    ax,[es:si]
       cmp    ax,[yMax]
       jnge   @@13
       mov    [yMax],ax
  @@13:
       add    si,4
       inc    cx
       cmp    cx,[Count]
       jb     @@11
       cmp    [yMin],199
       jg     @@71
       cmp    [yMax],0
       jl     @@71

       mov    ax,[yMin]
       mov    [yi],ax

       mov    ax,[min]
       mov    [L],ax
       mov    [R],ax
       shl    ax,2
       add    bx,ax
       mov    ax,[es:bx]
       mov    [LL.x],ax
       mov    [RL.x],ax

       call   InitLeft
       call   InitRight

       mov    ax,199
       cmp    [yMax],ax
       jng    @@14
       mov    [yMax],ax
  @@14:
       mov    ax,[yMin]
       cmp    ax,[yMax]
       jg     @@71
       mov    [yi],ax
  @@21:
       mov    ax,[LL.x]
       mov    dx,[LL.ddy]
       mov    bx,[LL.error]
       cmp    bx,[LL.ddx]
       jge    @@33
       cmp    ax,[LL.xTo]
       je     @@33
  @@31:
       add    bx,dx
       add    ax,[LL.icx]
       mov    [LL.error],bx
       mov    [LL.x],ax
       cmp    bx,[LL.ddx]
       jge    @@32
       cmp    ax,[LL.xTo]
       jne    @@31
  @@32:
       mov    [LL.x],ax
  @@33:
       sub    bx,[LL.ddx]
       mov    [LL.error],bx
       mov    eax,[LL.icC]
       add    [LL.Col],eax

       mov    ax,[RL.x]
       mov    dx,[RL.ddy]
       mov    bx,[RL.error]
       cmp    bx,[RL.ddx]
       jge    @@43
       cmp    ax,[RL.xTo]
       je     @@43
  @@41:
       add    bx,dx
       add    ax,[RL.icx]
       mov    [RL.error],bx
       mov    [RL.x],ax
       cmp    bx,[RL.ddx]
       jge    @@42
       cmp    ax,[RL.xTo]
       jne    @@41
  @@42:
       mov    [RL.x],ax
  @@43:
       sub    bx,[RL.ddx]
       mov    [RL.error],bx
       mov    eax,[RL.icC]
       add    [RL.Col],eax

       cmp    [yi],0
       jl     @@60
       mov    ax,[LL.x]
       mov    [k1.x],ax
       mov    eax,[LL.Col]
       mov    [k1.Col],eax
       mov    ax,[RL.x]
       mov    [k2.x],ax
       mov    eax,[RL.Col]
       mov    [k2.Col],eax
       call   GouraudVLine
  @@60:

       mov    ax,[yi]
       cmp    [LL.yTo],ax
       jne    @@61
       call   InitLeft
       mov    ax,[yi]
  @@61:
       cmp    [RL.yTo],ax
       jne    @@62
       call   InitRight
  @@62:
       inc    [yi]
       mov    ax,[yMax]
       cmp    [yi],ax
       jle    @@21
  @@71:
       leave
       ret    @@return
  ENDP



;----------------------------------------------------------------------------
; procedure GouraudVLine; near;
;----------------------------------------------------------------------------
  PROC GouraudVLine NEAR
       push   ds

       movzx  ebx,[k2.x]
       sub    bx,[k1.x]
       jns    @@01
       neg    bx
  @@01:
       inc    bx
       mov    [DeltaX],bx

       xor    edx,edx
       mov    eax,[k2.Col]
       sub    eax,[k1.Col]
       jns    @@02
       neg    eax
  @@02:
       div    ebx
       mov    [Cic],eax

       movzx  ebx,[k1.x]
       movzx  ecx,[k2.x]
       cmp    bx,cx
       jnl    @@13

       cmp    bx,0
       jnl    @@11
       neg    bx
       mov    eax,[Cic]
       imul   ebx
       add    [k1.Col],eax
       xor    bx,bx
  @@11:
       cmp    cx,319
       jng    @@12
       sub    cx,319
       mov    eax,[Cic]
       imul   ecx
       add    [k2.Col],eax
       mov    cx,319
  @@12:
       cmp    bx,cx
       jg     @@40
       jmp    @@16

  @@13:
       cmp    cx,0
       jnl    @@14
       neg    cx
       mov    eax,[Cic]
       imul   ecx
       add    [k1.Col],eax
       xor    cx,cx
  @@14:
       cmp    bx,319
       jng    @@15
       sub    bx,319
       mov    eax,[Cic]
       imul   ebx
       add    [k2.Col],eax
       mov    bx,319
  @@15:
       cmp    cx,bx
       jg     @@40
  @@16:
       mov    [k1.x],bx
       mov    [k2.x],cx

       mov    bx,[k2.x]
       sub    bx,[k1.x]
       jns    @@03
       neg    bx
  @@03:
       inc    bx
       mov    [DeltaX],bx

       mov    eax,[Cic]
       mov    bx,ax
       rol    ebx,16
       rol    eax,16
       mov    cl,al

       mov    bx,1
       mov    ax,[k1.x]
       cmp    ax,[k2.x]
       jng    @@10
       neg    bx
  @@10:

       mov    eax,[k1.Col]
       cmp    eax,[k2.Col]
       jnle   @@21

       mov    di,[WORD PTR k1.Col]
       rol    edi,16
       mov    ax,[xSize]
       mul    [yi]
       mov    di,[k1.x]
       add    di,ax
       mov    al,[BYTE PTR 2+k1.Col]
       jmp    @@22
 @@21:
       mov    di,[WORD PTR k2.Col]
       rol    edi,16
       mov    ax,[xSize]
       mul    [yi]
       mov    di,[k2.x]
       add    di,ax
       mov    al,[BYTE PTR 2+k2.Col]
       neg    bx
 @@22:
       mov    ah,cl

       mov    cx,[DeltaX]
       mov    ds,[_VirtualVSeg]
  @@31:
       mov    [di],al
       add    edi,ebx
       adc    al,ah
       loop   @@31
  @@40:
       pop    ds
       ret
  ENDP



;----------------------------------------------------------------------------
; procedure InitLeft;
;----------------------------------------------------------------------------
  PROC InitLeft NEAR
       les    si,[P]
  @@11:
       mov    bx,[L]
       mov    [K],bx
       shl    bx,2
       mov    ax,[es:si+bx]
       mov    [LL.x],ax

       mov    bx,[L]
       cmp    bx,0
       jne    @@12
       mov    bx,[Count]
  @@12:
       dec    bx
       mov    [L],bx

       shl    bx,2
       mov    ax,[es:si+bx+2]
       mov    [LL.yTo],ax
       sub    ax,[yi]
       jns    @@13
       neg    ax
  @@13:
       inc    ax
       mov    [LL.ddy],ax

       mov    ax,[es:si+bx]
       mov    [LL.xTo],ax

       les    si,[C]
       mov    bx,[k]
       movzx  ax,[BYTE PTR es:si+bx]
       shl    eax,16
       mov    [LL.Col],eax

       mov    [LL.icx],1
       mov    ax,[LL.xTo]
       sub    ax,[LL.x]
       jns    @@14
       neg    [LL.icx]
       neg    ax
  @@14:
       mov    [LL.ddx],ax
       mov    [LL.error],0

       mov    bx,[L]
       movzx  ax,[BYTE PTR es:si+bx]
       shl    eax,16
       sub    eax,[LL.Col]
       cdq
       movzx  ebx,[LL.ddy]
       idiv   ebx
       mov    [LL.icC],eax
  @@15:
       ret
  ENDP



;----------------------------------------------------------------------------
; procedure InitRight;
;----------------------------------------------------------------------------
  PROC InitRight NEAR
       les    si,[P]
  @@11:
       mov    bx,[R]
       mov    [K],bx
       shl    bx,2
       mov    ax,[es:si+bx]
       mov    [RL.x],ax

       mov    bx,[R]
       mov    ax,[Count]
       dec    ax
       cmp    bx,ax
       jne    @@12
       mov    bx,-1
  @@12:
       inc    bx
       mov    [R],bx

       shl    bx,2
       mov    ax,[es:si+bx+2]
       mov    [RL.yTo],ax
       sub    ax,[yi]
       jns    @@13
       neg    ax
  @@13:
       inc    ax
       mov    [RL.ddy],ax

       mov    ax,[es:si+bx]
       mov    [RL.xTo],ax

       les    si,[C]
       mov    bx,[k]
       movzx  ax,[BYTE PTR es:si+bx]
       shl    eax,16
       mov    [RL.Col],eax

       mov    [RL.icx],1
       mov    ax,[RL.xTo]
       sub    ax,[RL.x]
       jns    @@14
       neg    [RL.icx]
       neg    ax
  @@14:
       mov    [RL.ddx],ax
       mov    [RL.error],0

       mov    bx,[R]
       movzx  ax,[BYTE PTR es:si+bx]
       shl    eax,16
       sub    eax,[RL.Col]
       cdq
       movzx  ebx,[RL.ddy]
       idiv   ebx
       mov    [RL.icC],eax
  @@15:
       ret
  ENDP
  END

