Subversion Repositories Kolibri OS

Rev

Rev 6108 | Rev 6126 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5153 IgorA 1
;
2
; We draw a triangle with various interpolations
3
;
5922 IgorA 4
; Порядок преобразований цветов вершин:
5
; ZBufferPoint.r -> r1 (+drdl_min or +drdl_max) -> or1 (+drdx) -> [pixel buffer]
6
; ZBufferPoint.g -> g1 (+dgdl_min or +dgdl_max) -> og1 (+dgdx) -> [pixel buffer]
7
; ZBufferPoint.b -> b1 (+dbdl_min or +dbdl_max) -> ob1 (+dbdx) -> [pixel buffer]
8
;
9
; В некоторых случаях значения цвета (во 2-м байте переменных: or1,og1,ob1)
10
; может становиться < 0 или > 255, тогда появляються пиксели не правильного
11
; цвета. Скорее всего это связано с ошибками округления дробных чисел,
12
; при вычислении коэфициентов для плавного перехода цвета.
13
;
14
; Для лечения этой проблемы в версии на C++ специально ограничиваються
15
; минимальные и максимальные значения цвета точек (например от 3 до 252).
16
; Потому цвета граней могут немного отличаться от указанных в программе.
17
;
18
; В даной версии алгоритм немного другой. В наиболее вероятных местах появления
19
; пикселей не правильного цвета (обычно начало и конец линии) иправляеться
20
; цвет испорченных пикселей. Цвет получаеться наиболее близким к указанному
21
; пользователем.
22
 
5153 IgorA 23
	pr1 dd ? ;ZBufferPoint*
24
	pr2 dd ? ;ZBufferPoint*
25
	l1 dd ? ;ZBufferPoint*
26
	l2 dd ? ;ZBufferPoint*
5175 IgorA 27
	fdx1 dd ? ;float
28
	fdx2 dd ? ;float
29
	fdy1 dd ? ;float
30
	fdy2 dd ? ;float
6113 IgorA 31
	fz dd ? ;float - переменная отвечающая за геометрию фигуры
5175 IgorA 32
	d1 dd ? ;float
33
	d2 dd ? ;float
5153 IgorA 34
	pz1 dd ? ;unsigned short*
35
	pp1 dd ? ;PIXEL*
36
	part dd ?
37
	update_left dd ?
38
	update_right dd ?
39
 
5187 IgorA 40
	nb_lines dd ? ;число горизонтальных линий в половине треугольника
5153 IgorA 41
	dx1 dd ?
42
	dy1 dd ?
5187 IgorA 43
	;dx2 dd ?
5153 IgorA 44
	dy2 dd ?
45
 
5187 IgorA 46
	error dd ? ;int
47
	derror dd ? ;int
48
	x1 dd ? ;int
49
	dxdy_min dd ? ;int
50
	dxdy_max dd ? ;int
5153 IgorA 51
	; warning: x2 is multiplied by 2^16
5187 IgorA 52
	x2 dd ? ;int
53
	dx2dy2 dd ? ;int
5153 IgorA 54
 
6108 IgorA 55
	pz dd ? ;unsigned short *
56
	z dd ? ;uint
57
	zz dd ? ;uint
58
 
6113 IgorA 59
	n dd ? ;int - длинна горизонтальной линии в пикселях
60
 
5153 IgorA 61
if INTERP_Z eq 1
5187 IgorA 62
	z1 dd ? ;int
63
	dzdx dd ? ;int
64
	dzdy dd ? ;int
65
	dzdl_min dd ? ;int
66
	dzdl_max dd ? ;int
5153 IgorA 67
end if
68
if INTERP_RGB eq 1
69
	r1 dd ? ;int
70
	drdx dd ?
71
	drdy dd ?
72
	drdl_min dd ?
73
	drdl_max dd ?
74
	g1 dd ?
75
	dgdx dd ?
76
	dgdy dd ?
77
	dgdl_min dd ?
78
	dgdl_max dd ?
79
	b1 dd ?
80
	dbdx dd ?
81
	dbdy dd ?
82
	dbdl_min dd ?
83
	dbdl_max dd ?
6113 IgorA 84
	or1 dd ? ;uint
85
	og1 dd ? ;uint
86
	ob1 dd ? ;uint
5153 IgorA 87
end if
88
if INTERP_ST eq 1
5187 IgorA 89
	s1 dd ? ;int
90
	dsdy dd ? ;int
91
	dsdl_min dd ? ;int
92
	dsdl_max dd ? ;int
93
	t1 dd ? ;int
94
	dtdy dd ? ;int
95
	dtdl_min dd ? ;int
96
	dtdl_max dd ? ;int
5153 IgorA 97
end if
98
if INTERP_STZ eq 1
5175 IgorA 99
	sz1 dd ? ;float
100
	dszdx dd ? ;float
101
	dszdy dd ? ;float
102
	dszdl_min dd ? ;float
103
	dszdl_max dd ? ;float
104
	tz1 dd ? ;float
105
	dtzdx dd ? ;float
106
	dtzdy dd ? ;float
107
	dtzdl_min dd ? ;float
108
	dtzdl_max dd ? ;float
6108 IgorA 109
	s_z dd ? ;float
110
	t_z dd ? ;float
5153 IgorA 111
end if
6113 IgorA 112
if (INTERP_ST eq 1) | (DRAW_LINE_M eq 1)
5175 IgorA 113
	s dd ? ;uint
114
	t dd ? ;uint
6113 IgorA 115
	dsdx dd ? ;int
116
	dtdx dd ? ;int
5175 IgorA 117
end if
5153 IgorA 118
endl
5187 IgorA 119
pushad
5153 IgorA 120
 
5175 IgorA 121
	; we sort the vertex with increasing y
122
	mov ebx,[p0]
123
	mov ecx,[p1]
124
	mov edx,[p2]
5187 IgorA 125
	mov eax,[edx+offs_zbup_y]
126
	cmp [ecx+offs_zbup_y],eax ;(2-1)
127
	jle @f
128
		xchg edx,ecx
5175 IgorA 129
	@@:
130
	mov eax,[ecx+offs_zbup_y]
5187 IgorA 131
	cmp [ebx+offs_zbup_y],eax ;(1-0)
132
	jle @f
133
		xchg ecx,ebx
134
	@@:
135
	mov eax,[edx+offs_zbup_y]
136
	cmp [ecx+offs_zbup_y],eax ;(2-1)
137
	jle @f
138
		xchg edx,ecx
139
	@@:
140
	mov [p0],ebx
141
	mov [p1],ecx
142
	mov [p2],edx
5153 IgorA 143
 
144
	; we compute dXdx and dXdy for all interpolated values
5175 IgorA 145
	mov eax,[ecx+offs_zbup_x]
146
	sub eax,[ebx+offs_zbup_x]
147
	mov [fdx1],eax ;p1.x - p0.x
148
	mov eax,[ecx+offs_zbup_y]
149
	sub eax,[ebx+offs_zbup_y]
150
	mov [fdy1],eax ;p1.y - p0.y
5153 IgorA 151
 
5175 IgorA 152
	mov eax,[edx+offs_zbup_x]
153
	sub eax,[ebx+offs_zbup_x]
154
	mov [fdx2],eax ;p2.x - p0.x
155
	mov eax,[edx+offs_zbup_y]
156
	sub eax,[ebx+offs_zbup_y]
157
	mov [fdy2],eax ;p2.y - p0.y
5153 IgorA 158
 
5187 IgorA 159
	fild dword[fdx1]
160
	fst dword[fdx1]
161
	fild dword[fdy2]
162
	fst dword[fdy2]
163
	fmulp
5175 IgorA 164
	fild dword[fdx2]
165
	fst dword[fdx2]
166
	fild dword[fdy1]
167
	fst dword[fdy1]
168
	fmulp
5187 IgorA 169
	fsubp ;st0 = st1-st0
5175 IgorA 170
	fst dword[fz] ;fz = fdx1 * fdy2 - fdx2 * fdy1
171
	fldz
5187 IgorA 172
	fcompp ;if (fz == 0) return
5175 IgorA 173
	fstsw ax
174
	sahf
175
	je .end_f
5189 IgorA 176
 
5175 IgorA 177
	fld1
178
	fdiv dword[fz] ;fz = 1.0 / fz
179
	fst dword[fz]  ;st0 = fz
5153 IgorA 180
 
5175 IgorA 181
	fld dword[fdx1]
182
	fmul st0,st1
183
	fstp dword[fdx1] ;fdx1 *= fz
184
	fld dword[fdy1]
185
	fmul st0,st1
186
	fstp dword[fdy1] ;fdy1 *= fz
187
	fld dword[fdx2]
188
	fmul st0,st1
189
	fstp dword[fdx2] ;fdx2 *= fz
190
	fld dword[fdy2]
191
	fmul st0,st1
192
	fstp dword[fdy2] ;fdy2 *= fz
193
	ffree st0
194
	fincstp
5153 IgorA 195
 
196
if INTERP_Z eq 1
5175 IgorA 197
	mov eax,[ecx+offs_zbup_z]
198
	sub eax,[ebx+offs_zbup_z]
199
	mov [d1],eax
200
	mov eax,[edx+offs_zbup_z]
201
	sub eax,[ebx+offs_zbup_z]
202
	mov [d2],eax
5187 IgorA 203
	fild dword[d1] ;d1 = p1.z - p0.z
204
	fild dword[d2] ;d2 = p2.z - p0.z
5175 IgorA 205
 
5187 IgorA 206
	fld dword[fdy2]
207
	fmul st0,st2
5175 IgorA 208
	fld dword[fdy1]
5187 IgorA 209
	fmul st0,st2
210
	fsubp
211
	fistp dword[dzdx] ;dzdx = (int) (fdy2*d1 - fdy1*d2)
212
	fld dword[fdx1]
5175 IgorA 213
	fmul st0,st1
5187 IgorA 214
	fld dword[fdx2]
5175 IgorA 215
	fmul st0,st3
5187 IgorA 216
	fsubp
5175 IgorA 217
	fistp dword[dzdy] ;dzdy = (int) (fdx1*d2 - fdx2*d1)
5187 IgorA 218
	ffree st0 ;free d2
5175 IgorA 219
	fincstp
5187 IgorA 220
	ffree st0 ;free d1
221
	fincstp
5153 IgorA 222
end if
223
 
224
if INTERP_RGB eq 1
5175 IgorA 225
	mov eax,[ecx+offs_zbup_r]
226
	sub eax,[ebx+offs_zbup_r]
227
	mov [d1],eax
228
	mov eax,[edx+offs_zbup_r]
229
	sub eax,[ebx+offs_zbup_r]
230
	mov [d2],eax
5187 IgorA 231
	fild dword[d1] ;d1 = p1.r - p0.r
232
	fild dword[d2] ;d2 = p2.r - p0.r
5153 IgorA 233
 
5187 IgorA 234
	fld dword[fdy2]
235
	fmul st0,st2
5175 IgorA 236
	fld dword[fdy1]
5187 IgorA 237
	fmul st0,st2
238
	fsubp
239
	fistp dword[drdx] ;drdx = (int) (fdy2*d1 - fdy1*d2)
240
	fld dword[fdx1]
5175 IgorA 241
	fmul st0,st1
5187 IgorA 242
	fld dword[fdx2]
5175 IgorA 243
	fmul st0,st3
5187 IgorA 244
	fsubp
5175 IgorA 245
	fistp dword[drdy] ;drdy = (int) (fdx1*d2 - fdx2*d1)
5187 IgorA 246
	ffree st0 ;free d2
5175 IgorA 247
	fincstp
5187 IgorA 248
	ffree st0 ;free d1
249
	fincstp
5153 IgorA 250
 
5175 IgorA 251
	mov eax,[ecx+offs_zbup_g]
252
	sub eax,[ebx+offs_zbup_g]
253
	mov [d1],eax
254
	mov eax,[edx+offs_zbup_g]
255
	sub eax,[ebx+offs_zbup_g]
256
	mov [d2],eax
5187 IgorA 257
	fild dword[d1] ;d1 = p1.g - p0.g
258
	fild dword[d2] ;d2 = p2.g - p0.g
5153 IgorA 259
 
5187 IgorA 260
	fld dword[fdy2]
261
	fmul st0,st2
5175 IgorA 262
	fld dword[fdy1]
5187 IgorA 263
	fmul st0,st2
264
	fsubp
265
	fistp dword[dgdx] ;dgdx = (int) (fdy2*d1 - fdy1*d2)
266
	fld dword[fdx1]
5175 IgorA 267
	fmul st0,st1
5187 IgorA 268
	fld dword[fdx2]
5175 IgorA 269
	fmul st0,st3
5187 IgorA 270
	fsubp
5175 IgorA 271
	fistp dword[dgdy] ;dgdy = (int) (fdx1*d2 - fdx2*d1)
5187 IgorA 272
	ffree st0 ;free d2
5175 IgorA 273
	fincstp
5187 IgorA 274
	ffree st0 ;free d1
275
	fincstp
5175 IgorA 276
 
277
	mov eax,[ecx+offs_zbup_b]
278
	sub eax,[ebx+offs_zbup_b]
279
	mov [d1],eax
280
	mov eax,[edx+offs_zbup_b]
281
	sub eax,[ebx+offs_zbup_b]
282
	mov [d2],eax
5187 IgorA 283
	fild dword[d1] ;d1 = p1.b - p0.b
284
	fild dword[d2] ;d2 = p2.b - p0.b
5175 IgorA 285
 
5187 IgorA 286
	fld dword[fdy2]
287
	fmul st0,st2
5175 IgorA 288
	fld dword[fdy1]
5187 IgorA 289
	fmul st0,st2
290
	fsubp
291
	fistp dword[dbdx] ;dbdx = (int) (fdy2*d1 - fdy1*d2)
292
	fld dword[fdx1]
5175 IgorA 293
	fmul st0,st1
5187 IgorA 294
	fld dword[fdx2]
5175 IgorA 295
	fmul st0,st3
5187 IgorA 296
	fsubp
5175 IgorA 297
	fistp dword[dbdy] ;dbdy = (int) (fdx1*d2 - fdx2*d1)
5187 IgorA 298
	ffree st0 ;free d2
5175 IgorA 299
	fincstp
5187 IgorA 300
	ffree st0 ;free d1
301
	fincstp
5153 IgorA 302
end if
303
 
304
if INTERP_ST eq 1
5175 IgorA 305
	mov eax,[ecx+offs_zbup_s]
306
	sub eax,[ebx+offs_zbup_s]
307
	mov [d1],eax
308
	mov eax,[edx+offs_zbup_s]
309
	sub eax,[ebx+offs_zbup_s]
310
	mov [d2],eax
5187 IgorA 311
	fild dword[d1] ;d1 = p1.s - p0.s
312
	fild dword[d2] ;d2 = p2.s - p0.s
5153 IgorA 313
 
5187 IgorA 314
	fld dword[fdy2]
315
	fmul st0,st2
5175 IgorA 316
	fld dword[fdy1]
5187 IgorA 317
	fmul st0,st2
318
	fsubp
5175 IgorA 319
	fistp dword[dsdx] ;dsdx = (int) (fdy2*d1 - fdy1*d2)
320
	fld dword[fdx2]
321
	fmul st0,st2
322
	fld dword[fdx1]
323
	fmul st0,st2
324
	fsub st0,st1
325
	fistp dword[dsdy] ;dsdy = (int) (fdx1*d2 - fdx2*d1)
326
	ffree st0
327
	fincstp
5187 IgorA 328
	ffree st0 ;free d2
329
	fincstp
330
	ffree st0 ;free d1
331
	fincstp
5175 IgorA 332
 
333
	mov eax,[ecx+offs_zbup_t]
334
	sub eax,[ebx+offs_zbup_t]
335
	mov [d1],eax
336
	mov eax,[edx+offs_zbup_t]
337
	sub eax,[ebx+offs_zbup_t]
338
	mov [d2],eax
5187 IgorA 339
	fild dword[d1] ;d1 = p1.t - p0.t
340
	fild dword[d2] ;d2 = p2.t - p0.t
5175 IgorA 341
 
342
	fld dword[fdy1]
343
	fmul st0,st1
344
	fld dword[fdy2]
345
	fmul st0,st3
346
	fsub st0,st1
347
	fistp dword[dtdx] ;dtdx = (int) (fdy2*d1 - fdy1*d2)
348
	ffree st0
349
	fincstp
350
	fld dword[fdx2]
351
	fmul st0,st2
352
	fld dword[fdx1]
353
	fmul st0,st2
354
	fsub st0,st1
355
	fistp dword[dtdy] ;dtdy = (int) (fdx1*d2 - fdx2*d1)
356
	ffree st0
357
	fincstp
5187 IgorA 358
	ffree st0 ;free d2
359
	fincstp
360
	ffree st0 ;free d1
361
	fincstp
5153 IgorA 362
end if
363
 
364
if INTERP_STZ eq 1
5175 IgorA 365
	fild dword[ebx+offs_zbup_z]
366
	fild dword[ebx+offs_zbup_s]
367
	fmul st0,st1
368
	fstp dword[ebx+offs_zbup_sz] ;p0.sz = (float) p0.s * p0.z
369
	fild dword[ebx+offs_zbup_t]
5187 IgorA 370
	fmulp
5175 IgorA 371
	fstp dword[ebx+offs_zbup_tz] ;p0.tz = (float) p0.t * p0.z
5153 IgorA 372
 
5175 IgorA 373
	fild dword[ecx+offs_zbup_z]
374
	fild dword[ecx+offs_zbup_s]
375
	fmul st0,st1
376
	fstp dword[ecx+offs_zbup_sz] ;p1.sz = (float) p1.s * p1.z
377
	fild dword[ecx+offs_zbup_t]
5187 IgorA 378
	fmulp
5175 IgorA 379
	fstp dword[ecx+offs_zbup_tz] ;p1.tz = (float) p1.t * p1.z
5153 IgorA 380
 
5175 IgorA 381
	fild dword[edx+offs_zbup_z]
382
	fild dword[edx+offs_zbup_s]
383
	fmul st0,st1
384
	fstp dword[edx+offs_zbup_sz] ;p2.sz = (float) p2.s * p2.z
385
	fild dword[edx+offs_zbup_t]
5187 IgorA 386
	fmulp
5175 IgorA 387
	fstp dword[edx+offs_zbup_tz] ;p2.tz = (float) p2.t * p2.z
388
 
389
	fld dword[ecx+offs_zbup_sz]
5187 IgorA 390
	fsub dword[ebx+offs_zbup_sz] ;d1 = p1.sz - p0.sz
5175 IgorA 391
	fld dword[edx+offs_zbup_sz]
5187 IgorA 392
	fsub dword[ebx+offs_zbup_sz] ;d2 = p2.sz - p0.sz
5175 IgorA 393
 
5187 IgorA 394
	fld dword[fdy2]
395
	fmul st0,st2
5175 IgorA 396
	fld dword[fdy1]
5187 IgorA 397
	fmul st0,st2
398
	fsubp
399
	fstp dword[dszdx] ;dszdx = (fdy2*d1 - fdy1*d2)
5175 IgorA 400
	fld dword[fdx2]
401
	fmul st0,st2
402
	fld dword[fdx1]
403
	fmul st0,st2
404
	fsub st0,st1
5187 IgorA 405
	fstp dword[dszdy] ;dszdy = (fdx1*d2 - fdx2*d1)
5175 IgorA 406
	ffree st0
407
	fincstp
5187 IgorA 408
	ffree st0 ;free d2
409
	fincstp
410
	ffree st0 ;free d1
411
	fincstp
5175 IgorA 412
 
413
	fld dword[ecx+offs_zbup_tz]
5187 IgorA 414
	fsub dword[ebx+offs_zbup_tz] ;d1 = p1.tz - p0.tz
5175 IgorA 415
	fld dword[edx+offs_zbup_tz]
5187 IgorA 416
	fsub dword[ebx+offs_zbup_tz] ;d2 = p2.tz - p0.tz
5175 IgorA 417
 
418
	fld dword[fdy1]
419
	fmul st0,st1
420
	fld dword[fdy2]
421
	fmul st0,st3
422
	fsub st0,st1
5187 IgorA 423
	fstp dword[dtzdx] ;dtzdx = (fdy2*d1 - fdy1*d2)
5175 IgorA 424
	ffree st0
425
	fincstp
426
	fld dword[fdx2]
427
	fmul st0,st2
428
	fld dword[fdx1]
429
	fmul st0,st2
430
	fsub st0,st1
5187 IgorA 431
	fstp dword[dtzdy] ;dtzdy = (fdx1*d2 - fdx2*d1)
5175 IgorA 432
	ffree st0
433
	fincstp
5187 IgorA 434
	ffree st0 ;free d2
435
	fincstp
436
	ffree st0 ;free d1
437
	fincstp
5153 IgorA 438
end if
439
 
440
	; screen coordinates
5175 IgorA 441
	mov eax,[zb]
442
	mov edx,[eax+offs_zbuf_linesize]
443
	imul edx,[ebx+offs_zbup_y]
444
	add edx,[eax+offs_zbuf_pbuf]
445
	mov [pp1],edx ;pp1 = zb.pbuf + zb.linesize * p0.y
446
	mov edx,[eax+offs_zbuf_xsize]
447
	imul edx,[ebx+offs_zbup_y]
448
	shl edx,1
449
	add edx,[eax+offs_zbuf_zbuf]
450
	mov [pz1],edx ;pz1 = zb.zbuf + zb.xsize * p0.y
5153 IgorA 451
 
452
	DRAW_INIT
453
 
5175 IgorA 454
	mov dword[part],0
455
	.cycle_0:
456
		mov ebx,[p0]
457
		mov ecx,[p1]
458
		mov edx,[p2]
5187 IgorA 459
		cmp dword[part],0 ;if (part == 0)
5175 IgorA 460
		jne .els_0
461
			mov dword[update_left],1
462
			mov dword[update_right],1
463
			mov [l1],ebx
464
			mov [pr1],ebx
465
			fldz
466
			fld dword[fz]
467
			fcompp ;if (fz > 0)
468
			fstsw ax
469
			sahf
470
			jbe .els_1
471
				mov [l2],edx
472
				mov [pr2],ecx
473
				jmp .end_1
474
			.els_1:
475
				mov [l2],ecx
476
				mov [pr2],edx
477
			.end_1:
478
			mov eax,[ecx+offs_zbup_y]
479
			sub eax,[ebx+offs_zbup_y]
480
			mov [nb_lines],eax ;nb_lines = p1.y - p0.y
481
			jmp .end_0
482
		.els_0:
483
			; second part
484
			fldz
485
			fld dword[fz]
486
			fcompp ;if (fz > 0)
487
			fstsw ax
488
			sahf
489
			jbe .els_2
5187 IgorA 490
				mov dword[update_left],0
491
				mov dword[update_right],1
5175 IgorA 492
				mov [pr1],ecx
493
				mov [pr2],edx
494
				jmp .end_2
495
			.els_2:
5187 IgorA 496
				mov dword[update_left],1
497
				mov dword[update_right],0
5175 IgorA 498
				mov [l1],ecx
499
				mov [l2],edx
500
			.end_2:
501
			mov eax,[edx+offs_zbup_y]
502
			sub eax,[ecx+offs_zbup_y]
503
			inc eax
504
			mov [nb_lines],eax ;nb_lines = p2.y - p1.y + 1
505
		.end_0:
5153 IgorA 506
 
507
	; compute the values for the left edge
5175 IgorA 508
	cmp dword[update_left],0 ;if (update_left)
509
	je .end_upd_l
510
		mov ebx,[l1]
511
		mov ecx,[l2]
5187 IgorA 512
		mov edx,[ecx+offs_zbup_y]
513
		sub edx,[ebx+offs_zbup_y]
514
		mov [dy1],edx ;dy1 = l2.y - l1.y
5175 IgorA 515
		mov eax,[ecx+offs_zbup_x]
516
		sub eax,[ebx+offs_zbup_x]
517
		mov [dx1],eax ;dx1 = l2.x - l1.x
5187 IgorA 518
		cmp edx,0 ;if (dy1 > 0)
5175 IgorA 519
		jle .els_3
5187 IgorA 520
			xor edx,edx
521
			cmp eax,0
522
			jl .otr_dx1
5175 IgorA 523
			shl eax,16
524
			div dword[dy1] ;eax = (dx1 << 16) / dy1
525
			jmp .end_3
5187 IgorA 526
			.otr_dx1:
527
			neg eax
528
			inc eax
529
			shl eax,16
530
			div dword[dy1] ;eax = (-dx1 << 16) / dy1
531
			neg eax
532
			inc eax
533
			jmp .end_3
5175 IgorA 534
		.els_3:
535
			xor eax,eax
536
		.end_3:
537
		mov edx,[ebx+offs_zbup_x]
5187 IgorA 538
		mov [x1],edx ;x1 = l1.x
539
		mov dword[error],0 ;error = 0
5175 IgorA 540
		mov dword[derror],eax
5187 IgorA 541
		and dword[derror],0xffff ;derror = eax & 0x0000ffff
5208 IgorA 542
		sar eax,16
5187 IgorA 543
		mov [dxdy_min],eax ;dxdy_min = eax >> 16
5175 IgorA 544
		inc eax
545
		mov [dxdy_max],eax
5153 IgorA 546
 
547
if INTERP_Z eq 1
5175 IgorA 548
	mov eax,[l1]
549
	mov eax,[eax+offs_zbup_z]
550
	mov [z1],eax ;z1 = l1.z
551
	mov eax,[dzdx]
552
	imul eax,[dxdy_min]
553
	add eax,[dzdy]
554
	mov [dzdl_min],eax ;dzdl_min = (dzdy +dzdx*dxdy_min)
555
	add eax,[dzdx]
556
	mov [dzdl_max],eax ;dzdl_max = dzdl_min +dzdx
5153 IgorA 557
end if
558
if INTERP_RGB eq 1
5175 IgorA 559
	mov ebx,[l1]
560
	mov eax,[ebx+offs_zbup_r]
561
	mov [r1],eax ;r1 = l1.r
562
	mov eax,[drdx]
563
	imul eax,[dxdy_min]
564
	add eax,[drdy]
565
	mov [drdl_min],eax ;drdl_min = (drdy +drdx*dxdy_min)
566
	add eax,[drdx]
567
	mov [drdl_max],eax ;drdl_max = drdl_min +drdx
5153 IgorA 568
 
5175 IgorA 569
	mov eax,[ebx+offs_zbup_g]
570
	mov [g1],eax ;g1 = l1.g
571
	mov eax,[dgdx]
572
	imul eax,[dxdy_min]
573
	add eax,[dgdy]
574
	mov [dgdl_min],eax ;dgdl_min = (dgdy +dgdx*dxdy_min)
575
	add eax,[dgdx]
576
	mov [dgdl_max],eax ;dgdl_max = dgdl_min +dgdx
5153 IgorA 577
 
5175 IgorA 578
	mov eax,[ebx+offs_zbup_b]
579
	mov [b1],eax ;b1 = l1.b
580
	mov eax,[dbdx]
581
	imul eax,[dxdy_min]
582
	add eax,[dbdy]
583
	mov [dbdl_min],eax ;dbdl_min = (dbdy +dbdx*dxdy_min)
584
	add eax,[dbdx]
585
	mov [dbdl_max],eax ;dbdl_max = dbdl_min +dbdx
5153 IgorA 586
end if
587
if INTERP_ST eq 1
5175 IgorA 588
	mov ebx,[l1]
589
	mov eax,[ebx+offs_zbup_s]
590
	mov [s1],eax ;s1 = l1.s
591
	mov eax,[dsdx]
592
	imul eax,[dxdy_min]
593
	add eax,[dsdy]
594
	mov [dsdl_min],eax ;dsdl_min = (dsdy +dsdx*dxdy_min)
595
	add eax,[dsdx]
596
	mov [dsdl_max],eax ;dsdl_max = dsdl_min +dsdx
5153 IgorA 597
 
5175 IgorA 598
	mov eax,[ebx+offs_zbup_t]
599
	mov [t1],eax ;t1 = l1.t
600
	mov eax,[dtdx]
601
	imul eax,[dxdy_min]
602
	add eax,[dtdy]
603
	mov [dtdl_min],eax ;dtdl_min = (dtdy +dtdx*dxdy_min)
604
	add eax,[dtdx]
605
	mov [dtdl_max],eax ;dtdl_max = dtdl_min +dtdx
5153 IgorA 606
end if
607
if INTERP_STZ eq 1
5175 IgorA 608
	mov ebx,[l1]
609
	mov eax,[ebx+offs_zbup_sz]
610
	mov [sz1],eax ;sz1 = l1.sz - преобразований нет, потому без сопроцессора
611
	fild dword[dxdy_min]
612
	fmul dword[dszdx]
613
	fadd dword[dszdy]
614
	fst dword[dszdl_min] ;dszdl_min = (dszdy +dszdx*dxdy_min)
615
	fadd dword[dszdx]
616
	fstp dword[dszdl_max] ;dszdl_max = dszdl_min +dszdx
5153 IgorA 617
 
5175 IgorA 618
	mov eax,[ebx+offs_zbup_tz]
619
	mov [tz1],eax ;tz1 = l1.tz - преобразований нет, потому без сопроцессора
620
	fild dword[dxdy_min]
621
	fmul dword[dtzdx]
622
	fadd dword[dtzdy]
623
	fst dword[dtzdl_min] ;dtzdl_min = (dtzdy +dtzdx*dxdy_min)
624
	fadd dword[dtzdx]
625
	fstp dword[dtzdl_max] ;dtzdl_max = dtzdl_min +dtzdx
5153 IgorA 626
end if
5175 IgorA 627
	.end_upd_l:
5153 IgorA 628
 
5175 IgorA 629
	; compute values for the right edge
5153 IgorA 630
 
5175 IgorA 631
	cmp dword[update_right],0 ;if(update_right)
632
	je .end_upd_r
633
		mov ebx,[pr1]
634
		mov ecx,[pr2]
5187 IgorA 635
		mov edx,[ebx+offs_zbup_x]
5175 IgorA 636
		mov eax,[ecx+offs_zbup_x]
5187 IgorA 637
		sub eax,edx
638
		;mov [dx2],eax ;dx2 = pr2.x - pr1.x
639
		shl edx,16
640
		mov [x2],edx ; x2 = pr1.x << 16
641
		mov edx,[ecx+offs_zbup_y]
642
		sub edx,[ebx+offs_zbup_y]
643
		mov [dy2],edx ;dy2 = pr2.y - pr1.y
644
		cmp edx,0 ;if (dy2 > 0)
5175 IgorA 645
		jle .els_4
5187 IgorA 646
			xor edx,edx
647
			cmp eax,0
648
			jl .otr_dx2
5175 IgorA 649
			shl eax,16
650
			div dword[dy2] ;eax = (dx2 << 16) / dy2
651
			jmp .end_4
5187 IgorA 652
			.otr_dx2:
653
			neg eax
654
			inc eax ;dx2 *= -1
655
			shl eax,16
656
			div dword[dy2] ;eax = (-dx2 << 16) / dy2
657
			neg eax
658
			inc eax
659
			jmp .end_4
5175 IgorA 660
		.els_4:
661
			xor eax,eax
662
		.end_4:
663
		mov [dx2dy2],eax
664
	.end_upd_r:
5153 IgorA 665
 
5175 IgorA 666
	; we draw all the scan line of the part
5187 IgorA 667
if DEBUG ;[nb_lines]
668
push ecx edi
669
	mov eax,[nb_lines]
670
	mov ecx,80
671
	lea edi,[buf_param]
672
	stdcall convert_int_to_str,ecx
5153 IgorA 673
 
5187 IgorA 674
	stdcall str_n_cat,edi,txt_nl,2
675
	stdcall dbg_print,f_fill_tr_nl,buf_param
676
pop edi ecx
677
end if
678
 
5175 IgorA 679
	.beg_w_lin:
680
	cmp dword[nb_lines],0 ;while (nb_lines>0)
681
	jle .end_w_lin
682
		dec dword[nb_lines]
683
if DRAW_LINE_M eq 1
6113 IgorA 684
		DRAW_LINE
5175 IgorA 685
else
686
		; generic draw line
687
		mov eax,[x2]
5208 IgorA 688
		sar eax,16
5175 IgorA 689
		mov edi,[x1]
690
		sub eax,edi
691
		mov [n],eax ;n = (x2 >> 16) - x1
692
		imul edi,PSZB
693
		add edi,[pp1] ;pp = pp1 + x1 * PSZB
5187 IgorA 694
 
5153 IgorA 695
if INTERP_Z eq 1
5175 IgorA 696
		mov eax,[x1]
697
		shl eax,1
698
		add eax,[pz1]
699
		mov [pz],eax
700
		mov eax,[z1]
701
		mov [z],eax
5153 IgorA 702
end if
703
if INTERP_RGB eq 1
5175 IgorA 704
		mov eax,[r1]
5922 IgorA 705
		bt eax,31 ; коректирование испорченных пикселей (в начале линии)
706
		jnc @f
707
			xor eax,eax
708
		@@:
709
		bt eax,16
710
		jnc @f
711
			mov eax,0xff00
712
		@@:
5175 IgorA 713
		mov [or1],eax
714
		mov eax,[g1]
5922 IgorA 715
		bt eax,31
716
		jnc @f
717
			xor eax,eax
718
		@@:
719
		bt eax,16
720
		jnc @f
721
			mov eax,0xff00
722
		@@:
5175 IgorA 723
		mov [og1],eax
724
		mov eax,[b1]
5922 IgorA 725
		bt eax,31
726
		jnc @f
727
			xor eax,eax
728
		@@:
729
		bt eax,16
730
		jnc @f
731
			mov eax,0xff00
732
		@@:
5175 IgorA 733
		mov [ob1],eax
5153 IgorA 734
end if
735
if INTERP_ST eq 1
5175 IgorA 736
		mov eax,[s1]
737
		mov [s],eax
738
		mov eax,[t1]
739
		mov [t],eax
5153 IgorA 740
end if
741
if INTERP_STZ eq 1
5175 IgorA 742
		mov eax,[sz1]
743
		mov [s_z],eax
744
		mov eax,[tz1]
745
		mov [t_z],eax
5153 IgorA 746
end if
5187 IgorA 747
 
748
align 4
5175 IgorA 749
		.cycle_1: ;while (n>=3)
5922 IgorA 750
if INTERP_RGB eq 1
751
		cmp dword[n],5
752
		jl .cycle_2
753
else
5187 IgorA 754
		cmp dword[n],3
755
		jl .cycle_2
5922 IgorA 756
end if
5175 IgorA 757
			PUT_PIXEL 0
758
			PUT_PIXEL 1
759
			PUT_PIXEL 2
760
			PUT_PIXEL 3
5153 IgorA 761
if INTERP_Z eq 1
5175 IgorA 762
			add dword[pz],8 ;=4*sizeof(uint)
5153 IgorA 763
end if
5175 IgorA 764
			add edi,4*PSZB
765
			sub dword[n],4
5187 IgorA 766
		jmp .cycle_1
5175 IgorA 767
		.cycle_2: ;while (n>=0)
5939 IgorA 768
		cmp dword[n],0
769
		jl .cycle_2_end
5922 IgorA 770
if INTERP_RGB eq 1
771
		; коректирование испорченных пикселей (в конце линии)
772
		bt dword[or1],31
773
		jnc @f
774
			mov dword[or1],0
775
			jmp .end_r
776
		@@:
777
		bt dword[or1],16
778
		jnc .end_r
779
			mov dword[or1],0xff00
780
		.end_r:
781
		bt dword[og1],31
782
		jnc @f
783
			mov dword[og1],0
784
			jmp .end_g
785
		@@:
786
		bt dword[og1],16
787
		jnc .end_g
788
			mov dword[og1],0xff00
789
		.end_g:
790
		bt dword[ob1],31
791
		jnc @f
792
			mov dword[ob1],0
793
			jmp .end_b
794
		@@:
795
		bt dword[ob1],16
796
		jnc .end_b
797
			mov dword[ob1],0xff00
798
		.end_b:
799
end if
5175 IgorA 800
			PUT_PIXEL 0
5153 IgorA 801
if INTERP_Z eq 1
5175 IgorA 802
			add dword[pz],2 ;=sizeof(uint)
5153 IgorA 803
end if
5175 IgorA 804
			add edi,PSZB
805
			dec dword[n]
5187 IgorA 806
		jmp .cycle_2
807
		.cycle_2_end:
808
end if ;проверка от макроса DRAW_LINE
5175 IgorA 809
 
810
	; left edge
811
	mov eax,[derror]
812
	add [error],eax
5187 IgorA 813
	cmp dword[error],0 ;if (error > 0)
5175 IgorA 814
	jle .els_er
815
		sub dword[error],0x10000
816
		mov eax,[dxdy_max]
817
		add [x1],eax
5153 IgorA 818
if INTERP_Z eq 1
5175 IgorA 819
		mov eax,[dzdl_max]
820
		add [z1],eax
5153 IgorA 821
end if
822
if INTERP_RGB eq 1
5175 IgorA 823
		mov eax,[drdl_max]
824
		add [r1],eax
825
		mov eax,[dgdl_max]
826
		add [g1],eax
827
		mov eax,[dbdl_max]
828
		add [b1],eax
5153 IgorA 829
end if
830
if INTERP_ST eq 1
5175 IgorA 831
		mov eax,[dsdl_max]
832
		add [s1],eax
833
		mov eax,[dtdl_max]
834
		add [t1],eax
5153 IgorA 835
end if
836
if INTERP_STZ eq 1
5175 IgorA 837
		fld dword[dszdl_max]
838
		fadd dword[sz1]
839
		fstp dword[sz1]
840
		fld dword[dtzdl_max]
841
		fadd dword[tz1]
842
		fstp dword[tz1]
5153 IgorA 843
end if
5175 IgorA 844
		jmp .end_er
845
	.els_er:
846
		mov eax,[dxdy_min]
847
		add [x1],eax
5153 IgorA 848
if INTERP_Z eq 1
5175 IgorA 849
		mov eax,[dzdl_min]
850
		add [z1],eax
5153 IgorA 851
end if
852
if INTERP_RGB eq 1
5175 IgorA 853
		mov eax,[drdl_min]
854
		add [r1],eax
855
		mov eax,[dgdl_min]
856
		add [g1],eax
857
		mov eax,[dbdl_min]
858
		add [b1],eax
5153 IgorA 859
end if
860
if INTERP_ST eq 1
5175 IgorA 861
		mov eax,[dsdl_min]
862
		add [s1],eax
863
		mov eax,[dtdl_min]
864
		add [t1],eax
5153 IgorA 865
end if
866
if INTERP_STZ eq 1
5175 IgorA 867
		fld dword[dszdl_min]
868
		fadd dword[sz1]
869
		fstp dword[sz1]
870
		fld dword[dtzdl_min]
871
		fadd dword[tz1]
872
		fstp dword[tz1]
5153 IgorA 873
end if
5175 IgorA 874
	.end_er:
875
			; right edge
876
			mov eax,[dx2dy2]
877
			add [x2],eax
878
 
879
			; screen coordinates
880
			mov ebx,[zb]
881
			mov eax,[ebx+offs_zbuf_linesize]
882
			add [pp1],eax
883
			mov eax,[ebx+offs_zbuf_xsize]
884
			shl eax,1
885
			add [pz1],eax
886
			jmp .beg_w_lin
887
		.end_w_lin:
888
		inc dword[part]
889
		cmp dword[part],2
890
		jl .cycle_0
891
	.end_f:
5187 IgorA 892
popad
5175 IgorA 893
	ret
894
endp
895
 
5153 IgorA 896
restore INTERP_Z
897
restore INTERP_RGB
898
restore INTERP_ST
899
restore INTERP_STZ
5175 IgorA 900
restore DRAW_LINE_M
5153 IgorA 901
 
902
purge DRAW_INIT
5175 IgorA 903
purge DRAW_LINE
5153 IgorA 904
purge PUT_PIXEL