home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / RAYCAST.ZIP / SLIVER.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-07-20  |  7.9 KB  |  264 lines

  1.  
  2. ;/////////////////////////////////////////////////////////////////////////////
  3. ;  
  4. ; The one and only asm file for the kick ass ray caster to be used in the
  5. ; upcoming game- the Four Horsemen (fanfare)
  6. ; Portions of Render_Floor_asm is taken from Tricks of the Graphics Gurus
  7. ; However, Josh Glaser and Matt Howard wrote the really cool stuff. So we
  8. ; get to stand up on a pedastal and look like arrogant fools to the rest of
  9. ; The world.
  10. ;
  11. ; Oh, and BTW, I think this is Copyright @ 1994 to 
  12. ; Josh Glaser and Matt Howard. So if you try to copy it, your genitalia
  13. ; will become vulnerable to mysterious shrinking.
  14. ;////////////////////////////////////////////////////////////////////////////
  15.  
  16. .DATA?
  17.  
  18. sliver_info_struct STRUC
  19.    ray DW ?                  ; ray on screen
  20.    top DW ?                  ; top on screen
  21.    scale DW ?               ; number of pixels to draw
  22.    column DW ?             ; column in texture
  23.    clip DD ?                  ; starting row (fixed point)
  24.    increment DD ?          ; fixed point increment to y val
  25.    texture DD ?             ; pointer to texture to draw
  26.    light DD ?                  ; pointer to lighting table
  27.    bounder DW ?             ; value to bound texture index with
  28.    wshift DB ?                ; tells sliver how much to shift width to get texture offset
  29. sliver_info_struct ENDS
  30.  
  31. ; Note on floor struct- all members preceded with f
  32. ; so as not to confuse assembler with sliver_info_struct
  33.  
  34. floor_info_struct STRUC
  35.    f_texture DD ?       ; pointer to texture to draw
  36.    f_light DD ?           ; pointer to lighting table
  37.    f_screen_x DW ?    ; starting xpos on screen
  38.    f_screen_y DW ?    ; ypos on screen
  39.    f_scale DW ?         ; number of pixels to draw
  40.    f_x_inc DD ?          ; increment in map x per pixel
  41.    f_y_inc DD ?          ; increment in map y per pixel
  42.    f_map_x DD ?        ; startin map x
  43.    f_map_y DD ?        ; starting map y
  44. floor_info_struct ENDS
  45.  
  46. floor_inc_x dd ? ; the fixed-point increment to the x value
  47. floor_inc_y dd ? ; the same but for the y
  48. sliver_and dd ? ; bounds texture value on each Render_Sliver_asm loop
  49.  
  50. .CODE                       ; begin code segment
  51. .386                            ; use 80386 instructions, we need them for the
  52.                                  ; extra segments fs,gs
  53.  
  54. SLIVER_INFO_SIZE equ 27
  55. FLOOR_INFO_SIZE equ 30
  56.  
  57. EXTRN "C", buff:DWORD   ; the external double buffer
  58. EXTRN "C", wall_runs:DWORD ; point to sliver_info_struct with all draw values
  59. EXTRN "C", wall_run_count:DWORD ; number of wall runs to draw
  60. EXTRN "C", floor_runs:DWORD ; pointer to list of all floor screen runs
  61. EXTRN "C", floor_run_count:DWORD ; number of floor runs to draw
  62. EXTRN "C", PHYS_SCREEN_WIDTH:DWORD ; actual size of physical screen
  63. EXTRN "C", y_jumps:DWORD ; pointer to table with screen offset for a given row
  64.  
  65. PUBLIC Render_Sliver_asm_, Render_Floor_asm_     ; export the function to the linker
  66.  
  67.  
  68. Render_Sliver_asm_ PROC NEAR C ; this is a C function and is near
  69.  
  70.         pushad                  ; save registers we will obliterate
  71.  
  72.         mov ecx, wall_run_count ; how many walls to draw?
  73.  
  74.         mov ebp, ecx                    ; get last entry in sliver table
  75.  
  76.         dec ebp                           
  77.  
  78.         imul ebp, SLIVER_INFO_SIZE
  79.  
  80.         add ebp, wall_runs
  81.  
  82.         out_sliv_loop:
  83.  
  84.                 push ebp
  85.  
  86.                 push ecx
  87.  
  88.                 movzx eax, [ebp].top    ; point to first line
  89.         
  90.                 shl eax, 2 ; adjust for long
  91.  
  92.                 add eax, y_jumps ; point to table
  93.  
  94.                 mov edi, [eax] ; and get offset on screen
  95.  
  96.                 add di, [ebp].ray  ; adjust for x position on
  97.  
  98.                 adc edi, buff           ; and add the original screen to offset
  99.         
  100.                 movzx esi, [ebp].column   ; esi points to x position in texture
  101.  
  102.                 mov cl, [ebp].wshift
  103.                 shl esi, cl             ; adjust width to memory offset in texture
  104.         
  105.                 add esi, [ebp].texture ; and add the base location in memory
  106.                                 ; of the texture
  107.  
  108.                 movzx ecx, [ebp].scale   ; how many pixels are we drawing
  109.  
  110.                 mov edx, [ebp].clip ; offset into texture
  111.  
  112.                 mov eax, [ebp].light            ; eax = sliver_light
  113.  
  114.                 movzx ebx, [ebp].bounder ; get texture bound
  115.  
  116.                 mov sliver_and, ebx ; and save it
  117.  
  118.                 mov ebp, [ebp].increment ; sets to increment in texture
  119.  
  120.                 xor ebx, ebx                   ; ebx=0
  121.  
  122.                 slivloopst:
  123.  
  124.                         shld ebx, edx, 12             ; get offset in texture from fixed point offset
  125.                 
  126.                         and ebx, sliver_and      ; make sure texture pointer does not exceed length of texture
  127.                 
  128.                         add edx, ebp                    ; update fixed point offset
  129.  
  130.                         mov bl, [esi+ebx] ; get value from texture
  131.  
  132.                         or bl,bl ; is it 0?
  133.         
  134.                         jz noshow ; if so, don't draw it
  135.  
  136.                         mov bl, [eax+ebx] ; get properly lighted value
  137.         
  138.                         mov [edi], bl ; draw the pixel
  139.  
  140.                         noshow:
  141.  
  142.                         add edi, PHYS_SCREEN_WIDTH; update screen offset
  143.  
  144.                         dec ecx
  145.  
  146.                         jnz slivloopst
  147.  
  148.                 pop ecx
  149.  
  150.                 pop ebp
  151.  
  152.                 sub ebp, SLIVER_INFO_SIZE
  153.  
  154.                 dec ecx
  155.  
  156.                 jnz out_sliv_loop
  157.  
  158.         popad ; restore regs
  159.         
  160.         ret                         ; blaze
  161.  
  162. Render_Sliver_asm_ ENDP
  163.  
  164. Render_Floor_asm_ PROC NEAR C
  165.  
  166.    pushad       ; save regs
  167.  
  168.    mov ecx, floor_run_count
  169.  
  170.    mov ebp, floor_runs
  171.  
  172. out_floor_loop:
  173.  
  174.       push ecx
  175.  
  176.       push ebp
  177.  
  178.       mov eax, [ebp].f_x_inc
  179.  
  180.       mov floor_inc_x, eax
  181.  
  182.       mov eax, [ebp].f_y_inc
  183.  
  184.       mov floor_inc_y, eax
  185.  
  186.       shl floor_inc_y, 6 ; adjust y increment for width of texture (64 or 2^6)
  187.  
  188.       movzx ecx, [ebp].f_scale ; set the loop counter to sliver_scale
  189.  
  190.       movzx eax, [ebp].f_screen_y    ; point to first line
  191.  
  192.       shl eax, 2 ; adjust for long
  193.  
  194.       add eax, y_jumps ; point to table
  195.  
  196.       mov edi, [eax] ; and get offset on screen        
  197.  
  198.       add di, [ebp].f_screen_x  ; adjust for x position on
  199.  
  200.       adc edi, buff           ; and add the original screen to offset
  201.    
  202.       mov ebx, [ebp].f_map_x
  203.  
  204.       mov esi, [ebp].f_map_y
  205.       shl esi, 6
  206.  
  207.       mov edx, [ebp].f_light   ; edx points to light table
  208.  
  209.       mov ebp, [ebp].f_texture ; ebp should not be used. However, this is a game,
  210.                                 ; so I don't care. We pulling out every stop 
  211.                                 ; to make it fast
  212.  
  213.    floorloopst:
  214.  
  215.          ; method- we will basically trace a line across the texture, using to fixed point numbers
  216.          ; to keep track of the x & y positions. These numbers are shifted and binary anded to get the
  217.          ; final x & y positions in the texture
  218.  
  219.          and ebx, 000fffffh ; check for bounds on x
  220.    
  221.          mov eax, esi ; get the y offset in the texture
  222.          and eax, 03f00000h
  223.    
  224.          add eax, ebx
  225.          shr eax, 14
  226.  
  227.          mov al, [ebp+eax] ; get the pixel color
  228.  
  229.          mov ah, 0    ; we need to make sure ax has nothing but what's in al
  230.  
  231.          mov al, [edx+eax]
  232.  
  233.          mov [edi], al ; move it to the screen
  234.  
  235.          inc edi ; increment screen position
  236.  
  237.          add ebx, floor_inc_x ; increment x & y positions in texture
  238.          add esi, floor_inc_y
  239.  
  240.          dec ecx ; decrement loop count
  241.  
  242.          jnz floorloopst ; if it's >0, keep going
  243.  
  244.       pop ebp
  245.  
  246.       pop ecx
  247.  
  248.       add ebp, FLOOR_INFO_SIZE
  249.  
  250.       dec ecx
  251.  
  252.       jnz out_floor_loop
  253.  
  254.    popad ; restore regs
  255.  
  256.    ret
  257.  
  258. Render_Floor_asm_ ENDP
  259.  
  260. END
  261.  
  262.  
  263.  
  264.