@@ -613,13 +613,22 @@ private static IReadOnlyList<IMesh> TryToAddChosenPart0Tuple_(
613613 . PrimitiveDisplayListSegmentedAddresses )
614614 . ToArray ( ) ;
615615
616+ var nonzeroMeshCount
617+ = meshDefinition . MeshSegmentedAddresses . Count ( a => a != 0 ) ;
618+
616619 var addedDisplayList = false ;
617620 var meshes = new List < IMesh > ( ) ;
618621 for ( var i = 0 ; i < 4 ; ++ i ) {
619622 var ( meshSegmentedAddress ,
620623 vertexDlSegmentedAddress ,
621624 primitiveDlSegmentedAddress ) = tuples [ i ] ;
622625
626+ var isLast = i == nonzeroMeshCount - 1 ;
627+
628+ // HACK: Surely there's a better way to determine this???
629+ var usePattern
630+ = ( primitiveDlSegmentedAddress != 0 || ! isLast ) && i != 3 ;
631+
623632 if ( meshSegmentedAddress != 0 &&
624633 n64Hardware . Memory
625634 . TryToOpenPossibilitiesAtSegmentedAddress (
@@ -645,7 +654,7 @@ private static IReadOnlyList<IMesh> TryToAddChosenPart0Tuple_(
645654 var primitiveDlOffset = sbr . ReadUInt32 ( ) ;
646655 var vertexDlOffset = sbr . ReadUInt32 ( ) ;
647656
648- // Not really sure why, but sometimes these aren't set.
657+ // HACK: Not really sure why, but sometimes these aren't set.
649658 if ( primitiveDlSegmentedAddress == 0 ) {
650659 primitiveDlSegmentedAddress
651660 = meshSegmentedAddress + primitiveDlOffset ;
@@ -664,6 +673,9 @@ private static IReadOnlyList<IMesh> TryToAddChosenPart0Tuple_(
664673
665674 ResetRspAndRdp_ ( n64Hardware ) ;
666675
676+ // HACK: This branching if is based on what seems to work, but ideally
677+ // this should be based on decomp.
678+ // Check decomp, at 0x80116a9c
667679 var withTexture = imageCount > 0 ;
668680 if ( chosenPart0 == skinChosenPart ) {
669681 SetCombiner_ ( n64Hardware ,
@@ -673,28 +685,20 @@ private static IReadOnlyList<IMesh> TryToAddChosenPart0Tuple_(
673685 chosenPart0 . ChosenColor0 . Color . ToSystemColor ( ) ) ,
674686 chosenPart0 . Pattern0MaterialType ) ;
675687 } else {
676- SetCombiner_ ( n64Hardware ,
677- withTexture ,
678- false ,
679- OneOf < uint , Color > . FromT0 (
680- i == 1
681- ? chosenPart0 . Pattern1SegmentedAddress
682- : chosenPart0 . Pattern0SegmentedAddress ) ,
683- i == 1
684- ? chosenPart0 . Pattern1MaterialType
685- : chosenPart0 . Pattern0MaterialType ) ;
688+ if ( usePattern ) {
689+ SetCombinerForPattern_ ( n64Hardware , chosenPart0 , i , withTexture ) ;
690+ } else {
691+ SetAdditiveBlending_ ( n64Hardware ) ;
692+ SetCombiner_ ( n64Hardware , withTexture , true ) ;
693+ }
686694 }
687695 } else {
688- SetCombiner_ ( n64Hardware ,
689- true ,
690- false ,
691- OneOf < uint , Color > . FromT0 (
692- i == 1
693- ? chosenPart0 . Pattern1SegmentedAddress
694- : chosenPart0 . Pattern0SegmentedAddress ) ,
695- i == 1
696- ? chosenPart0 . Pattern1MaterialType
697- : chosenPart0 . Pattern0MaterialType ) ;
696+ if ( usePattern ) {
697+ SetCombinerForPattern_ ( n64Hardware , chosenPart0 , i , true ) ;
698+ } else {
699+ SetAdditiveBlending_ ( n64Hardware ) ;
700+ SetCombiner_ ( n64Hardware , true , true ) ;
701+ }
698702 }
699703
700704 if ( primitiveDlSegmentedAddress == 0 ) {
@@ -704,7 +708,8 @@ private static IReadOnlyList<IMesh> TryToAddChosenPart0Tuple_(
704708 n64Hardware . Rsp . CullingMode
705709 = GetCullingModeForChosenPartId_ ( chosenPart0 . Id ) ;
706710
707- var primitiveDlVertexMatrix = Matrix4x4 . CreateScale ( originalFlipByBone [ childBone ] ) ;
711+ var primitiveDlVertexMatrix
712+ = Matrix4x4 . CreateScale ( originalFlipByBone [ childBone ] ) ;
708713 var primitiveDlBoneWeights = model . Skin . GetOrCreateBoneWeights (
709714 VertexSpace . RELATIVE_TO_BONE ,
710715 childBone ) ;
@@ -733,15 +738,15 @@ jointIndex is not ((int) JointIndex.UPPER_ARM_1
733738 ( uint , Matrix4x4 ? , IBoneWeights ) [ ] displayLists
734739 = vertexDlSegmentedAddress == 0
735740 ? [
736- ( primitiveDlSegmentedAddress ,
741+ ( primitiveDlSegmentedAddress ,
737742 primitiveDlVertexMatrix ,
738743 primitiveDlBoneWeights )
739744 ]
740745 : [
741- ( vertexDlSegmentedAddress ,
742- vertexMatrix ,
746+ ( vertexDlSegmentedAddress ,
747+ vertexMatrix ,
743748 vertexDlBoneWeights ) ,
744- ( primitiveDlSegmentedAddress ,
749+ ( primitiveDlSegmentedAddress ,
745750 primitiveDlVertexMatrix ,
746751 primitiveDlBoneWeights )
747752 ] ;
@@ -869,6 +874,29 @@ private static void ResetRspAndRdp_(IN64Hardware n64Hardware) {
869874 rdp . M1 = BlenderPm . G_BL_CLR_IN ;
870875 rdp . B1 = BlenderB . G_BL_1 ;
871876 rdp . CycleType = CycleType . TWO_CYCLE ;
877+
878+ rdp . UseCoverageForAlpha = true ;
879+ }
880+
881+ private static void SetAdditiveBlending_ ( IN64Hardware n64Hardware ) {
882+ var rsp = n64Hardware . Rsp ;
883+ rsp . UvType = N64UvType . LINEAR ;
884+ rsp . EnvironmentColor = Color . White ;
885+ rsp . PrimColor = Color . White ;
886+
887+ var rdp = n64Hardware . Rdp ;
888+ rdp . ForceBlending = true ;
889+ rdp . P0 = BlenderPm . G_BL_CLR_MEM ;
890+ rdp . A0 = BlenderA . G_BL_A_IN ;
891+ rdp . M0 = BlenderPm . G_BL_CLR_IN ;
892+ rdp . B0 = BlenderB . G_BL_1MA ;
893+ rdp . P1 = BlenderPm . G_BL_CLR_MEM ;
894+ rdp . A1 = BlenderA . G_BL_A_IN ;
895+ rdp . M1 = BlenderPm . G_BL_CLR_IN ;
896+ rdp . B1 = BlenderB . G_BL_1MA ;
897+ rdp . CycleType = CycleType . TWO_CYCLE ;
898+
899+ rdp . UseCoverageForAlpha = false ;
872900 }
873901
874902 private static IMesh ? AddDisplayLists_ (
@@ -932,6 +960,32 @@ var displayList
932960 return mesh ;
933961 }
934962
963+ private static void SetCombinerForPattern_ (
964+ IN64Hardware < N64Memory > n64Hardware ,
965+ ChosenPart0 chosenPart0 ,
966+ int patternI ,
967+ bool withTexture ) {
968+ var isMark = patternI == 2 ;
969+ SetCombiner_ ( n64Hardware ,
970+ withTexture ,
971+ isMark ,
972+ OneOf < uint , Color > . FromT0 (
973+ patternI switch {
974+ 0 => chosenPart0 . Pattern0SegmentedAddress ,
975+ 1 => chosenPart0 . Pattern1SegmentedAddress ,
976+ 2 => chosenPart0 . MarkSegmentedAddress ,
977+ } ) ,
978+ patternI switch {
979+ 0 => chosenPart0 . Pattern0MaterialType ,
980+ 1 => chosenPart0 . Pattern1MaterialType ,
981+ 2 => chosenPart0 . MarkMaterialType ,
982+ } ) ;
983+
984+ if ( isMark ) {
985+ SetAdditiveBlending_ ( n64Hardware ) ;
986+ }
987+ }
988+
935989 private static void SetCombiner_ (
936990 IN64Hardware < N64Memory > n64Hardware ,
937991 bool withTexture0 ,
@@ -1008,8 +1062,34 @@ private static void SetCombiner_(
10081062 CombinerCycleParams . FromTexture0AndShade ( withAlpha ) ) ;
10091063 break ;
10101064 }
1065+ case ( false , not null ) : {
1066+ if ( patternSegmentedOffsetOrColor . Value . TryPickT0 (
1067+ out var patternSegmentedOffset ,
1068+ out var color ) ) {
1069+ rdp . Tmem . SetImageSimple (
1070+ patternSegmentedOffset ,
1071+ N64ColorFormat . RGBA ,
1072+ BitsPerTexel . _16BPT ,
1073+ 32 ,
1074+ 32 ,
1075+ F3dWrapMode . REPEAT ,
1076+ F3dWrapMode . REPEAT ,
1077+ 0 ,
1078+ shift ) ;
1079+
1080+ rdp . SetCombinerCycleParams (
1081+ CombinerCycleParams . FromTexture0AndShade ( withAlpha ) ) ;
1082+ } else {
1083+ rdp . SetCombinerCycleParams (
1084+ CombinerCycleParams . FromPrimitiveAndLighting ( withAlpha ) ) ;
1085+ rsp . PrimColor = color ;
1086+ }
1087+
1088+ break ;
1089+ }
10111090 default : {
1012- rdp . SetCombinerCycleParams ( CombinerCycleParams . FromShade ( withAlpha ) ) ;
1091+ rdp . SetCombinerCycleParams (
1092+ CombinerCycleParams . FromTexture0AndShade ( withAlpha ) ) ;
10131093 break ;
10141094 }
10151095 }
0 commit comments