/[projet1]/users/chema/TINE/oobj3d/obj3d.s
Defence Force logotype

Contents of /users/chema/TINE/oobj3d/obj3d.s

Parent Directory Parent Directory | Revision Log Revision Log


Revision 354 - (show annotations)
Sun Jun 27 19:32:47 2010 UTC (9 years, 9 months ago) by Chema
File size: 37899 byte(s)
First tweaks after the BETA1 version

Changed the way rear view is patched, so no it is in obj3d.s before calling GLOBROT. Is much more efficient.

Also corrected an error with this, as only Z component was inverted, and not also X component. This also meant changes into stars.s which also had some errors in rear view...

Tweaked the rotation of the initial screen ships, and added the hermit as type of ship (but not yet created in universe.s)
1 ;
2 ; lib3d extensions
3 ;
4 ; A collection of routines which extends
5 ; the 3d library, adding routines for creating,
6 ; manipulating, and rendering objects.
7 ;
8 ; SLJ March/April 1999
9 ;
10 ; Obj3d
11 ; Oric port Chema 2008
12 ;
13 ;
14 ; Idea Maintain a list of objects.
15
16 ; Get constants in an include file..
17 #include "obj3d.h"
18 #include "params.h"
19
20
21 ; Now some internal (not visible) variables
22
23 _NumObjs
24 NUMOBJS .byt 00 ;Number of objects
25 NUMCENTS .byt 00 ;Number of object senter
26 CUROBJ .byt 00 ;Current object
27 LASTOBJ .byt 00
28 ZMAX .word $2300 ;Maximum range
29 ZMIN .byt 50 ;Minimum range
30 OBJECTS .word $0800 ;Object records 1227 = 3456 bytes = $0D80
31
32
33 NUMLINES .byt 00 ;This is for the line-drawing... I think. Defined below in the original
34
35 ;===============================
36
37 ; Zero page variables
38
39 .zero
40
41 __obj3d_zeropage_start
42
43 RTEMPA .byt 00
44 RTEMPX .byt 00
45 RTEMPY .byt 00
46 TEMP .word 00 ;two bytes
47 POINT .word 00 ;two bytes
48
49 ; This is for the line-plotting routine
50 ; Coordinates are 16-bit
51
52 /*X1 .word 00 ;Line x-coord
53 Y1 .word 00
54 X2 .word 00
55 Y2 .word 00
56 */
57
58 ; This is for polygon drawing or C64 specific ???
59
60 ;BITMAP .word $B9 ;Page of bitmap base
61 ;FILLPAT .word $BB ;Pointer to fill pattern
62
63
64 __obj3d_zeropage_end
65
66 .text
67
68 __obj3d_start
69
70 ;Lines drawn
71 ;speeds up wireframe
72 ; Oric port This is the same I already used.
73 ; 100 bytes instead of $67.
74
75 #define MAXLINES 39;100
76 LINELO .dsb 40;100
77 LINEHI .dsb 40;100
78
79 #ifdef USEOBLETS
80 #define OBHEAD $2F-1 ;Head of list = $55FF Oric port Just the size of OBLETS
81 OBLETS .dsb OBHEAD+1 ;Oblet list
82 #endif
83
84 .dsb 256-(*&255)
85 PLISTX .dsb (MAXVERTEX*2) ;Point lists (projected)
86 PLISTY .dsb (MAXVERTEX*2)
87 PLISTZ .dsb (MAXVERTEX*2)
88
89 // META
90 VISOBJS .dsb 129
91 OBCEN .dsb MAXOBJS ;Center object #
92 ;Note will bug if 128 vis objs
93
94 OBJLO .dsb MAXOBJS ;Object pointers
95 OBJHI .dsb MAXOBJS ;if 0 then empty
96
97 CX .dsb MAXOBJS ;Rotated/relative centers
98 HCX .dsb MAXOBJS
99 CY .dsb MAXOBJS
100 HCY .dsb MAXOBJS
101 CZ .dsb MAXOBJS
102 HCZ .dsb MAXOBJS
103
104 #ifdef AVOID_INVISBLEVERTICES
105 #define MAXV 28
106 vertex2proj .dsb MAXV
107 #endif
108
109
110 ; Some stuff from lib3D
111
112 #define MATRIX A11 ; Local rotation Matrix
113 #define VIEWMAT VA11 ; Viewpoint rotation matrix
114
115
116 ; Now let's go to the code...
117
118
119 ;
120 ; Initialize lib3d pointers, variables
121 ;
122 ; On entry .AY = pointer to object records
123 ;
124
125 Init3D
126 .(
127 STA OBJECTS
128 STY OBJECTS+1
129
130 jsr _lib3dInit ; Initialize lib3D Oric Version
131 /*
132 lda #<PLISTX
133 sta PLISTXLO
134 lda #<PLISTY
135 sta PLISTYLO
136 lda #<PLISTZ
137 sta PLISTZLO
138
139 lda #>PLISTX
140 sta PLISTXLO+1
141 lda #>PLISTY
142 sta PLISTYLO+1
143 lda #>PLISTZ
144 sta PLISTZLO+1
145
146
147 lda #<(PLISTX+MAXVERTEX)
148 sta PLISTXHI
149 lda #<(PLISTY+MAXVERTEX)
150 sta PLISTYHI
151 lda #<(PLISTZ+MAXVERTEX)
152 sta PLISTZHI
153
154 lda #>(PLISTX+MAXVERTEX)
155 sta PLISTXHI+1
156 lda #>(PLISTY+MAXVERTEX)
157 sta PLISTYHI+1
158 lda #>(PLISTZ+MAXVERTEX)
159 sta PLISTZHI+1
160 */
161 LDX #<CX
162 STX CXLO
163 LDX #<CY
164 STX CYLO
165 LDX #<CZ
166 STX CZLO
167
168 LDX #>CX
169 STX CXLO+1
170 LDX #>CY
171 STX CYLO+1
172 LDX #>CZ
173 STX CZLO+1
174
175
176 LDX #<HCX
177 STX CXHI
178 LDX #<HCY
179 STX CYHI
180 LDX #<HCZ
181 STX CZHI
182
183 LDX #>HCX
184 STX CXHI+1
185 LDX #>HCY
186 STX CYHI+1
187 LDX #>HCZ
188 STX CZHI+1
189
190 ;LDX #159 ;(0,0) = center of screen
191 ;LDY #99
192
193 ; Oric port Let's put center in center )
194
195 ldx #CENTER_X
196 ldy #CENTER_Y
197 NOM STX XOFFSET
198 STY YOFFSET
199
200
201 +_EmptyObj3D
202 LDA #$FF
203 STA CUROBJ
204 LDA #00
205 STA NUMOBJS
206 STA LASTOBJ
207 sta NUMCENTS
208
209 LDY #00 ;Zero out object pointers
210 TYA
211 L1 STA OBJHI,Y
212 INY
213 ;BPL L1 ;128 entries
214 cpy #MAXOBJS
215 bne L1
216
217 RTS
218 .)
219
220 ;
221 ; AddObj -- Add object to object list
222 ;
223 ; On entry .AY = pointer to object point data
224 ; .X = optional ID byte
225 ;
226 ; On exit .AY = pointer to object
227 ; .X = object number
228 ; C set indicates an error
229 ;
230
231 AddObj
232 .(
233 sta RTEMPA
234 sty RTEMPY
235 stx RTEMPX
236
237 ldx #00 ;Find open slot
238 txa
239 sta tmp
240 clc
241 loop ldy OBJHI,x
242 beq found
243 adc #ObjSize ;32 bytes per record
244 bcc c1
245 inc tmp
246 clc
247 c1 inx
248 bpl loop
249 sec
250 rts
251
252 found adc OBJECTS
253 sta POINT
254 sta OBJLO,x
255 lda tmp
256 adc OBJECTS+1
257 sta POINT+1
258 sta OBJHI,x
259 inc NUMOBJS
260 cpx LASTOBJ
261 bcc init
262 stx LASTOBJ
263 init
264 ldy #ObjSize-1 ;Init object
265 lda #00
266 l2 sta (POINT),y
267 dey
268 bpl l2
269
270 lda #64 ;Identity matrix
271 ldy #ObjMat
272 sta (POINT),y
273 ldy #ObjMat+4
274 sta (POINT),y
275 ldy #ObjMat+8
276 sta (POINT),y
277
278 ldy #ObjID
279 lda RTEMPX ;ID
280 sta (POINT),y
281
282 lda RTEMPY ;Obj data pointer
283 dey
284 sta (POINT),y
285 lda RTEMPA
286 dey
287 sta (POINT),y
288
289 +SetCurOb stx CUROBJ
290 +GetCurOb ldx CUROBJ
291 +GetObj lda OBJLO,x
292 ldy OBJHI,x
293 clc
294 rts
295
296 .)
297
298
299 ;
300 ; DelObj -- Remove object from list
301 ; by setting high byte=0
302 ;
303 ; On entry .X = object number
304 ; C set means serious error!
305 ;
306
307 DelObj
308 .(
309 LDA #00
310 STA OBJHI,X
311 LDA NUMOBJS
312 BEQ end
313 DEC NUMOBJS
314 CPX LASTOBJ ;Last object in list
315 BCC end
316 L1 LDA OBJHI,X
317 BNE save_X
318 DEX
319 BPL L1
320 SEC ;Out of objects!
321 INX
322 save_X STX LASTOBJ
323 end RTS
324 .)
325
326
327 ;
328 ; GetNextOb -- Get next object in list
329 ;
330 ; On exit .X = object number
331 ; .AY= object pointer
332 ; C set indicates error
333 ; Current object set to .X
334 ;
335 GetNextOb
336 .(
337 ;LDA NUMOBJS
338 ;BEQ ERR
339 LDX CUROBJ
340 ;BMI ERR
341 CPX LASTOBJ
342 BCC C1
343 LDX #$FF
344 C1 INX
345 LDY OBJHI,X
346 BEQ C1
347 LDA OBJLO,X
348 STX CUROBJ
349 ;CLC
350 RTS
351 /*
352 ERR SEC
353 RTS
354 */
355 .)
356
357
358
359 ;-------------------------------
360 ;
361 ; Object manipulation routines
362 ;
363 ;-------------------------------
364
365 ;
366 ; SetMat -- Calculate matrix for current object
367 ;
368 ; On entry .A = Angle around z-axis
369 ; .Y = Angle around y-axis
370 ; .X = Angle around x-axis
371 ;
372 SetMat
373 .(
374 JSR CALCMAT ;Result -> MATRIX
375 LDX CUROBJ
376 BMI done
377 LDA OBJLO,X
378 CLC
379 ADC #ObjMat ;Matrix
380 STA POINT
381 LDA OBJHI,X
382 ADC #00
383 STA POINT+1
384
385 LDA #00
386 LDY #17
387 L2 STA (POINT),Y ;Zero remainder
388 DEY
389 CPY #8
390 BNE L2
391
392 LOOP LDA MATRIX,Y
393 STA (POINT),Y
394 DEY
395 BPL LOOP
396
397 done RTS
398 .)
399
400
401 ;
402 ; Yaw/Pitch/Roll -- Accumulate a rotation on current object
403 ;
404 ; On entry C clear -> positive rotation
405 ; C set -> negative rotation
406 ;
407
408 GetCurMat
409 .(
410 PHP
411 JSR GetCurOb
412 CLC
413 ADC #ObjMat
414 BCC save_P
415 INY
416 save_P PLP
417 RTS
418
419 +Pitch
420 JSR GetCurMat
421 JMP ACCROTX
422 +Yaw
423 JSR GetCurMat
424 JMP ACCROTY
425 +Roll
426 JSR GetCurMat
427 JMP ACCROTZ
428 .)
429
430
431 ;
432 ; MoveDown/Side/Forwards -- Move object along its
433 ; (local) X Y or Z axis.
434 ;
435 ; Note that orientation matrix is inverse of object matrix
436 ;
437 ; On entry .A = velocity (signed)
438 ;
439
440 .(
441 MOVRTS RTS
442 +MoveDown
443 LDY #ObjMat ;Row 1
444 .byt $2C
445 +MoveSide
446 LDY #ObjMat+3 ;Row 2
447 .byt $2C
448 +MoveForwards
449 LDY #ObjMat+6
450 STY RTEMPY ;Object offset
451 CMP #00
452 BEQ MOVRTS
453 STA MultLo1 ;Plain signed multply
454 STA MultHi1
455 EOR #$FF
456 CLC
457 ADC #01
458 STA MultLo2
459 STA MultHi2
460
461 LDX CUROBJ
462 BMI MOVRTS
463 LDA OBJLO,X
464 STA POINT
465 LDA OBJHI,X
466 STA POINT+1
467
468 LDA (POINT),Y
469 TAY
470 LDA #ObjCXRem
471 LDX #ObjCX
472 JSR MovMult
473
474 LDY RTEMPY
475 INY
476 STY RTEMPY
477 LDA (POINT),Y
478 TAY
479 LDA #ObjCYRem
480 LDX #ObjCY
481 JSR MovMult
482
483 LDY RTEMPY
484 INY
485 LDA (POINT),Y
486 TAY
487 LDA #ObjCZRem
488 LDX #ObjCZ
489
490 MovMult
491 STX RTEMPX ;Coord
492 STA RTEMPA ;Remainder
493 LDA (MultLo1),Y
494 SEC
495 SBC (MultLo2),Y
496 STA TEMP
497 LDA (MultHi1),Y
498 SBC (MultHi2),Y
499 CPY #$80 ;Fix up signs
500 BCC POS1
501 SBC MultLo1
502 POS1 LDX MultLo1
503 BPL DIV
504 STY TEMP+1
505 SEC
506 SBC TEMP+1
507
508 DIV STA TEMP+1 ;Now div by 16
509 LDY #00
510 AND #$FF
511 BPL POSA
512 DEY ;High byte
513 POSA TYA
514 ASL TEMP
515 ROL TEMP+1
516 ROL
517 ASL TEMP
518 ROL TEMP+1
519 ROL
520 ASL TEMP
521 ROL TEMP+1
522 ROL
523 ASL TEMP
524 ROL TEMP+1
525 ROL
526
527 TAX
528 LDA TEMP
529 LDY RTEMPA ;Remainder
530 CLC
531 ADC (POINT),Y
532 STA (POINT),Y
533 LDY RTEMPX ;Coord
534 LDA TEMP+1
535 ADC (POINT),Y
536 STA (POINT),Y
537 INY
538 TXA
539 ADC (POINT),Y
540 STA (POINT),Y
541 RTS
542 .)
543
544 ;
545 ; GetDown/Side/FrontVec
546 ;
547 ; Get orientation vector
548 ; On entry Current object set
549 ; On exit (.X,.Y,.A) = (X,Y,Z) signed
550 ; direction vector, length=64
551 ;
552
553 GetDownVec
554 LDY #ObjMat ;Row 1
555 .byt $2C
556 GetSideVec
557 LDY #ObjMat+3 ;Row 2
558 .byt $2C
559 GetFrontVec
560 .(
561 LDY #ObjMat+6
562
563 LDX CUROBJ
564 BMI done
565 LDA OBJLO,X
566 STA POINT
567 LDA OBJHI,X
568 STA POINT+1
569
570 LDA (POINT),Y
571 TAX
572 INY
573 INY
574 LDA (POINT),Y
575 PHA
576 DEY
577 LDA (POINT),Y
578 TAY
579 PLA
580 done RTS
581
582 .)
583
584
585
586 ;-------------------------------
587 ;
588 ; Visualization routines
589 ;
590 ;-------------------------------
591
592 ViewObj .byt 00 ;Viewpoint object
593 ;SOLIDPOL .byt 00 ;Solid/wireframe polygons
594
595 ; Oric Port There is NO Pattern table, so point anywhere...
596 ;PATTAB .word $1000 ;Pattern table
597
598 ;
599 ; SetParms -- Set rendering parameters
600 ;
601 ; On entry .AY = Pointer to pattern table
602 ; .X = Bitmap page
603 ; C set -> solid polygons
604 ; C clear -> wireframe
605 ;
606
607 ;SetParms
608 ; ROR SOLIDPOL
609 ; STA PATTAB
610 ; STY PATTAB+1
611 ; STX BITMAP
612 ; RTS
613
614 ;
615 ; SetVisParms -- Set visibility parms
616 ;
617 ; On entry .AY = Maximum object range
618 ; .X = Minimum object range
619 ;
620
621 ;SetVisParms
622 ; STA ZMAX
623 ; STY ZMAX+1
624 ; STX ZMIN
625 ; RTS
626
627 ;
628 ; CalcView -- Calculate view (Set viewpoint, translate and rotate centers)
629 ;
630 ; On entry .X = viewpoint object
631 ;
632 ; On exit: translated rotated centers
633 ; in CX/CY/CZ
634 ;
635
636 CalcView
637 .(
638 STX ViewObj
639 JSR SetCurOb
640 STA POINT
641 STY POINT+1
642
643 LDX #8
644 LDY #ObjMat+8
645 loop
646 LDA (POINT),Y ;Viewpoint matrix
647 STA VIEWMAT,X
648 DEY
649 DEX
650 BPL loop
651
652
653 +_patch_invertZ
654 ;jsr invertZmat
655 nop
656 nop
657 nop
658
659 LDX #11 ;Set up pointers
660 cl LDA CXLO,X
661 STA C0XLO,X
662 DEX
663 BPL cl
664
665 LDX #00
666 STX RTEMPX ;Object index
667
668 getloop JSR GetNextOb
669 CPX ViewObj
670 BEQ done
671
672 STA TEMP
673 STY TEMP+1
674 TXA
675 LDX RTEMPX
676 STA OBCEN,X ;Object number
677 TXA
678 LDY #ObjCenPos ;Position in center list
679 STA (TEMP),Y
680
681 LDY #00
682 LDA (TEMP),Y ;Translate
683 SEC
684 SBC (POINT),Y
685 STA CX,X
686 INY
687 LDA (TEMP),Y
688 SBC (POINT),Y
689 STA HCX,X
690
691 INY
692 LDA (TEMP),Y ;Translate
693 SEC
694 SBC (POINT),Y
695 STA CY,X
696 INY
697 LDA (TEMP),Y
698 SBC (POINT),Y
699 STA HCY,X
700
701 INY
702 LDA (TEMP),Y ;Translate
703 SEC
704 SBC (POINT),Y
705 STA CZ,X
706 INY
707 LDA (TEMP),Y
708 SBC (POINT),Y
709 STA HCZ,X
710
711 INC RTEMPX
712 BPL getloop
713 done
714 LDY RTEMPX ;# of objects
715 STY NUMCENTS
716
717 JMP GLOBROT ;off she goes!
718 .)
719
720
721 invertZmat
722 .(
723 .(
724 ldy #8
725 ldx #3
726 loop
727 sec
728 lda #0
729 sbc VIEWMAT,y
730 sta VIEWMAT,y
731 dey
732 dex
733 bne loop
734 .)
735
736 .(
737 ldy #2
738 loop
739 sec
740 lda #0
741 sbc VIEWMAT,y
742 sta VIEWMAT,y
743 dey
744 bpl loop
745 .)
746
747 rts
748 .)
749
750
751
752 ;
753 ; SortVis -- Compute and sort all visible objects
754 ;
755 ; On entry centers stored in CX etc.
756 ;
757 ; On exit VisObjs = linked list of visible objects
758 ; (farthest objects at start of list)
759 ;
760 ; Visibility conditions
761 ; x+z>0, x-z<0 (within view area)
762 ; same for x+y/x-y
763 ; z > 8192 will be treated as too far away to see
764 ; z < 180 is treated as being too near.
765 ;
766
767 NUMVIS .byt 00
768
769 SortVis
770 .(
771 LDA #00
772 STA NUMVIS
773 LDA #$80
774 STA VISOBJS+$80
775 LDX NUMCENTS
776 DEX
777 bpl loop
778 rts
779 loop
780
781 LDA HCZ,X ;high byte
782 STA TEMP+1
783 LDA CZ,X ;low byte
784 STA TEMP
785
786 ; Check if object is not affected
787 ; by distance skipping
788 lda OBCEN,x
789 tay
790 lda OBJLO,y
791 sta tmp3
792 lda OBJHI,y
793 sta tmp3+1
794 ldy #ObjData ; Get pointer to data
795 lda (tmp3),y
796 sta pdata+1
797 iny
798 lda (tmp3),y
799 sta pdata+2
800 pdata
801 lda $1234 ; Get ObjType
802 beq normal
803 cmp #5 ; is it 1,2 or 4 ? Then planet, sun or moon
804 /*
805 bcs normal
806
807 lda TEMP+1
808 cmp #$60
809 bcs SKIP
810 bcc checkmin */
811
812 bcc checkmin
813
814 normal
815 /*
816 lda TEMP
817 CMP ZMAX
818 LDA TEMP+1
819 SBC ZMAX+1 ;Greater than 8192?
820 BCS SKIP ;(or negative)
821 */
822 lda TEMP+1
823 bmi SKIP
824
825 checkmin
826 LDA TEMP
827 CMP ZMIN
828 LDA TEMP+1
829 SBC #00
830 BCC SKIP
831
832 LDA TEMP ;x+z>0
833 CLC
834 ADC CX,X
835 LDA TEMP+1
836 ADC HCX,X
837 BMI SKIP
838
839 LDA TEMP ;z-x>0
840 CMP CX,X
841 LDA TEMP+1
842 SBC HCX,X
843 BMI SKIP
844
845 LDA TEMP ;y+z>0
846 CLC
847 ADC CY,X
848 LDA TEMP+1
849 ADC HCY,X
850 BMI SKIP
851
852 LDA TEMP ;z-y>0
853 CMP CY,X
854 LDA TEMP+1
855 SBC HCY,X
856 BMI SKIP
857
858 LDY #$80 ;Head of list
859 l1 LDA VISOBJS,Y ;Linked list of objects
860 BMI link
861 STY RTEMPY
862 TAY ;Next object
863 LDA CZ,Y ;If farther, then
864 CMP TEMP ;move down list
865 LDA HCZ,Y
866 SBC TEMP+1
867 BCS l1
868 ;Nearest objects last in list
869 TYA
870 LDY RTEMPY ;Insert into list
871
872 link STA VISOBJS,X ;X -> rest of list
873 TXA
874 STA VISOBJS,Y ;beginning of list -> X
875 dex
876 bmi next
877 jmp loop
878 SKIP
879 lda CX,x
880 sta _vertexXLO,x
881 lda HCX,x
882 sta _vertexXHI,x
883 lda CY,x
884 sta _vertexYLO,x
885 lda HCY,x,
886 sta _vertexYHI,x
887 lda TEMP+1 ;HCZ,x
888 bpl isok
889 stx savx+1
890 jsr _gen_rnd_number
891 savx
892 ldx #0 ;SMC
893 ora #%1
894 sta _vertexXHI,x
895 lda _rnd_seed+3
896 ora #%1
897 sta _vertexYHI,x
898
899 isok
900 dex
901 bmi next
902 jmp loop
903 next
904 LDY #$80
905 STY COB ;Current object
906 done RTS
907
908 .)
909
910
911
912 ;
913 ; DrawAllVis -- Draw all visible objects
914 ; in linked list.
915 ;
916 COB .byt 00 ;Current object
917 .(
918 DrawLoop
919 STY COB
920 ldx OBCEN,y ;Actual object number
921
922 JSR RotDraw
923
924 ldy COB
925 ldx OBCEN,y
926
927 jsr GetObj
928 sta POINT ;Object pointer
929 sty POINT+1
930
931 ; Is the object far away?
932 ldy #ObjCenPos
933 lda (POINT),Y
934 tay
935 lda HCZ,y
936 cmp #12
937 bcc normal
938 lda #0 ; Use vertex 0
939 beq patch
940 normal
941 ; Get ship ID byte...
942 ldy #ObjID
943 lda (POINT),y
944 and #%01111111
945 beq DrawAllVis
946 tay
947
948 ; Save the (projected) laser vertex for each visible ship
949 ; I hate this, because uses information and routines out of
950 ; oobj3d, but this saves time and space, so... (
951
952 lda ShipLaserVertex-1,y
953 patch
954 tay
955 lda PLISTX,y
956 sta _vertexXLO,x
957 lda PLISTX+MAXVERTEX,y
958 sta _vertexXHI,x
959 lda PLISTY,y
960 sta _vertexYLO,x
961 lda PLISTY+MAXVERTEX,y
962 sta _vertexYHI,x
963
964 +DrawAllVis
965 LDX COB ;Head = #$80
966 LDY VISOBJS,X
967 BPL DrawLoop
968 done
969 DrawRTS RTS
970
971
972
973 ;
974 ; GetNextVis -- Get next object in
975 ; visible list.
976 ;
977 ; On exit N set indicates end of list
978 ;
979 +GetNextVis
980 LDX COB
981 LDY VISOBJS,X
982 BMI DrawRTS
983 php
984 STY COB
985 ldx OBCEN,y
986 LDA #00
987 STA NUMLINES
988 jsr SetCurOb
989 plp
990 rts
991 .)
992
993 ; .dsb 256-(*&255)
994
995
996 ;
997 ; RotDraw -- Rotate and draw an object
998 ;
999 ; On entry Object number in .X
1000 ; SetParms already called.
1001 ;
1002 DATAP .word 0 ;Temp pointer
1003 NPOINTS .byt 00
1004 OBTYPE .byt 00
1005
1006 NFACES .byt 00 ;Faces/Oblets
1007
1008 RotDraw
1009 .(
1010 LDA OBJLO,X
1011 STA POINT
1012 LDA OBJHI,X
1013 STA POINT+1
1014
1015 LDY #ObjMat ;Matrix -> ZP
1016 LDX #00
1017 STX NUMLINES
1018 mli STX TEMP
1019 LDA #3
1020 STA TEMP+1
1021 ml LDA (POINT),Y ;Take transpose to get
1022 STA MATRIX,X ;orientation matrix
1023 INY
1024 INX
1025 INX
1026 INX
1027 DEC TEMP+1
1028 BNE ml
1029 LDX TEMP
1030 INX
1031 CPX #3
1032 BNE mli
1033
1034 LDY #ObjCenPos
1035 LDA (POINT),Y
1036 STA RTEMPA ;Position of center in list
1037
1038 LDY #ObjData ;Get data pointer for later
1039 LDA (POINT),Y
1040 STA DATAP
1041 TAX
1042 INY
1043 LDA (POINT),Y
1044 STA DATAP+1
1045 STA POINT+1
1046 STX POINT
1047
1048 ; Check model to see if we can use a far model alternative
1049 LDY #00
1050 LDA (POINT),Y
1051 STA OBTYPE ;Object's type
1052
1053 and #%01111111
1054 bne normalmodel
1055
1056 ldx RTEMPA
1057 lda HCZ,x
1058 cmp #11
1059 bcc normalmodel
1060 cmp #17
1061 bcc easymodel
1062 lda #DEBRIS
1063 sta OBTYPE
1064 lda #<ONEDOT
1065 sta DATAP
1066 sta POINT
1067 lda #>ONEDOT
1068 sta DATAP+1
1069 sta POINT+1
1070 jmp normalmodel
1071 easymodel
1072 lda #<CAPSULE
1073 sta DATAP
1074 sta POINT
1075 lda #>CAPSULE
1076 sta DATAP+1
1077 sta POINT+1
1078 normalmodel
1079 INY
1080 LDA (POINT),Y ;Number of points
1081 ;BEQ done
1082 bne cont
1083 rts
1084 cont
1085 STA NPOINTS
1086 INY
1087 LDA (POINT),Y
1088 STA NFACES
1089 iny
1090 tya
1091 clc
1092 adc POINT
1093 sta P0X
1094 ldx POINT+1
1095 bcc cc1
1096 inx
1097 clc
1098 cc1
1099 stx P0X+1
1100 adc NFACES
1101 sta P0Y
1102 bcc cc2
1103 inx
1104 clc
1105 cc2
1106 stx P0Y+1
1107 adc NFACES
1108 sta P0Z
1109 bcc cc3
1110 inx
1111 clc
1112 cc3
1113 stx P0Z+1
1114
1115 #ifdef AVOID_INVISBLEVERTICES
1116 lda OBTYPE
1117 and #%01111111
1118 bne patchme
1119 lda NFACES
1120 bne skipthis
1121 patchme
1122 .(
1123 ldx #(MAXV-1)
1124 lda #1
1125 l3
1126 sta vertex2proj,x
1127 dex
1128 bpl l3
1129 .)
1130 jmp end_prepare_normals
1131 skipthis
1132 #else
1133 lda NFACES
1134 beq end_prepare_normals
1135 #endif
1136
1137 jmp prepare_normals
1138 +end_prepare_normals
1139
1140 lda NFACES ; Point pointers
1141 clc
1142 adc P0Z
1143 sta P0X
1144 ldx P0Z+1
1145 BCC c1
1146 INX
1147 CLC
1148 c1 STX P0X+1
1149 ADC NPOINTS
1150 STA P0Y
1151 BCC c2
1152 INX
1153 CLC
1154 c2 STX P0Y+1
1155 ADC NPOINTS
1156 STA P0Z
1157 BCC c3
1158 INX
1159 CLC
1160 c3 STX P0Z+1
1161 ADC NPOINTS
1162 STA FACEPTR
1163 TXA
1164 ADC #00
1165 STA FACEPTR+1
1166
1167 LDY NPOINTS
1168 LDX RTEMPA ;Center index
1169 SEC ;Rot and proj
1170 JSR ROTPROJ
1171
1172 LDA NFACES ;Maybe just want tointsate p
1173 BEQ done
1174 LDA FACEPTR
1175 LDY FACEPTR+1
1176 LDX OBTYPE ; Draw depending on object type.
1177
1178 #ifdef USEOBLETS
1179 BMI Compound
1180 #endif
1181 beq dloop
1182
1183 cpx #PLANET ; Sun or planet object
1184 beq FilledCircle
1185
1186 cpx #MOON
1187 beq SmallFilledCircle ; A Moon
1188
1189 cpx #DEBRIS ; Space debris
1190 beq SmallDot
1191
1192 ; Can't reach here. Either it is Compound (branches to Compound)
1193 ; or it is normal (0), so branching to dloop, or one of the above
1194 ; options. All those branches end with RTS.
1195
1196 dloop ;JSR DrawFace
1197 jmp DrawFace
1198 +draw_face_end
1199 DEC NFACES
1200 BNE dloop
1201 done RTS
1202
1203 .)
1204
1205
1206
1207 FilledCircle
1208 .(
1209 jsr CirclePrepare
1210
1211 ldx RTEMPA
1212 lda HCZ,x
1213 lsr
1214 sta op2+1
1215 lda CZ,x
1216 ror
1217 sta op2
1218
1219 lda #$ff
1220 sta op1
1221 sta op1+1
1222 jsr divu
1223 txa
1224 cmp #2
1225 bcs normal
1226 small
1227 lda #2
1228 normal
1229 sta rad
1230 lda #0
1231 sta rad+1
1232 jmp _circleMidpoint
1233 .)
1234
1235
1236 SmallFilledCircle
1237 .(
1238 jsr CirclePrepare
1239
1240 ldx RTEMPA
1241 lda HCZ,x
1242 sta op2+1
1243 lda CZ,x
1244 sta op2
1245
1246 lda #$00
1247 sta op1
1248 lda #$40
1249 sta op1+1
1250 jsr divu
1251 txa
1252 bne notzero
1253 lda #1
1254 notzero
1255 sta rad
1256 lda #0
1257 sta rad+1
1258 jmp _circleMidpoint
1259 .)
1260
1261
1262
1263 SmallDot
1264 .(
1265 STA POINT
1266 STY POINT+1
1267
1268 ldx RTEMPA
1269 lda HCZ,x
1270 bmi end
1271 cmp ZMAX+1
1272 bcs end
1273
1274 ldy #2
1275 lda (POINT),y
1276 tax
1277
1278 lda PLISTX+MAXVERTEX,x
1279 ;sta X1+1
1280 ora PLISTY+MAXVERTEX,x
1281 beq test2
1282 end
1283 rts
1284 test2
1285 lda PLISTX,x
1286 sta X1
1287 lda PLISTY,x
1288 sta Y1
1289
1290 ;; Plots debris (a point) at given X1,Y1 position (signed 16-bit)
1291 ;; after clipping
1292
1293 ldy Y1
1294 cpy #(CLIP_BOTTOM)
1295 bcs end
1296 cpy #(CLIP_TOP)
1297 bcc end
1298
1299 ldx X1
1300 jsr draw_dot
1301 ldy Y1
1302 ldx X1
1303 inx
1304 beq end
1305 ;inc X1+1
1306 ; Let the program flow
1307 .)
1308
1309 draw_dot
1310 .(
1311 ;lda X1+1
1312 ;bne end
1313 cpx #(CLIP_RIGHT)
1314 bcs end
1315 cpx #(CLIP_LEFT)
1316 bcc end
1317
1318 jsr pixel_address
1319 eor (tmp0),y
1320 sta (tmp0),y
1321 end
1322 rts
1323 .)
1324
1325
1326
1327 #ifdef USEOBLETS
1328 ;
1329 ; Compound objects are made up of
1330 ; a smaller number of "oblets",
1331 ; drawn in order after sorting their
1332 ; reference points.
1333 ;
1334
1335
1336 COBLET .byt 00 ;Current oblet
1337 OBLPTR .word 00 ;Pointer to oblets
1338
1339 Compound
1340 .(
1341 STA POINT
1342 STY POINT+1
1343 CLC
1344 ADC NFACES
1345 STA OBLPTR
1346 TYA
1347 ADC #00
1348 STA OBLPTR+1
1349
1350 LDA #OBHEAD
1351 STA OBLETS+OBHEAD ;Head of list
1352 DEC NFACES
1353
1354 sort LDY NFACES ;Number of oblets
1355 LDA (POINT),Y ;= # ref points
1356 TAX
1357 LDA PLISTZ,X
1358 STA TEMP
1359 LDA PLISTZ+MAXVERTEX,X
1360 STA TEMP+1
1361
1362 LDX NFACES ;Current oblet
1363 LDY #OBHEAD ;Head of list
1364 l1 LDA OBLETS,Y ;Linked list
1365 CMP #OBHEAD
1366 BCS link
1367 STY RTEMPY
1368 TAY ;Next object
1369 LDA PLISTZ,Y ;If farther, then
1370 CMP TEMP ;move down list
1371 LDA PLISTZ+MAXVERTEX,Y
1372 SBC TEMP+1
1373 BCS l1
1374 ;Nearest objects last in list
1375 TYA
1376 LDY RTEMPY ;Insert into list
1377 link STA OBLETS,X ;X -> rest of list
1378 TXA
1379 STA OBLETS,Y ;beginning of list -> X
1380 DEC NFACES
1381 BPL sort
1382 ;Now draw them
1383 LDY #OBHEAD
1384 loop
1385 ldx OBLETS,y
1386
1387 STX COBLET
1388 CPX #OBHEAD
1389 BCS done
1390 LDA OBLPTR+1
1391 STA POINT+1
1392 LDA OBLPTR ;Locate it
1393 STA POINT
1394 CPX #00
1395 BEQ draw
1396
1397 LDY #00
1398 CLC
1399 l2 ADC (POINT),Y
1400 STA POINT
1401 BCC decx
1402 INC POINT+1
1403 CLC
1404 decx DEX
1405 BNE l2
1406
1407 draw LDY #1
1408 LDA (POINT),Y ;Number of faces
1409 STA NFACES
1410 LDY POINT+1
1411 LDA POINT
1412 CLC
1413 ADC #2
1414 BCC dloop
1415 INY
1416 dloop JSR DrawFace
1417 DEC NFACES
1418 BNE dloop
1419
1420 LDY COBLET
1421 BPL loop
1422 done RTS
1423
1424 .)
1425 #endif
1426
1427
1428 ;
1429 ; DrawFace -- Draw a polygon
1430 ;
1431 ; On entry .AY points to face data
1432 ; On exit .AY points to next face
1433 ;
1434 ; Wireframe C clear -> face not drawn
1435 ;
1436
1437 NVERTS .byt 00 ;Number of vertices
1438 FACEPTR .word 00 ;Pointer to face
1439
1440 DrawFace
1441 .(
1442 STA POINT
1443 STY POINT+1
1444
1445 LDY #00
1446 LDA (POINT),Y
1447 STA NVERTS
1448 SEC ;N+1 in list
1449 ADC #2 ;(closes on itself)
1450 ADC POINT
1451 STA FACEPTR ;Next face
1452 LDA #00
1453 STA TEMP
1454 ADC POINT+1
1455 STA FACEPTR+1
1456
1457 #ifdef FILLEDPOLYS
1458 LDY #1 ;Fill pattern
1459 LDA (POINT),Y ;index
1460 ASL
1461 ROL TEMP
1462 ASL
1463 ROL TEMP
1464 ASL
1465 ROL TEMP
1466 sta _CurrentPattern
1467
1468 lda NVERTS
1469 BEQ exit ; Empty face
1470
1471 lsr facevis+2
1472 ror facevis+1
1473 ror facevis
1474 bcc exit
1475
1476 JSR POLYFILL
1477
1478 #else
1479 ;Wireframe routine
1480 Wire
1481 lsr facevis+2
1482 ror facevis+1
1483 ror facevis
1484 bcc exit
1485
1486 LDY #2 ;Connect the dots...
1487 l2 LDA (POINT),Y
1488 TAX
1489 LDA PLISTX,X
1490 STA X1
1491 LDA PLISTX+MAXVERTEX,X
1492 STA X1+1
1493 LDA PLISTY,X
1494 STA Y1
1495 LDA PLISTY+MAXVERTEX,X
1496 STA Y1+1
1497 STX RTEMPA
1498
1499 INY
1500 LDA (POINT),Y
1501 TAX
1502 LDA PLISTX,X
1503 STA X2
1504 LDA PLISTX+MAXVERTEX,X
1505 STA X2+1
1506 LDA PLISTY,X
1507 STA Y2
1508 LDA PLISTY+MAXVERTEX,X
1509 STA Y2+1
1510 STY RTEMPY
1511
1512
1513 ; Check for line connections
1514 ; Points in RTEMPA and .X
1515 LDY #00
1516 loop CPY NUMLINES
1517 BEQ store
1518 TXA
1519 CMP LINELO,Y
1520 BNE test2
1521 LDA RTEMPA
1522 CMP LINEHI,Y
1523 BEQ skip
1524 incy INY
1525 BPL loop
1526 store LDA RTEMPA
1527 STA LINELO,Y
1528 TXA
1529 STA LINEHI,Y
1530 CPY #MAXLINES
1531 BEQ godraw
1532 INC NUMLINES
1533
1534 godraw
1535 JSR _DrawClippedLine
1536
1537 skip LDY RTEMPY
1538 DEC NVERTS
1539 BNE l2
1540
1541
1542 SEC
1543 BCS exit
1544 test2 CMP LINEHI,Y
1545 BNE incy
1546 LDA RTEMPA
1547 CMP LINELO,Y
1548 BNE incy
1549 BEQ skip
1550
1551 #endif
1552
1553 exit LDA FACEPTR
1554 LDY FACEPTR+1
1555 ;RTS
1556 jmp draw_face_end
1557 .)
1558
1559
1560 #ifdef FILLEDPOLYS
1561
1562
1563 POLYFILL
1564 .(
1565 LDY #2 ;Connect the dots...
1566 l2 LDA (POINT),Y
1567 TAX
1568 LDA PLISTX,X
1569 STA X1
1570 LDA PLISTX+MAXVERTEX,X
1571 STA X1+1
1572 LDA PLISTY,X
1573 STA Y1
1574 LDA PLISTY+MAXVERTEX,X
1575 STA Y1+1
1576 ;STX RTEMPA
1577
1578 INY
1579 LDA (POINT),Y
1580 TAX
1581 LDA PLISTX,X
1582 STA X2
1583 LDA PLISTX+MAXVERTEX,X
1584 STA X2+1
1585 LDA PLISTY,X
1586 STA Y2
1587 LDA PLISTY+MAXVERTEX,X
1588 STA Y2+1
1589
1590 STY RTEMPY
1591
1592 jsr _DrawClippedLine ;_AddLineASM
1593
1594
1595 LDY RTEMPY
1596 DEC NVERTS
1597 BNE l2
1598
1599 jmp _FillTablesASM
1600 ;rts
1601 .)
1602
1603 #endif
1604
1605
1606 CirclePrepare
1607 .(
1608 STA POINT
1609 STY POINT+1
1610
1611 #ifdef FILLEDPOLYS
1612 lda #0
1613 sta TEMP
1614 LDY #1 ;Fill pattern
1615 LDA (POINT),Y ;index
1616 ASL
1617 ROL TEMP
1618 ASL
1619 ROL TEMP
1620 ASL
1621 ROL TEMP
1622 sta _CurrentPattern
1623 #endif
1624 ldy #2
1625 lda (POINT),y
1626
1627 tax
1628 ldy #0
1629 lda PLISTX,x
1630 sta cx
1631 lda PLISTX+MAXVERTEX,x
1632 sta cx+1
1633
1634 lda PLISTY,x
1635 sta cy
1636 lda PLISTY+MAXVERTEX,x
1637 sta cy+1
1638
1639 #ifdef 0
1640 ldx RTEMPA
1641 lda HCZ,x
1642 tax
1643 bne done
1644 inx
1645 done
1646 #endif
1647 rts
1648 .)
1649
1650
1651 #define cx_ tmp3
1652 #define cy_ tmp4
1653 #define cz_ tmp5
1654 #define tempx op2
1655
1656 #ifdef AVOID_INVISBLEVERTICES
1657 .zero
1658 pface .word 0000
1659
1660 .text
1661 prepare_normals
1662 .(
1663 ; Prepare call to ROTPROJ in mode "Rotation only"
1664 LDY NFACES
1665 LDX RTEMPA ;Center index
1666 CLC ;Rot and NOT proj
1667 JSR ROTPROJ
1668
1669 ; Initialize the information about vertices
1670 ; which belong to a visible face at least
1671
1672 ldx #(MAXV-1)
1673 lda #0
1674 l3
1675 sta vertex2proj,x
1676 dex
1677 bpl l3
1678
1679 ; Initialize pointer to face data
1680 lda NPOINTS
1681 asl
1682 adc NPOINTS
1683 adc NFACES
1684
1685 adc P0Z
1686 sta pface
1687 ldx P0Z+1
1688 bcc c1
1689 inx
1690 c1 stx pface+1
1691
1692 ; Save center coordinates in cx_, cy_, cz_ for later.
1693 ldx RTEMPA
1694 lda CX,x
1695 sta cx_
1696 lda HCX,x
1697 sta cx_+1
1698
1699 lda CY,x
1700 sta cy_
1701 lda HCY,x
1702 sta cy_+1
1703
1704 lda CZ,x
1705 sta cz_
1706 lda HCZ,x
1707 sta cz_+1
1708
1709 ; If too far we patch code below and avoid calculating the
1710 ; dot product between the normal and the view vector.
1711 ; Just will use the normal Z sign.
1712
1713 cmp #5
1714 bcc nopatch
1715
1716 lda #$18 ; clc opcode
1717 sta _patch_code
1718 jmp startcheck
1719
1720 nopatch
1721 lda #$38 ; sec opcode
1722 sta _patch_code
1723
1724
1725 ; Adjust center coordinates, so they are 7-bit signed and SMULT can be used
1726 loopadj
1727 lda cx_+1
1728 beq conty
1729 bpl shift
1730 eor #$ff
1731 bne shift
1732 conty
1733 lda cy_+1
1734 beq contz
1735 bpl shift
1736 eor #$ff
1737 bne shift
1738 contz
1739 lda cz_+1
1740 beq endloop
1741 shift
1742 lda cx_+1
1743 cmp #$80
1744 ror cx_+1
1745 ror cx_
1746
1747 lda cy_+1
1748 cmp #$80
1749 ror cy_+1
1750 ror cy_
1751
1752 ; Z is allways positive (or it won't be visible)
1753 lsr cz_+1
1754 ror cz_
1755
1756 jmp loopadj
1757 endloop
1758
1759 ; We need two more adjustments
1760 ; To be sure the amount is 7-bit signed (-64..64).
1761
1762 lda cx_+1
1763 cmp #$80
1764 ror
1765 ror cx_
1766 cmp #$80
1767 ror
1768 ror cx_
1769 sta cx_+1
1770
1771 lda cy_+1
1772 cmp #$80
1773 ror
1774 ror cy_
1775 cmp #$80
1776 ror
1777 ror cy_
1778 sta cy_+1
1779
1780 ; Z is allways positive (or it wouldn't be visible)
1781 lsr cz_+1
1782 ror cz_
1783 lsr cz_+1
1784 ror cz_
1785
1786 startcheck
1787
1788 ; Prepare facevis bitfield.
1789
1790 lda #0
1791 sta facevis
1792 sta facevis+1
1793 sta facevis+2
1794
1795
1796 ; Loop through face list. Can't do this backwards, as pointer to face has to be updated
1797 ; and we don't know where it ends...
1798 ldx #0
1799 stx tempx
1800 loop
1801 ; First check. If all normals are zero, face is visible
1802 ldx tempx
1803 lda PLISTX,x
1804 ora PLISTY,x
1805 ora PLISTZ,x
1806 bne cont
1807 jmp vis
1808 cont
1809
1810 _patch_code
1811 sec ; This is patched to clc or sec
1812 bcs cont2
1813 lda PLISTZ,x
1814 bpl noneg
1815 jmp novis
1816 noneg
1817 jmp vis
1818 cont2
1819
1820 ; For each face we need to calculate the dot-product
1821 ; of the center and the normal.
1822 ; <cx_,cy_,cz_>*<nx,ny,nz>=
1823 ; cx_*nx+cy_*ny+cz_*nz.
1824 ; All within range of SMULT
1825 ; op1 (2-byte) will store the 16-bit result
1826
1827 lda #0
1828 sta op1+1
1829
1830 lda PLISTX,x
1831 ldy cx_
1832 SMULT
1833 sta op1
1834 bpl doY
1835 dec op1+1
1836 doY
1837 lda #0
1838 sta tmp
1839 lda PLISTY,x
1840 ldy cy_
1841 SMULT
1842 bpl noneg1
1843 dec tmp
1844 noneg1
1845 clc
1846 adc op1
1847 sta op1
1848 lda tmp
1849 adc op1+1
1850 sta op1+1
1851
1852 doZ
1853 lda #0
1854 sta tmp
1855 lda PLISTZ,x
1856 ldy cz_
1857 SMULT
1858 bpl noneg2
1859 dec tmp
1860 noneg2
1861 clc
1862 adc op1
1863 sta op1
1864 lda tmp
1865 adc op1+1
1866 sta op1+1
1867
1868 doneall
1869 bmi novis
1870 lda op1+1
1871 ora op1
1872 bne vis
1873 ;bpl vis
1874 ;beq vis
1875 novis
1876 clc
1877 ror facevis+2
1878 ror facevis+1
1879 ror facevis
1880 jmp next
1881 vis
1882 sec
1883 ror facevis+2
1884 ror facevis+1
1885 ror facevis
1886
1887 ; Iterate through face points, marking those
1888 ; which are used in this (visible) face
1889 ldy #0
1890 lda (pface),y
1891 clc
1892 adc #2
1893 tay
1894 loopf
1895 ;lda $dead,y
1896 lda (pface),y
1897 tax
1898 inc vertex2proj,x
1899 dey
1900 cpy #2
1901 bne loopf
1902
1903 next
1904 ldx tempx
1905 inx
1906 cpx NFACES
1907 beq end
1908
1909 stx tempx
1910
1911 ldy #0
1912 lda (pface),y
1913 clc
1914 adc #3
1915 adc pface
1916 sta pface
1917 bcc upface
1918 inc pface+1
1919 upface
1920 jmp loop
1921 end
1922 ; Rotate what is left
1923 lda #24
1924 sec
1925 sbc NFACES
1926 tax
1927 lda facevis
1928 loopend
1929 lsr facevis+2
1930 ror facevis+1
1931 ror ;facevis
1932 dex
1933 bne loopend
1934 sta facevis
1935
1936 ; Get ship ID byte...
1937 ldy #ObjID
1938 lda (POINT),y
1939 and #%01111111
1940 tay
1941 ldx ShipLaserVertex-1,y
1942 inc vertex2proj,x
1943 jmp end_prepare_normals
1944 .)
1945
1946 #else
1947 prepare_normals
1948 .(
1949 ; Prepare call to ROTPROJ in mode "Rotation only"
1950 ldy NFACES
1951 ldx RTEMPA ;Center index
1952 clc ;Rot and NOT proj
1953 jsr ROTPROJ
1954
1955 ; Save center coordinates in cx_, cy_, cz_ for later.
1956 ldx RTEMPA
1957 lda CX,x
1958 sta cx_
1959 lda HCX,x
1960 sta cx_+1
1961
1962 lda CY,x
1963 sta cy_
1964 lda HCY,x
1965 sta cy_+1
1966
1967 lda CZ,x
1968 sta cz_
1969 lda HCZ,x
1970 sta cz_+1
1971
1972 ; If too far we patch code below and avoid calculating the
1973 ; dot product between the normal and the view vector.
1974 ; Just will use the normal Z sign.
1975
1976 cmp #5
1977 bcc nopatch
1978
1979 lda #$18 ; clc opcode
1980 sta _patch_code
1981 jmp startcheck
1982
1983 nopatch
1984 lda #$38 ; sec opcode
1985 sta _patch_code
1986
1987 ; Adjust center coordinates, so they are 7-bit signed and SMULT can be used
1988 loopadj
1989 lda cx_+1
1990 beq conty
1991 bpl shift
1992 eor #$ff
1993 bne shift
1994 conty
1995 lda cy_+1
1996 beq contz
1997 bpl shift
1998 eor #$ff
1999 bne shift
2000 contz
2001 lda cz_+1
2002 beq endloop
2003 shift
2004 lda cx_+1
2005 cmp #$80
2006 ror cx_+1
2007 ror cx_
2008
2009 lda cy_+1
2010 cmp #$80
2011 ror cy_+1
2012 ror cy_
2013
2014 ; Z is allways positive (or it won't be visible)
2015 lsr cz_+1
2016 ror cz_
2017
2018 jmp loopadj
2019 endloop
2020
2021 ; We need two more adjustments
2022 ; To be sure the amount is 7-bit signed (-64..64).
2023
2024 lda cx_+1
2025 cmp #$80
2026 ror
2027 ror cx_
2028 cmp #$80
2029 ror
2030 ror cx_
2031 sta cx_+1
2032
2033 lda cy_+1
2034 cmp #$80
2035 ror
2036 ror cy_
2037 cmp #$80
2038 ror
2039 ror cy_
2040 sta cy_+1
2041
2042 ; Z is allways positive (or it wouldn't be visible)
2043 lsr cz_+1
2044 ror cz_
2045 lsr cz_+1
2046 ror cz_
2047
2048 startcheck
2049 ; Prepare facevis bitfield.
2050
2051 lda #0
2052 sta facevis
2053 sta facevis+1
2054 sta facevis+2
2055
2056
2057 ; Loop through face list
2058 ldx NFACES
2059 dex
2060 stx tempx
2061 loop
2062 ; First check. If all normals are zero, face is visible
2063 ldx tempx
2064 lda PLISTX,x
2065 ora PLISTY,x
2066 ora PLISTZ,x
2067 bne cont
2068 sec
2069 jmp vis
2070 cont
2071
2072 _patch_code
2073 sec ; This is patched to clc or sec
2074 bcs cont2
2075 lda PLISTZ,x
2076 bpl noneg
2077 clc
2078 jmp vis
2079 noneg
2080 sec
2081 jmp vis
2082 cont2
2083
2084
2085 ; For each face we need to calculate the dot-product
2086 ; of the center and the normal.
2087 ; <cx_,cy_,cz_>*<nx,ny,nz>=
2088 ; cx_*nx+cy_*ny+cz_*nz.
2089 ; All within range of SMULT
2090 ; op1 (2-byte) will store the 16-bit result
2091
2092 lda #0
2093 sta op1+1
2094
2095 lda PLISTX,x
2096 ldy cx_
2097 SMULT
2098 sta op1
2099 bpl doY
2100 dec op1+1
2101 doY
2102 lda #0
2103 sta tmp
2104 lda PLISTY,x
2105 ldy cy_
2106 SMULT
2107 bpl noneg1
2108 dec tmp
2109 noneg1
2110 clc
2111 adc op1
2112 sta op1
2113 lda tmp
2114 adc op1+1
2115 sta op1+1
2116
2117 doZ
2118 lda #0
2119 sta tmp
2120 lda PLISTZ,x
2121 ldy cz_
2122 SMULT
2123 bpl noneg2
2124 dec tmp
2125 noneg2
2126 clc
2127 adc op1
2128 sta op1
2129 lda tmp
2130 adc op1+1
2131 sta op1+1
2132
2133 doneall
2134 sec
2135 bmi novis
2136 lda op1+1
2137 ora op1
2138 bne vis
2139 ;bpl vis
2140 ;beq vis
2141 novis
2142 clc
2143 vis
2144 rol facevis
2145 rol facevis+1
2146 rol facevis+2
2147 dec tempx
2148 bmi end
2149 jmp loop
2150 end
2151 ;rts
2152 jmp end_prepare_normals
2153 .)
2154
2155
2156 #endif
2157
2158
2159 .zero
2160 facevis .dsb 3
2161 .text
2162
2163
2164
2165
2166 __obj3d_end
2167
2168 #echo obj3d: Memory usage
2169 #echo obj3d: Zero page:
2170 #print (__obj3d_zeropage_end - __obj3d_zeropage_start)
2171 #echo obj3d: Normal memory:
2172 #print (__obj3d_end - __obj3d_start)
2173
2174
2175
2176
2177

  ViewVC Help
Powered by ViewVC 1.1.26