gclipl.s
12.6 KB
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
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
##########################################################################
#
# line clipping code
# simplification of general polygon clipper
#
##########################################################################
.name v1, $1 # pointer to vertex structure for first point
.name v2, $2 # pointer to vertex structure for second point
.name cc1, $19 # clip code for first point
.name cc2, $17 # clip code for second point
.name tAcc, $5 # points are a trivial accept?
.name tRej, $6 # points are a trivial reject?
.name voutp, $7
.name tmp, $8
.ent doClip
doClip:
# SIMPLE BYPASS OF THE CLIPPER
# j lineSetup
# store return address to gimm.s loop
sw return, RSP_L_0(zero)
# initialize pointer to scratch mem, used for
# creation of new points
addi voutp, zero, (((RSP_SCRATCH_OFFSET + 7) & 0xfff8) - RSP_PTS_LEN)
lh tmp, NEXTCLIP($0)
sh tmp, RETURNJUMP($0)
lh cc1, RSP_PTS_CC(v1)
lh cc2, RSP_PTS_CC(v2)
# check for trivial accept, or clip codes
or tAcc, cc1, cc2
# if cc1 | cc2 = 0, then trivial accept
beq tAcc, zero, lineSetup
# check for trivial reject, and clip codes
and tRej, cc1, cc2
# if cc1 & cc2 = 0, then nontrivial accept
beq tRej, zero, nonTrivialAccept
nop
# else we have a trivial reject, so go back
# to the processing loop and skip the line
# setup code
jr return
.unname tAcc
.unname tRej
.name straddle, $5
.name plane, $6
.name cc1Mask, $12
.name cc2Mask, $13
.name clipMask, $14
nonTrivialAccept:
# At this point we need to loop through the 5 (or 6)
# clip planes and do a clip compare against each one
# plane = 2*current plane being tested, use a factor
# of two so that we get the right clipmask loaded in
addi plane, zero, 12
nextClip:
# if we have cycled through all the planes then we're
# done, so jump to the line setup routine
beq plane, zero, lineSetup
# otherwise decrement plane by 2 to point to next
addi plane, 0xfffe
# reload clip codes after possible clipping
lh cc1, RSP_PTS_CC(v1)
lh cc2, RSP_PTS_CC(v2)
# now load in the clip mask for the current plane
# being tested against
lh clipMask, CLIPMASKS(plane)
# construct the clip masks against the current plane
# to see if we have a straddle
and cc1Mask, cc1, clipMask
and cc2Mask, cc2, clipMask
or straddle, cc1Mask, cc2Mask
# if cc1Mask and cc2Mask are both zero, then the
# line does not intersect this clip plane, so move
# along
beq straddle, zero, nextClip
nop
.name OutPt, $20
.name InPt, $10
SetupInOut:
# At this point we have a straddled plane, so we
# need to compute the intersection with it
# increment pointer to scratch buffer for next generated point
addi voutp, voutp, RSP_PTS_LEN
beq cc1Mask, zero, v2Out
v1Out:
add OutPt, v1, zero
add InPt, v2, zero
j IntersectPlane
# now set up v1 so that when we return
# to nextclip we'll be using the original inside
# point and the newly calculated outside point
# delay slot
add v1, voutp, zero
v2Out:
add InPt, v1, zero
add OutPt, v2, zero
# now set up v2 so that when we return
# to nextclip we'll be using the original inside
# point and the newly calculated outside point
add v2, voutp, zero
.unname straddle
.unname cc1Mask
.unname cc2Mask
.unname clipMask
.unname cc1
.unname cc2
.unname OutPt
.unname InPt
# BELOW IS MOSTLY COPIED OUT OF NATHAN'S POLYGON CLIPPING CODE
.name newlist, $17 # new list of vertices
.name oldlist, $5 # old list of vertices
.name prevpoint, $20 # point preceding current point
.name pointptr, $10 # point to current point
.name ini, $v4 # non clipped points vector
.name inf, $v5
.name outi, $v9 # clipped points vector
.name outf, $v10
.name topi, $v11 # numerator of n calculation
.name topf, $v12
.name boti, $v27 # denominator of n calculation
.name botf, $v26
.name selp, $v1 # select which plane we are clipping against
.name seln, $v0 # negative of selp
.name nf, $v15 # parameter of clip (0.16)
.name negnf, $v8 # 1 - parameter of clip (0.16)
.name vtmpi, $v29 # temporary vector
.name vtmpf, $v28 # temporary vector
IntersectPlane:
ldv outi[0],RSP_PTS_X_INT(pointptr) # get XYZW of in and out
ldv outf[0],RSP_PTS_X_FRAC(pointptr) # vertices
ldv ini[0],RSP_PTS_X_INT(prevpoint) #
ldv inf[0],RSP_PTS_X_FRAC(prevpoint) #
#
sll tmp,plane,2 # plane to select
ldv selp[0],(CLIP_SELECT)(tmp) # select vector
vmudh seln,selp,vconst[3] # negative select vector
# ----------------------------
# CALCULATE n (comments assume
# positive x plane clipping,
# so selp=[1 0 0 -1])
# xyz= in point; XYZ=out point
#-----------------------------
vmudn topf,inf,selp # top=[x 0 0 -w]
vmadh topi,ini,selp #
vmadn topf,vconst,vconst[0] #
#-----------------------------
vmadn vtmpf,outf,seln # bot= [-X 0 0 W] + top =
vmadh vtmpi,outi,seln # [(x-X) 0 0 (W-w)]
vmadn vtmpf,vconst,vconst[0] #
#-----------------------------
vaddc botf,vtmpf,vtmpf[0q] # add all componants together
vadd boti,vtmpi,vtmpi[0q] # (2 of X,Y,Z are zero)
vaddc vtmpf,botf,botf[1h] # ... into element 3
#
vadd vtmpi,boti,boti[1h] # result = [? ? ? (x-X)-(w-W)]
#
#-----------------------------
#
.name wsclf, $v3 # calculate scalefactor to
.name wscli, $v7 # improve reciprical precision
#
mfc2 tmp,vtmpi[6] # sign of bot
#
vrcph wscli[3], vtmpi[3] # scalefactor wscl
vrcpl wsclf[3], vtmpf[3] # for greater precision in
vrcph wscli[3], vconst[0] # reciprical
#
#
vmudn wsclf, wsclf, vconst[2] # *2 to complete reciprical
bgez tmp, clampWscl # branch if non negative
vmadh wscli, wscli, vconst[2] # *2 to complete reciprical
#
### BRANCH OCCURS TO clampWscl: IF wscl>=0 #
#------------------------------
vmudn wsclf, wsclf, vconst[3] # *-1 for absolute value
vmadh wscli, wscli, vconst[3] # *-1 for absolute value
clampWscl: #------------------------------
veq wscli,wscli,vconst[0] # if wscl >= 1.0
vmrg wsclf,wsclf,vconst[3] # then wsclf = 0.99999
# (only wsclf used; not wscl)
#------------------------------
vmudl vtmpf, vtmpf, wsclf[3] # use scalefactor wsclf for 1/x
vmadm vtmpi, vtmpi, wsclf[3] # (improves 1/x precicion)
jal NewtonDiv #
vmadn vtmpf, vconst, vconst[0] #
#------------------------------
### JUMP OCCURS to subroutine NewtonDiv: # bot= 1/vtmp
#------------------------------
vaddc vtmpf,topf,topf[0q] # add all componants together
vadd vtmpi,topi,topi[0q] # (2 of X,Y,Z are zero)
vaddc topf,vtmpf,vtmpf[1h] # ... into element 3
vadd topi,vtmpi,vtmpi[1h] # result = [? ? ? (x-w)]
#------------------------------
vmudl nf,topf,botf # n= top * 1/bot
vmadm nf,topi,botf #
vmadn nf,topf,boti #
vmadh negnf,topi,boti #
#------------------------------
vmudl vtmpf, vconst, vconst[5] # add 0.0003fffc (~0.0004)
# to ensure outside of frustum
#
vmadl nf, nf, wsclf[3] # remove scalefcator wsclf
vmadm negnf, negnf, wsclf[3] #
vmadn nf, vconst, vconst[0] #
#------------------------------
.unname wscli # done with scalefactor
.unname wsclf #
#------------------------------
veq negnf,negnf,vconst[0] # if number >=1
#ww j skipWMul
vmrg nf,nf,vconst[3] # then number = 0.99999
#wwnegWLoop:
#ww mfc2 tmp, nf[6] # get nf
#ww addi tmp, tmp, -1 # compare to 1
#ww beq tmp, zero, skipWLoop # too small
#ww nop
#ww vmudl nf, nf, vconst1[1] # make smaller
#ww
#wwskipWMul:
vne nf,nf,vconst[0] # if number =0
vmrg nf,nf,vconst[1] # then number = 0.00001
#---------------------------
vnxor negnf,nf,vconst[0] # negnf[0h] = 1-n (0.16)
vaddc negnf,negnf,vconst[1] # ones complement + 1 of frac
vadd vtmpi,vtmpi,vtmpi # VCO=0
########### SET UP REGISTERS TO MATCH screenCalc: in gvtx.s ##############
#-----------------------------------------------------------------------
# THESE NEED TO BE LOADED WITH APPROPRIATE DATA TO SAVE TO VERTICES
#......................................#
.unname boti # bot now called persp12
.unname botf #
.name invW12f, $v26 #
.name invW12i, $v27 #
.name st12, $v18 # S and T
#......................................#
.name clr1, $15 # RGBA new point 1
#......................................#
.name clr2, $16 # NOT TOUCHED !!!!
#
#-----------------------------------------------------------------------
# THESE NEED TO BE SET UP FOR THE VTX ROUTINE TO WORK
#......................................#
.unname selp #
.name vptrans, $v1 # loaded by getScaleTrans subroutine
#......................................#
.unname seln #
.name vpscale, $v0 # loaded by getScaleTrans subroutine
#......................................#
.name i, $9 # indicate 1 vertex to process
# (the clipped vertex)
#-----------------------------------------------------------------------
# THESE NEED TO BE AVAILABLE #
#......................................#
.unname newhdl #
.name flg2, $14 #
#......................................#
.unname vtmpi #
.name vout12i, $v29 #
#......................................#
.unname vtmpf #
.name vout12f, $v28 #
#......................................#
.name flg1, $13 #
.name vtmp, $v3 #
.name scrn12f, $v7 #
.name scrn12i, $v6 #
.name vin12, $v2 #
#......................................#
.unname tmp # No change here
.name tmp, $8 #
#......................................#
.name vnewton1, $v22 # used for newton raphson subroutine
.name vnewton2, $v23 #
.name vnewton3, $v24 #
.name vnewton4, $v25 #
# .name vnewton5, $v26 # invW12f
# .name vnewton6, $v27 # invW12i
# .name vnewton7, $v28 # vout12f
# .name vnewton8, $v29 # vout12i
#......................................
# CALCULATE new values for
# coordinates & attributes
#---------------------------
vmudl vout12f,inf,negnf[3h] # in * (1-n)
vmadm vout12i,ini,negnf[3h] #
vmadl vout12f,outf,nf[3h] # ... + (out * n)
vmadm vout12i,outi,nf[3h] #
vmadn vout12f,vconst,vconst[0] # = new xyzw
#---------------------------
######### START W>0 LOOP ####################
# mfc2 tmp, vout12i[6] # sign of resultant W
# blez tmp, negWLoop # loop if W<=0
#ww vch topf, vout12i, vout12i[3h] # is z > -w ?
#ww vcl topf, vout12f, vout12f[3h] #
#ww cfc2 tmp, $vcc # get result from VCC
#ww andi tmp, tmp, 0x0004 # is z > -w ?
#ww bne tmp, zero, negWLoop # make smaller
# NOTE DELAY SLOT BELOW
######### END W>0 LOOP ####################
#......................................#
.unname inf #
.name persp12f, $v5 #
#......................................#
.unname ini #
.name persp12i, $v4 #
#......................................#
#wwskipWLoop:
#---------------------------
luv topf[0],RSP_PTS_R_NX(pointptr) # topf[0-6] = RGBAout
luv topi[0],RSP_PTS_R_NX(prevpoint) # topi[0-6] = RGBAin
#---------------------------
llv topf[8],RSP_PTS_S(pointptr) # topf[8,10] = STout
llv topi[8],RSP_PTS_S(prevpoint) # topi[8,10] = STin
#---------------------------
vmudm st12,topf,nf[3] # st12 = new ST & RGBA
vmadm st12,topi,negnf[3] #
#---------------------------
suv st12[0],0(voutp) # temp store new RGBA
sdv st12[8],8(voutp) #
ldv st12[0],8(voutp) #
jal getScaleTrans # get screen scale & trans
lw clr1,0(voutp) # new RGBA 1
#---------------------------
### BRANCH OCCURS to subroutine getScaleTrans: # load regs for screenCalc
#---------------------------
# mfc2 pointptr,ptptrhold[0] # restore pointptr
j screenCalc # calc screen coord & store
ori i,$0,1 # setup for vtx routine
#
### JUMP OCCURS to screenCalc: subroutine; return to nextPlane:
#---------------------------
.unname vout12i #
.unname vout12f #
.unname flg1 #
.unname flg2 #
.unname clr1 #
.unname clr2 #
.unname st12 #
.unname vptrans #
.unname vpscale #
.unname i #
.unname vtmp #
.unname invW12f #
.unname invW12i #
.unname scrn12f #
.unname scrn12i #
.unname vin12 #
.unname vnewton1 #
.unname vnewton2 #
.unname vnewton3 #
.unname vnewton4 #
#
.unname voutp #
.unname persp12i #
.unname persp12f #
.unname outi #
.unname outf #
.unname topi #
.unname topf #
.unname nf #
.unname negnf #
#
.unname pointhdl #
.unname prevpoint #
.unname pointptr #
.unname plane #
.unname clipmask #
.unname state #
.unname inoutcheck #
.unname ptptrhold #
#
#
# ########################### END CLIPPING ###############################
.unname minp #
.unname midp #
.unname maxp #
#
.align 8 # even out the end for DMA's
.unname v1
.unname v2
.unname newlist
.unname oldlist
.unname tmp
.end doClip