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

  ViewVC Help
Powered by ViewVC 1.1.26