home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / RAYCAST.ZIP / VRSMOOTH.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-10-03  |  11.6 KB  |  475 lines

  1. ; ///////////////////////////////////////////////////////////////////////////
  2. ; Vrsmooth.asm - The inner loop of a program to draw voxel terrain
  3. ; Er um, this code is copyright @1994 Matt Howard, and stuff.
  4. ; But why copyright a program? It's just an instrument of the imperialist
  5. ; capatalist regime. In a true socialist society, we'd all share our code.
  6. ; And someone would tape Bill Gates mouth shut. Harmony would prevail.
  7. ; But anyway... here's the code...
  8. ; Oh, BTW, this performs the same function as VOXROW.asm, but w/
  9. ; smooth mountains
  10. ; /////////////////////////////////////////////////////////////////////////
  11. .DATA?
  12. h_inc DD ? ; height increment on screen per pixel
  13. c_inc DD ? ; color increment on screen per pixel
  14. last_x DB ? ; saves last map x
  15. last_y DB ? ; saves last map y
  16. last_height DW ? ; saved last height
  17. vox_cur_change DD ? ; current height change point
  18. .CODE
  19. .386
  20.  
  21. X_LOC_BOUNDER equ 00ffffffh
  22. Y_LOC_BOUNDER equ 0ff000000h
  23. VOX_FP_SHIFT equ 10h
  24. LIGHT_FP_SHIFT equ 08h
  25. ALT_TO_COL_DIFF equ 0ffffh
  26. G_TABLE_SHIFT equ 9
  27. G_TABLE_ADJUST equ 100h
  28. LIGHT_AND equ 0f0h
  29. COLOR_AND equ 0fh
  30. HEIGHT_CHANGE_SHIFT equ 10h
  31. H_TABLE_SHIFT equ 6h
  32. MAX_TABLED_HC_INTP equ 040h
  33. LEV_LOC equ 4h
  34. COL_LOC equ 6h
  35. HCP_SIZE equ 8h
  36. HEIGHT_AND equ 0000ffffh
  37. X_CORRECT equ 8h
  38. Y_CORRECT equ 10h
  39.  
  40. EXTRN "C", x_inc:DWORD; speed at which to go across map in x
  41. EXTRN "C", y_inc:DWORD; speed at which to go across map in y
  42. EXTRN "C", x_loc:DWORD; fixed-point x loc in map
  43. EXTRN "C", y_loc:DWORD; fixed-point y loc in map
  44. EXTRN "C", vox_buff:DWORD; buffer in which to draw
  45. EXTRN "C", starting_y:WORD; highest value to starting drawing at
  46. EXTRN "C", cur_scaler:DWORD ; array holds data to scale altitudes to screen
  47. EXTRN "C", alt_array:DWORD ; grid of altitudes
  48. EXTRN "C", prev_vox_colors:DWORD ; array to save last trace colors
  49. EXTRN "C", prev_vox_heights:DWORD ; array to save last trace heights
  50. EXTRN "C", g_table:DWORD ; scaler to get gauraud interpolation w/o division
  51. EXTRN "C", h_table:DWORD ; scaler to get line interpolation w/o division
  52. EXTRN "C", y_jumps:DWORD ; scaler to get y line offset w/o multiplication
  53. EXTRN "C", WINDOW_HEIGHT:WORD ; height of view window
  54. EXTRN "C", v_horiz_length:DWORD ; length horizontally of current vox run
  55. EXTRN "C", PHYS_SCREEN_WIDTH:DWORD ; length of physical screen
  56. EXTRN "C", PHYS_SCREEN_HEIGHT:DWORD ; length of physical screen
  57. EXTRN "C", vox_change_table:DWORD ; keeps track of the height changes
  58. EXTRN "C", v_light_table:DWORD ; table of values to change light
  59.  
  60. PUBLIC Draw_Vox_Row_Smooth_
  61.  
  62. Draw_Vox_Row_Smooth_ PROC NEAR C
  63.  
  64.    pushad
  65.  
  66.    mov esi, v_horiz_length
  67.    dec esi
  68.  
  69.    ; initialize map position trackers
  70.    mov eax, x_loc
  71.    sar eax, X_CORRECT
  72.    mov ebx, y_loc
  73.    sar ebx, Y_CORRECT
  74.    mov edx, y_inc
  75.    sar edx, Y_CORRECT
  76.    mov y_inc, edx
  77.    mov edx, x_inc
  78.    sar edx, X_CORRECT
  79.    mov x_inc, edx
  80.  
  81.    ; save starting y val in register
  82.    xor ebp, ebp
  83.    mov bp, starting_y
  84.  
  85.    ; get absolute values for map movements
  86.    mov edx, x_inc
  87.    cmp edx,00000000h
  88.    jge ABS_OK1
  89.    mov edi,edx
  90.    mov edx,0
  91.    sub edx, edi
  92. ABS_OK1:
  93.    mov ecx, y_inc
  94.    cmp ecx,000000000h
  95.    jge ABS_OK2
  96.    mov edi, ecx
  97.    mov ecx, 0
  98.    sub ecx, edi
  99. ABS_OK2:
  100.  
  101.   ; decide which movement is greater
  102.   cmp edx, ecx
  103.   jge VOX_SETUP_X_START
  104.  
  105.    ; put the array of height changes in register
  106.    mov edi, vox_change_table
  107.  
  108.    ;make sure first pass dosen't get skipped (we need at least one change point
  109.    mov last_y, bh
  110.    dec last_y
  111.    
  112.    mov ecx, y_inc
  113.    cmp ecx, 00000000h
  114.    je FIX_Y_INC
  115. FIX_Y_DONE:
  116. VOX_SETUP_Y:
  117.  
  118.       cmp bh, last_y
  119.       jne new_value_y
  120.  
  121.       ; update positions in map
  122.       mov edx, y_inc
  123.       add ebx, edx
  124.       mov edx, x_inc
  125.       add eax, edx
  126.  
  127.       ; and loop
  128.       dec esi
  129.       jmp VOX_SETUP_Y
  130.  
  131. new_value_y:
  132.       ; clear gen purpose regs
  133.       xor edx,edx
  134.       xor ecx,ecx
  135.  
  136.       ; save new position
  137.       mov last_y, bh
  138.  
  139.       ; get x,y location of next pixel
  140.       mov dh, bh
  141.       mov dl, ah
  142.  
  143.       ; get altitude
  144.       add edx, alt_array
  145.       mov cl, [edx]
  146.  
  147.       ; get color
  148.       ; Note: altitude & color array are next to each other
  149.       ; in memory for speed
  150.       add edx, ALT_TO_COL_DIFF
  151.       mov dl, [edx]
  152.       mov [edi+COL_LOC],dl
  153.       ; scale altitude
  154.       ; note: ecx added twice since it is word
  155.       mov edx, cur_scaler
  156.       add edx, ecx
  157.       add edx, ecx
  158.       mov cx, [edx]
  159.  
  160.       ; add base value and clip against screen for final value
  161.       add cx, bp
  162.  
  163.       ; too high
  164.       jns not_too_high
  165.       mov cx, 0
  166.  
  167. not_too_high:                  
  168.  
  169.       ; make another height change point
  170.        mov [edi], esi
  171.       mov [edi+LEV_LOC], cx
  172.       add edi, HCP_SIZE
  173.  
  174.        ; update positions in map
  175.       mov edx, y_inc
  176.       add ebx, edx
  177.       mov edx, x_inc
  178.       add eax, edx
  179.  
  180.       ; and loop
  181.       dec esi
  182.       cmp esi, 0FFFFFFFFh
  183.       jge VOX_SETUP_Y
  184.       jmp VOX_SETUP_DONE
  185.  
  186. VOX_SETUP_X_START:
  187.  
  188.    ; put the array of height changes in register
  189.    mov edi, vox_change_table
  190.  
  191.    ;make sure first pass dosen't get skipped (we need at least one change point
  192.    mov last_x, ah
  193.    dec last_x
  194.  
  195.    mov edx, x_inc
  196.    cmp edx, 00000000h
  197.    je FIX_X_INC
  198. FIX_X_DONE:
  199. VOX_SETUP_X:
  200.  
  201.       cmp ah, last_x
  202.       jne new_value_x
  203.  
  204.       ; update positions in map
  205.       mov edx, y_inc
  206.       add ebx, edx
  207.       mov edx, x_inc
  208.       add eax, edx
  209.  
  210.       ; and loop
  211.       dec esi
  212.       jmp VOX_SETUP_X
  213.  
  214. new_value_x:
  215.       ; clear gen purpose regs
  216.       xor edx,edx
  217.       xor ecx,ecx
  218.  
  219.       ; save new position
  220.       mov last_x, ah
  221.  
  222.       ; get x,y location of next pixel
  223.       mov dh, bh
  224.       mov dl, ah
  225.  
  226.       ; get altitude
  227.       add edx, alt_array
  228.       mov cl, [edx]
  229.  
  230.       ; get color
  231.       ; Note: altitude & color array are next to each other
  232.       ; in memory for speed
  233.       add edx, ALT_TO_COL_DIFF
  234.       mov dl, [edx]
  235.       mov [edi+COL_LOC],dl
  236.       ; scale altitude
  237.       ; note: ecx added twice since it is word
  238.       mov edx, cur_scaler
  239.       add edx, ecx
  240.       add edx, ecx
  241.       mov cx, [edx]
  242.  
  243.       ; add base value and clip against screen for final value
  244.       add cx, bp
  245.  
  246.       ; too high
  247.       jns not_too_high_x
  248.       mov cx, 0
  249.  
  250. not_too_high_x:
  251.  
  252.       ; make another height change point
  253.        mov [edi], esi
  254.       mov [edi+LEV_LOC], cx
  255.       add edi, HCP_SIZE
  256.  
  257.       ; update positions in map
  258.       mov edx, y_inc
  259.       add ebx, edx
  260.       mov edx, x_inc
  261.       add eax, edx
  262.  
  263.       ; and loop
  264.       dec esi
  265.       cmp esi, 0FFFFFFFFh
  266.       jge VOX_SETUP_X
  267.       jmp VOX_SETUP_DONE
  268.  
  269. VOX_SETUP_DONE:
  270. ; first run through voxels is done, now we must do the actual drawing
  271. ; we will use the change tables to interpolate the lines
  272.  
  273. mov esi, v_horiz_length
  274. dec esi
  275.  
  276. mov eax, vox_change_table
  277. mov vox_cur_change, eax
  278.  
  279. VOX_DRAW_LOOP:
  280.       xor ecx, ecx
  281.       xor eax, eax
  282.  
  283.       mov edi, vox_cur_change
  284.       cmp esi, [edi]
  285.       je VOX_MAKE_CHANGE
  286. VOX_DRAW_CONTINUE:
  287.  
  288.       xor edi, edi
  289.       shld ecx, ebp, HEIGHT_CHANGE_SHIFT
  290.       and ecx, HEIGHT_AND
  291.  
  292.       add ebp, h_inc
  293.       add edx, c_inc
  294.  
  295.       ; get difference in color
  296.       ; Note: previous height and previous color are next to each other
  297.       ; in memory for speed
  298.       mov ebx, prev_vox_colors;
  299.       add ebx, esi
  300.       mov al, [ebx]
  301.       mov [ebx], dh
  302.  
  303.       ; get previous y        
  304.       mov ebx, prev_vox_heights;
  305.       ; note: esi added twice for since it is word                             
  306.       add ebx, esi
  307.       add ebx, esi
  308.       mov di, [ebx]
  309.       sub di, cx
  310.       jbe NO_DRAW
  311.       
  312.          mov [ebx], cx ; save current value for next round, this seems
  313.                      ; out of place, but helps speed
  314.  
  315.          xor ebx, ebx
  316.  
  317.          ; get gauraud interpolation value
  318.          mov ebx, edi
  319.          shl ebx, G_TABLE_SHIFT
  320.          add eax, G_TABLE_ADJUST
  321.          add eax, ebx
  322.          xor ebx,ebx
  323.          mov bl, dh
  324.          sub eax, ebx
  325.          ; adjust for long
  326.          add eax, eax
  327.          add eax, g_table
  328.          mov ax, [eax]
  329.  
  330.          ; get screen starting pos
  331.          shl ecx, 2
  332.          add ecx, y_jumps
  333.          mov ecx, [ecx]
  334.          add ecx, esi
  335.          add ecx, vox_buff
  336.  
  337.          ; set up values for gauroud loop
  338.          mov bh, bl
  339.          xor bl,bl
  340.  
  341. VOX_IN_LOOP:
  342.  
  343.             ; note: to achieve super speed,
  344.             ; fixed point light is exactly 8 bits in the decimal
  345.             ; this way, the integer portion can be accessed
  346.             ; directly through byte register "bh"
  347.             ; cutting inner loop total to 5 instructions! (including counter update)
  348.  
  349.             ; get the color val and throw it on that screen
  350.             mov [ecx], bh
  351.  
  352.             ; update light val and screen pos
  353.             add ecx, PHYS_SCREEN_WIDTH
  354.             add bx, ax
  355.  
  356.             ; and loop
  357.             dec edi
  358.             jnz VOX_IN_LOOP
  359.  
  360. NO_DRAW:
  361.   
  362.       ; and loop
  363.       dec esi        
  364.       jns VOX_DRAW_LOOP
  365.  
  366.    popad
  367.    ret
  368.  
  369. ; all right think of these as functions, which happen to have intimate knowledge
  370. ; of how the calling function works, and what it is doing at the moment
  371. ; they're placed away from the main body, because they are all exceptions
  372. ; we want the normal path to be as fast as possible, and conditional jumps
  373. ; takes one third the time if the jump is not made, so we want more
  374. ; common conditions to do less jumping (phew, everybody got that?)
  375.  
  376. ; vox_make_change- loads ebp with new y value, edx with a new color value
  377. ; and sets h_inc and c_inc to the appropriate interpolation values
  378. VOX_MAKE_CHANGE:
  379.    xor ebp, ebp
  380.    xor edx, edx
  381.    mov bp, [edi+LEV_LOC]
  382.    mov dl, [edi+COL_LOC]
  383.  
  384.    ; light color (easiest place to do it)
  385.    mov ebx, v_light_table
  386.    mov dl, [ebx+edx]
  387.  
  388.    mov ecx, esi
  389.    add edi, HCP_SIZE
  390.    sub ecx, [edi]
  391.    cmp ecx, PHYS_SCREEN_WIDTH
  392.    jg CORRECT_CHANGE
  393. CORRECT_DONE:
  394.    mov al, [edi+COL_LOC]
  395.  
  396.    ; light destination color
  397.    mov ebx, v_light_table
  398.    mov al, [ebx+eax]
  399.  
  400.    ; get gauraud interpolation value
  401.    mov ebx, ecx
  402.    shl ebx, G_TABLE_SHIFT
  403.    add ebx, eax
  404.    add ebx, G_TABLE_ADJUST
  405.    sub ebx, edx
  406.    ; adjust for word
  407.    add ebx, ebx
  408.    add ebx, g_table
  409.    mov ax, [ebx]
  410.    mov c_inc, eax  
  411.  
  412.    ; now we need the height interpolation
  413.    mov ax, [edi+LEV_LOC]
  414.    ; can we get it from the table?
  415.    cmp ecx, MAX_TABLED_HC_INTP
  416.    jge HC_INTP_DIV
  417.  
  418.    ; yes, we can
  419.    mov ebx, eax
  420.    add ebx, PHYS_SCREEN_HEIGHT
  421.    sub ebx, ebp
  422.    shl ebx, H_TABLE_SHIFT
  423.    add ebx, ecx
  424.    ; adjust for long
  425.    shl ebx, 2
  426.    ; load it up
  427.    add ebx, h_table
  428.    mov eax, [ebx]
  429.    mov h_inc, eax
  430. VC_CONTINUE:
  431.    ; adjust color and height to be fixed points
  432.    mov dh, dl
  433.    mov dl, 0
  434.    shl ebp, HEIGHT_CHANGE_SHIFT
  435.    xor eax, eax
  436.    mov vox_cur_change, edi
  437.    jmp VOX_DRAW_CONTINUE
  438.  
  439. ; hp_intp_div gets height interpolation value by straight division (not enough memory to
  440. ; make a table for all interpolations
  441. HC_INTP_DIV:
  442.    sub eax, ebp
  443.    mov ebx, edx
  444.    mov edx, eax
  445.    xor eax, eax
  446.    shrd eax,edx, HEIGHT_CHANGE_SHIFT
  447.    sar edx, HEIGHT_CHANGE_SHIFT
  448.    idiv ecx
  449.    mov edx, ebx
  450.    mov h_inc, eax
  451.    jmp VC_CONTINUE 
  452.  
  453. ; makes sure the length of next interpolation is not longer than the screen 
  454. ; (which causes a page fault, if it is)
  455. CORRECT_CHANGE:
  456.    mov ecx, PHYS_SCREEN_WIDTH
  457.    jmp CORRECT_DONE
  458.  
  459. ; makes sure x_inc isn't 0 (vox_setup may otherwise be an infinite loop)
  460. FIX_X_INC:
  461.    inc edx
  462.    mov x_inc, edx
  463.    jmp FIX_X_DONE
  464.  
  465. ; same, but for y_inc
  466. FIX_Y_INC:    
  467.    inc ecx
  468.    mov y_inc, ecx
  469.    jmp FIX_Y_DONE
  470.  
  471. Draw_Vox_Row_Smooth_ ENDP
  472.  
  473. END
  474.                
  475.