-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSLIVER.ASM
106 lines (66 loc) · 3.16 KB
/
SLIVER.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
;/////////////////////////////////////////////////////////////////////////////
;
;This function is an assembly language version of the C function that renders
;a single textured sliver into the double buffer. It uses the pre-computed
;look up table for the scale indices to speed things up, moreover it uses
;global variables instead of variables passed on the stack. I highly suggest
;you understand the the C version first before trying this one!
;
;////////////////////////////////////////////////////////////////////////////
.MODEL MEDIUM,C ; use medium memory model and C function names
.CODE ; begin code segment
EXTRN double_buffer:DWORD ; the external double buffer
EXTRN sliver_texture:DWORD ; a pointer to the texture memory
EXTRN sliver_column:WORD ; the current texture column
EXTRN sliver_top:WORD ; the starting Y of the sliver
EXTRN sliver_scale:WORD ; the over all height of the sliver
EXTRN sliver_ray:WORD ; the current video column
EXTRN sliver_clip:WORD ; how much of the texture is being clipped
EXTRN scale_row:WORD ; the pointer to the proper row of pre-computed scale
; indices
PUBLIC Render_Sliver_32 ; export the function to the linker
Render_Sliver_32 PROC FAR C ; this is a C function and is far
.386 ; use 80386 instructions, we need them for the
; extra segments fs,gs
push si ; save registers we will obliterate
push di
les di, double_buffer ; point es:di to double buffer
mov dx,sliver_column ; hold the column in dx
lfs si, sliver_texture ; fs:si points to texture memory
; offset = (sprite->y << 8) + (sprite->y << 6) + sprite->x
mov bx,sliver_top ; multiply Y by 320 to get proper offset
shl bx,8
mov ax,bx
shr bx,2
add bx,ax
add bx,sliver_ray ; add X
add di,bx
mov bx,sliver_clip ; move important constants into registers
mov ax,sliver_scale
add ax,bx
Sliver_Loop: ; main loop
; double_buffer[offset] = work_sprite[work_offset+column]
xchg dx,bx ; exchange dx and bx since only bx can be used
; as a index
mov cl, BYTE PTR fs:[si+bx] ; get texture pixel
mov es:[di], cl ; move it to screen
xchg dx,bx ; restore dx and bx
mov cx,bx ; get ready to access proper scale index
; row = scale_table[scale]
mov dx, scale_row
shl bx,1
add bx,dx
mov dx, WORD PTR [bx] ; get scale index out of array
add dx,sliver_column
mov bx,cx
; offset += SCREEN_WIDTH;
add di,320 ; move down to next video line
inc bx ; increment counter
cmp bx, ax
jne Sliver_Loop ; are we done?
pop di ; restore registers
pop si
ret ; blaze
Render_Sliver_32 ENDP
END