home *** CD-ROM | disk | FTP | other *** search
/ The Party 1994: Try This At Home / disk_image.bin / source / gallery / a_proj.asm < prev    next >
Assembly Source File  |  1993-07-20  |  10KB  |  421 lines

  1. ; A_PROJ.ASM -- Projection, fog, and so on.
  2.  
  3.         IDEAL
  4.         MODEL Compact, Pascal
  5.         RADIX 16
  6.         P286
  7.  
  8.         INCLUDE "globals.inc"
  9.  
  10.  
  11.         DATASEG
  12.  
  13. EXTRN SkyTexture : DWord
  14. EXTRN FloorTexture : DWord
  15.  
  16. PUBLIC ScrHeight
  17. PUBLIC FogDensity
  18.  
  19. ; saturation/darkness table  (32 entries)
  20.  
  21.         RADIX 10
  22.         SkyColor    db  01ch
  23.         FloorColor  db  078h
  24.  
  25. SatTable: ;0           6      10    13    16  18  20  22  2425 26 27 28 29 30 31
  26.         db 0,0,0,0,0,0,1,1,1,1,2,2,2,3,3,3,4,4,5,5,6,6,7,7,8,9,10,11,12,13,14,15
  27.  
  28.         FogDensity  db  6d
  29.                     db  ?
  30.         RADIX 16
  31.  
  32. ; projection vars
  33.  
  34.         factor1     dd  ?
  35.         factor2     dd  ?
  36.         factor3     dd  ?
  37.         ObserDist   dd  ?
  38.         ScrHeight   dw  ?
  39.         EyeH        dw  ?
  40.         WallH       dw  ?
  41.  
  42.         FARDATA FloorSky
  43.  
  44. EXTRN   FloorSkyTable : Byte
  45.  
  46.         CODESEG
  47.  
  48. EXTRN MapColumn    : NEAR
  49. EXTRN FilterColumn : NEAR
  50. EXTRN FillColumn   : NEAR
  51. EXTRN RegisterRange  : NEAR
  52. EXTRN PlotFullScreen : NEAR;
  53.  
  54. PUBLIC  InitProjection  ;(Height,ObsDist,EyeHeight,WallHeight:Word)
  55.                         ; Calculates factor1,2,3. Must be called
  56.                         ; before Project.
  57.  
  58.                         ; NOTE: call w/ EyeHeight>WallHeight & you die!
  59.                         ; (I think it's because I use unsigned mul & div...)
  60.  
  61. PUBLIC  EyeHeight       ;(EyeHeight:Word) Changes Eye Height much quicker
  62.                         ;than calling InitProjection
  63.  
  64. PUBLIC  ReFloor         ; updates floor & ceiling w/ EyeHeight & Fog Values
  65.  
  66. PUBLIC  Project         ;(Dest,Texture:Pointer;SideWall,Ofs,screenX,L:Word)
  67.  
  68.                         ; Projects a column of texture (0..63)
  69.                         ; (Texture) onto ScreenColumns[Ofs]
  70.                         ; Height is height of screen (pixels)
  71.                         ; EyeHeight is height of observer
  72.                         ; L is distance to object
  73.  
  74.  
  75.  
  76.         ; Screen coords go from 0 to Height (top-bottom)
  77.  
  78.         ; H = Height of screen in Vpixels (centered at observer's eye)
  79.         ; E = Height of Eye in Vpixels from floor
  80.         ; W = Height of a Wall in Vpixels from floor
  81.         ; L = Distance from Wall to Screen in Vpixels
  82.         ; D = Distance from Observer to Screen in Vpixels
  83.  
  84.         ; projection:
  85.  
  86.         ;           ─┬─
  87.         ;            │ Screen                     ─┬─
  88.         ; Obs        │                             │
  89.         ;   *--------H-----------------------------│ Wall
  90.         ;   |   D    │             L               │
  91.         ;   |        │                             │
  92.         ;   |       ─┴─                            │  W
  93.         ; E |                                      │
  94.         ;   |                                      │
  95.         ;   |                                      │
  96.         ;   |                                      │
  97.         ; ///////////////////////////////////////////////
  98.         ;
  99.  
  100.         ;  y(top)    = H/2 - [ D*(W-E) ] / (L+D)
  101.         ;            = factor1 - factor2 div (L+D)
  102.  
  103.         ;  y(bottom) = H/2 + [ D*E ] / (L+D)
  104.         ;            = factor1 + factor3 div (L+D)
  105.  
  106.  
  107.         PROC InitProjection NEAR
  108.         ARG  H : Word, D : Word, E : Word, W : Word
  109. P386
  110.         pushad
  111.  
  112.           movzx eax, [H]
  113.           mov [ScrHeight], ax    ; ScrHeight = H
  114.           shr eax,1
  115.           mov [factor1], eax     ; factor1 = H/2
  116.  
  117.           movzx eax, [W]
  118.           mov [WallH],ax
  119.           movzx ebx, [E]
  120.           mov [EyeH], bx
  121.           movzx ecx, [D]
  122.           mov [ObserDist], ecx   ; ObserDist = D
  123.  
  124.           sub eax, ebx
  125.           mul ecx
  126.           mov [factor2], eax     ; factor2 = D(W-E)
  127.  
  128.           movzx eax, [E]
  129.           mul ecx
  130.           mov [factor3], eax     ; factor3 = D·E
  131.  
  132.           popad
  133.           ret
  134. P286
  135.         ENDP
  136.  
  137. ; // EyeHeight
  138.  
  139.         PROC EyeHeight NEAR
  140.         ARG  E : Word
  141. P386
  142.         USES eax, ebx, edx
  143.  
  144.           mov ebx, [factor2]     ; ebx = (DW-DE)'
  145.           add ebx, [factor3]     ; ebx = (DW)'
  146.  
  147.           movzx eax, [E]         ; eax = E
  148.           mov [EyeH], ax
  149.           mul [ObserDist]        ; eax = DE
  150.           mov [factor3], eax     ; factor3 = DE
  151.  
  152.           sub ebx, eax
  153.           mov [factor2], ebx     ; factor2 = DW-DE
  154.  
  155.           ret
  156. P286
  157.         ENDP
  158.  
  159.  
  160. ; // Project
  161.  
  162.         ; remember:
  163.  
  164.         ;  y(top)    = H/2 - [ D*(W-E) ] / (L+D)
  165.         ;            = factor1 - factor2 div (L+D)
  166.  
  167.         ;  y(bottom) = H/2 + [ D*E ] / (L+D)
  168.         ;            = factor1 + factor3 div (L+D)
  169.  
  170.         PROC Project NEAR
  171.         ARG Dest : FAR PTR Byte, Texture : FAR PTR Byte, \
  172.             SideWall : Word, Ofs : Word, \
  173.             screenX : Word, L : Word
  174.         LOCAL Ytop : Word, Ybottom : Word, \
  175.               X0 : Word, X1 : Word, YbmYt : Word, Fog : Byte
  176.  
  177. P386
  178.         pushad
  179.         push es
  180.  
  181.           mov ecx, [factor1]
  182.           movzx ebx, [L]
  183. ;         shr ebx,3               ; scale length
  184.  add ebx, 8
  185. ;         add ebx, [ObserDist]    ; ebx = L+D
  186.           mov eax, [factor2]
  187.           xor edx, edx
  188.           div ebx
  189.           sub ecx, eax
  190.           mov [Ytop], cx
  191.  
  192.           mov eax, [factor3]
  193.           xor edx, edx
  194.           div ebx
  195.           add eax, [factor1]
  196.           mov [Ybottom], ax
  197.  
  198.           sub ax, cx
  199.           mov [YbmYt], ax       ; Ybottom-Ytop
  200.  
  201.           mov [X0], 0
  202.           mov [X1], TexRes-1
  203.  
  204.           mov ax, [Ytop]
  205.           or ax, ax
  206.           jns @@SkipTopClip
  207.  
  208.           ; Ytop < 0, must clip top
  209.  
  210.           movsx eax, [Ytop]
  211.           neg eax            ; make positive
  212. IF TexRes EQ 128d
  213.           shl eax, 7         ; *128
  214. ENDIF
  215. IF TexRes EQ 64d
  216.           shl eax, 6         ; *64
  217. ENDIF
  218.           xor edx, edx
  219.           movzx ebx, [YbmYt]
  220.           div ebx
  221.           mov [X0], ax
  222.  
  223.           mov [Ytop], 0
  224.  
  225. @@SkipTopClip:
  226.  
  227.           mov ax, [Ybottom]
  228.           cmp ax, [ScrHeight]
  229.           jb @@SkipBotClip
  230.  
  231.           ; Ybottom > Height, must clip bottom
  232.  
  233.           movzx eax, [Ybottom]
  234.           movzx ebx, [ScrHeight]
  235.           sub eax, ebx
  236. IF TexRes EQ 128d
  237.           shl eax, 7         ; *128
  238. ENDIF
  239. IF TexRes EQ 64d
  240.           shl eax, 6         ; *64
  241. ENDIF
  242.           movzx ebx, [YbmYt]
  243.           xor edx, edx
  244.           div ebx
  245.           mov bx, TexRes-1
  246.           sub bx, ax
  247.           mov [X1], bx
  248.  
  249.           mov ax, [ScrHeight]
  250.           dec ax
  251.           mov [Ybottom], ax
  252.  
  253. @@SkipBotClip:
  254.  
  255. ;    Test for finale
  256.  
  257.           mov al, [byte ptr SideWall]
  258.           cmp al, 10d    ; final full-screen wall ?
  259.           jne @@notFinale
  260.  
  261.           push [dword ptr Dest]
  262.           push [Ytop]
  263.           push [Ybottom]
  264.           push [Ofs]
  265.           push [screenX]
  266.           call PlotFullScreen
  267.           jmp @@continue
  268.  
  269. @@notFinale:
  270.  
  271. ; calculate fog/darkness
  272.  
  273.           mov ax, [L]              ; get length
  274.           mov cl, [FogDensity]     ; get fog/darkness density
  275.           shr ax, cl
  276.  
  277. ; darken east-west walls
  278.  
  279.           mov bl, [byte ptr SideWall+1]
  280.           test bl,1
  281.           jz @@notdarkside
  282.  
  283.           add ax, 6
  284.  
  285. @@notdarkside:
  286.  
  287.           cmp ax, 31d
  288.           jbe @@1
  289.           mov al, 31d
  290. @@1:
  291.           mov bx, offset SatTable
  292.           xlat
  293.           mov [Fog], al
  294.  
  295.           cmp al, 15d
  296.           jb @@wallVisible
  297.  
  298.           push [dword ptr Dest]
  299.           push [Ytop]        ; wall is completely black
  300.           push [Ybottom]
  301.           push [Ofs]
  302.           push 0             ; just draw a black column
  303.           call FillColumn
  304.           jmp @@continue
  305.  
  306. @@wallVisible:
  307.           push [dword ptr Texture]
  308.           push [dword ptr Dest]
  309.           push [X0]
  310.           push [X1]
  311.           push [Ytop]
  312.           push [Ybottom]
  313.           push [Ofs]
  314.           call MapColumn
  315.  
  316.           cmp [Fog],0         ; skip filter if wall is too close
  317.           je @@continue       ;   for fog to have effect.
  318.  
  319.           push [dword ptr Dest]
  320.           push [Ytop]
  321.           push [Ybottom]
  322.           push [Ofs]
  323.           push [word ptr Fog]
  324.           call FilterColumn
  325.  
  326. @@continue:
  327.           push [Ytop]
  328.           push [Ybottom]
  329.           call RegisterRange
  330.  
  331.         pop es
  332.         popad
  333.         ret
  334. P286
  335.         ENDP
  336.  
  337.  
  338. ; // ReFloor
  339.  
  340.         PROC ReFloor NEAR
  341. P386
  342.         USES eax, bx, cx, dx, si, di, es
  343.  
  344.         mov ax, seg FloorSkyTable
  345.         mov es, ax
  346.         mov di, offset FloorSkyTable   ; es:di -> Table
  347.  
  348.         ; SkyTexture
  349.  
  350.         mov al, [FogDensity]
  351.         xor ah,ah
  352.         sub ax, 3
  353.         shl ax, 3                  ; ax = 8*(FogDensity-3)
  354.         mov bx, [WallH]
  355.         sub bx, [EyeH]
  356.         shl bx, 6                  ; bx = 64*(W-E)
  357.         add bx, ax
  358.         mov si, offset SkyTexture
  359.  
  360.         mov al, [SkyColor]
  361.         mov ah,al
  362.         mov cx, ax
  363.         shl eax, 16d
  364.         mov ax, cx                ; eax = ScScScSc
  365.  
  366.         mov cx, 99d               ; Y
  367. @@SkyLoop:
  368.         cmp cl, [es:di+bx]
  369.         ja @@same1
  370.  
  371.         sub eax,01010101h
  372.         inc bx
  373.  
  374. @@same1:
  375.         mov [si], eax
  376.         add si,4
  377.  
  378.         loop @@SkyLoop
  379.  
  380.         ; FloorTexture
  381.  
  382.         mov al, [FogDensity]
  383.         xor ah,ah
  384.         sub ax, 3
  385.         shl ax, 3                  ; ax = 8*(FogDensity-3)
  386.         mov bx, [EyeH]
  387.         shl bx, 6                  ; bx = 64*E
  388.         add bx, ax
  389.         mov si, offset FloorTexture
  390.         add si, 99d*4d
  391.  
  392.         mov al, [FloorColor]
  393.         mov ah,al
  394.         mov cx, ax
  395.         shl eax, 16d
  396.         mov ax, cx                ; eax = ScScScSc
  397.  
  398.         mov cx, 99d               ; Y
  399. @@FloorLoop:
  400.         cmp cl, [es:di+bx]
  401.         ja @@same2
  402.  
  403.         sub eax,01010101h
  404.         inc bx
  405.  
  406. @@same2:
  407.         mov [si], eax
  408.         sub si,4
  409.  
  410.         loop @@FloorLoop
  411.  
  412.  
  413.         ret
  414. P286
  415.         ENDP
  416.  
  417.  
  418.         END
  419.  
  420.  
  421.