home *** CD-ROM | disk | FTP | other *** search
-
- ;/////////////////////////////////////////////////////////////////////////////
- ;
- ; The one and only asm file for the kick ass ray caster to be used in the
- ; upcoming game- the Four Horsemen (fanfare)
- ; Portions of Render_Floor_asm is taken from Tricks of the Graphics Gurus
- ; However, Josh Glaser and Matt Howard wrote the really cool stuff. So we
- ; get to stand up on a pedastal and look like arrogant fools to the rest of
- ; The world.
- ;
- ; Oh, and BTW, I think this is Copyright @ 1994 to
- ; Josh Glaser and Matt Howard. So if you try to copy it, your genitalia
- ; will become vulnerable to mysterious shrinking.
- ;////////////////////////////////////////////////////////////////////////////
-
- .DATA?
-
- sliver_info_struct STRUC
- ray DW ? ; ray on screen
- top DW ? ; top on screen
- scale DW ? ; number of pixels to draw
- column DW ? ; column in texture
- clip DD ? ; starting row (fixed point)
- increment DD ? ; fixed point increment to y val
- texture DD ? ; pointer to texture to draw
- light DD ? ; pointer to lighting table
- bounder DW ? ; value to bound texture index with
- wshift DB ? ; tells sliver how much to shift width to get texture offset
- sliver_info_struct ENDS
-
- ; Note on floor struct- all members preceded with f
- ; so as not to confuse assembler with sliver_info_struct
-
- floor_info_struct STRUC
- f_texture DD ? ; pointer to texture to draw
- f_light DD ? ; pointer to lighting table
- f_screen_x DW ? ; starting xpos on screen
- f_screen_y DW ? ; ypos on screen
- f_scale DW ? ; number of pixels to draw
- f_x_inc DD ? ; increment in map x per pixel
- f_y_inc DD ? ; increment in map y per pixel
- f_map_x DD ? ; startin map x
- f_map_y DD ? ; starting map y
- floor_info_struct ENDS
-
- floor_inc_x dd ? ; the fixed-point increment to the x value
- floor_inc_y dd ? ; the same but for the y
- sliver_and dd ? ; bounds texture value on each Render_Sliver_asm loop
-
- .CODE ; begin code segment
- .386 ; use 80386 instructions, we need them for the
- ; extra segments fs,gs
-
- SLIVER_INFO_SIZE equ 27
- FLOOR_INFO_SIZE equ 30
-
- EXTRN "C", buff:DWORD ; the external double buffer
- EXTRN "C", wall_runs:DWORD ; point to sliver_info_struct with all draw values
- EXTRN "C", wall_run_count:DWORD ; number of wall runs to draw
- EXTRN "C", floor_runs:DWORD ; pointer to list of all floor screen runs
- EXTRN "C", floor_run_count:DWORD ; number of floor runs to draw
- EXTRN "C", PHYS_SCREEN_WIDTH:DWORD ; actual size of physical screen
- EXTRN "C", y_jumps:DWORD ; pointer to table with screen offset for a given row
-
- PUBLIC Render_Sliver_asm_, Render_Floor_asm_ ; export the function to the linker
-
-
- Render_Sliver_asm_ PROC NEAR C ; this is a C function and is near
-
- pushad ; save registers we will obliterate
-
- mov ecx, wall_run_count ; how many walls to draw?
-
- mov ebp, ecx ; get last entry in sliver table
-
- dec ebp
-
- imul ebp, SLIVER_INFO_SIZE
-
- add ebp, wall_runs
-
- out_sliv_loop:
-
- push ebp
-
- push ecx
-
- movzx eax, [ebp].top ; point to first line
-
- shl eax, 2 ; adjust for long
-
- add eax, y_jumps ; point to table
-
- mov edi, [eax] ; and get offset on screen
-
- add di, [ebp].ray ; adjust for x position on
-
- adc edi, buff ; and add the original screen to offset
-
- movzx esi, [ebp].column ; esi points to x position in texture
-
- mov cl, [ebp].wshift
- shl esi, cl ; adjust width to memory offset in texture
-
- add esi, [ebp].texture ; and add the base location in memory
- ; of the texture
-
- movzx ecx, [ebp].scale ; how many pixels are we drawing
-
- mov edx, [ebp].clip ; offset into texture
-
- mov eax, [ebp].light ; eax = sliver_light
-
- movzx ebx, [ebp].bounder ; get texture bound
-
- mov sliver_and, ebx ; and save it
-
- mov ebp, [ebp].increment ; sets to increment in texture
-
- xor ebx, ebx ; ebx=0
-
- slivloopst:
-
- shld ebx, edx, 12 ; get offset in texture from fixed point offset
-
- and ebx, sliver_and ; make sure texture pointer does not exceed length of texture
-
- add edx, ebp ; update fixed point offset
-
- mov bl, [esi+ebx] ; get value from texture
-
- or bl,bl ; is it 0?
-
- jz noshow ; if so, don't draw it
-
- mov bl, [eax+ebx] ; get properly lighted value
-
- mov [edi], bl ; draw the pixel
-
- noshow:
-
- add edi, PHYS_SCREEN_WIDTH; update screen offset
-
- dec ecx
-
- jnz slivloopst
-
- pop ecx
-
- pop ebp
-
- sub ebp, SLIVER_INFO_SIZE
-
- dec ecx
-
- jnz out_sliv_loop
-
- popad ; restore regs
-
- ret ; blaze
-
- Render_Sliver_asm_ ENDP
-
- Render_Floor_asm_ PROC NEAR C
-
- pushad ; save regs
-
- mov ecx, floor_run_count
-
- mov ebp, floor_runs
-
- out_floor_loop:
-
- push ecx
-
- push ebp
-
- mov eax, [ebp].f_x_inc
-
- mov floor_inc_x, eax
-
- mov eax, [ebp].f_y_inc
-
- mov floor_inc_y, eax
-
- shl floor_inc_y, 6 ; adjust y increment for width of texture (64 or 2^6)
-
- movzx ecx, [ebp].f_scale ; set the loop counter to sliver_scale
-
- movzx eax, [ebp].f_screen_y ; point to first line
-
- shl eax, 2 ; adjust for long
-
- add eax, y_jumps ; point to table
-
- mov edi, [eax] ; and get offset on screen
-
- add di, [ebp].f_screen_x ; adjust for x position on
-
- adc edi, buff ; and add the original screen to offset
-
- mov ebx, [ebp].f_map_x
-
- mov esi, [ebp].f_map_y
- shl esi, 6
-
- mov edx, [ebp].f_light ; edx points to light table
-
- mov ebp, [ebp].f_texture ; ebp should not be used. However, this is a game,
- ; so I don't care. We pulling out every stop
- ; to make it fast
-
- floorloopst:
-
- ; method- we will basically trace a line across the texture, using to fixed point numbers
- ; to keep track of the x & y positions. These numbers are shifted and binary anded to get the
- ; final x & y positions in the texture
-
- and ebx, 000fffffh ; check for bounds on x
-
- mov eax, esi ; get the y offset in the texture
- and eax, 03f00000h
-
- add eax, ebx
- shr eax, 14
-
- mov al, [ebp+eax] ; get the pixel color
-
- mov ah, 0 ; we need to make sure ax has nothing but what's in al
-
- mov al, [edx+eax]
-
- mov [edi], al ; move it to the screen
-
- inc edi ; increment screen position
-
- add ebx, floor_inc_x ; increment x & y positions in texture
- add esi, floor_inc_y
-
- dec ecx ; decrement loop count
-
- jnz floorloopst ; if it's >0, keep going
-
- pop ebp
-
- pop ecx
-
- add ebp, FLOOR_INFO_SIZE
-
- dec ecx
-
- jnz out_floor_loop
-
- popad ; restore regs
-
- ret
-
- Render_Floor_asm_ ENDP
-
- END
-
-
-