-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfixed3d.asm
352 lines (281 loc) · 6.09 KB
/
fixed3d.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
; (C) May 25, 2001 M. Feliks
include sys.inc
include flat3.inc
MAX_POINTS equ 8
MAX_FACES equ 12
.model tiny
.code
.386
org 100h
entrypoint:
call do_startup
call init_sin_cos
main_loop:
mov si, offset object
mov di, offset object_rotated
mov cx, MAX_POINTS*3
cld
rep movsw
mov si, offset angle_x
mov di, offset object_rotated
mov cx, MAX_POINTS
call rotate_points
mov si, offset object_rotated
mov di, offset object_translated
mov cx, MAX_POINTS
call translate_points
call draw_faces
call timer_wait
call copy_buffer
call clear_buffer
add angle_x, 2
add angle_y, 3
add angle_z, 1
mov ah, 6h
mov dl, 0ffh
int 21h
jz main_loop
call do_shutdown
draw_faces proc
@@x1 equ word ptr [bp-2]
@@y1 equ word ptr [bp-4]
@@x2 equ word ptr [bp-6]
@@y2 equ word ptr [bp-8]
@@x3 equ word ptr [bp-10]
@@y3 equ word ptr [bp-12]
push bp
mov bp, sp
sub sp, 12
mov si, offset link
mov cx, MAX_FACES
df_draw:
push cx
mov cx, 3
mov di, bp
sub di, 2
df_get_point:
xor bh, bh
mov bl, byte ptr [si]
shl bx, 2
mov ax, word ptr object_translated[bx]
mov word ptr ss:[di], ax
mov ax, word ptr object_translated[bx+2]
mov word ptr ss:[di-2], ax
inc si
sub di, 4
dec cx
jnz df_get_point
mov ax, @@y1
sub ax, @@y3
mov bx, @@x2
sub bx, @@x1
imul bx
shl edx, 16
mov dx, ax
push edx
mov ax, @@x1
sub ax, @@x3
mov bx, @@y2
sub bx, @@y1
imul bx
shl edx, 16
mov dx, ax
pop ebx
sub ebx, edx
or ebx, ebx
jge df_next
xor ah, ah
mov al, byte ptr [si]
push ax
push @@y3
push @@x3
push @@y2
push @@x2
push @@y1
push @@x1
call flat_triangle
df_next:
inc si
pop cx
dec cx
jnz df_draw
mov sp, bp
pop bp
ret
endp
;------------------------------------------------------------
; ds:si - offset to angles
; ds:di - offset to 3d points
; cx - number of points
;------------------------------------------------------------
rotate_points proc
@@sin_x equ word ptr [bp-2]
@@cos_x equ word ptr [bp-4]
@@sin_y equ word ptr [bp-6]
@@cos_y equ word ptr [bp-8]
@@sin_z equ word ptr [bp-10]
@@cos_z equ word ptr [bp-12]
@@x equ word ptr [di]
@@y equ word ptr [di+2]
@@z equ word ptr [di+4]
push bp
mov bp, sp
sub sp, 12
push di
mov di, bp
sub di, 2
mov dx, 3
rp_sin_cos:
mov bx, word ptr [si]
and bx, 511
shl bx, 1
mov ax, word ptr sin_table[bx]
mov word ptr [di], ax
mov ax, word ptr cos_table[bx]
mov word ptr [di-2], ax
add si, 2
sub di, 4
dec dx
jnz rp_sin_cos
pop di
rp_rotate:
; rotate around x-axis
mov ax, @@y
imul @@cos_x
mov bx, ax
mov si, dx
mov ax, @@z
imul @@sin_x
sub bx, ax
sbb si, dx
shrd bx, si, 14
push bx
mov ax, @@y
imul @@sin_x
mov bx, ax
mov si, dx
mov ax, @@z
imul @@cos_x
add bx, ax
adc si, dx
shrd bx, si, 14
pop @@y
mov @@z, bx
; rotate around y-axis
mov ax, @@x
imul @@cos_y
mov bx, ax
mov si, dx
mov ax, @@z
imul @@sin_y
sub bx, ax
sbb si, dx
shrd bx, si, 14
push bx
mov ax, @@x
imul @@sin_y
mov bx, ax
mov si, dx
mov ax, @@z
imul @@cos_y
add bx, ax
adc si, dx
shrd bx, si, 14
pop @@x
mov @@z, bx
; rotate around z-axis
mov ax, @@x
imul @@cos_z
mov bx, ax
mov si, dx
mov ax, @@y
imul @@sin_z
sub bx, ax
sbb si, dx
shrd bx, si, 14
push bx
mov ax, @@x
imul @@sin_z
mov bx, ax
mov si, dx
mov ax, @@y
imul @@cos_z
add bx, ax
adc si, dx
shrd bx, si, 14
pop @@x
mov @@y, bx
add di, 6
dec cx
jnz rp_rotate
mov sp, bp
pop bp
ret
endp
;------------------------------------------------------------
; ds:si - offset to 3d points
; es:di - offset to 2d points
; cx - number of points
;------------------------------------------------------------
translate_points proc
mov bx, word ptr [si+4]
add bx, 256
mov ax, word ptr [si]
shl ax, 8
cwd
idiv bx
add ax, 160
stosw
mov ax, word ptr [si+2]
shl ax, 8
cwd
idiv bx
add ax, 100
stosw
add si, 6
dec cx
jnz translate_points
ret
endp
init_sin_cos proc
push bp
mov bp, sp
sub sp, 4
fldz
fstp dword ptr [bp-4]
xor di, di
mov cx, 512
isc_make:
fld dword ptr [bp-4]
fld st(0)
fld st(0)
fsin
fmul fixed_point_const
fistp word ptr sin_table[di]
fcos
fmul fixed_point_const
fistp word ptr cos_table[di]
fadd inc_angle
fstp dword ptr [bp-4]
add di, 2
loop isc_make
mov sp, bp
pop bp
ret
endp
.data
angle_x dw 0
angle_y dw 0
angle_z dw 0
fixed_point_const dd 16384.0
inc_angle dd 0.01227184630309 ; pi/256
object dw -50, -50, -50, 50, -50, -50, 50, 50, -50, -50, 50, -50
dw -50, -50, 50, 50, -50, 50, 50, 50, 50, -50, 50, 50
link db 0, 1, 2, 45, 0, 2, 3, 45, 5, 4, 7, 32, 5, 7, 6, 32, 1, 5, 6, 40, 1, 6, 2, 40
db 4, 0, 3, 80, 4, 3, 7, 80, 4, 5, 1, 60, 1, 0, 4, 60, 3, 2, 6, 94, 3, 6, 7, 94
.data?
sin_table dw 512 dup(?)
cos_table dw 512 dup(?)
object_rotated dw MAX_POINTS dup(?, ?, ?)
object_translated dw MAX_POINTS dup(?, ?)
end entrypoint