@@ -329,6 +329,12 @@ bool C2D_SetTintMode(C2D_TintMode mode)
329329 case C2D_TintLuma :
330330 new_mode = C2DiF_Mode_ImageLuma ;
331331 break ;
332+ case C2D_TintAdd :
333+ new_mode = C2DiF_Mode_ImageAdd ;
334+ break ;
335+ case C2D_TintSub :
336+ new_mode = C2DiF_Mode_ImageSub ;
337+ break ;
332338 }
333339
334340 ctx -> flags = (ctx -> flags & ~ C2DiF_TintMode_Mask ) | (new_mode << (C2DiF_TintMode_Shift - C2DiF_Mode_Shift ));
@@ -714,6 +720,54 @@ void C2Di_Update(void)
714720 C3D_TexEnvFunc (env , C3D_RGB , GPU_INTERPOLATE );
715721 break ;
716722 }
723+ case C2DiF_Mode_ImageAdd :
724+ {
725+ // Use texenv to blend the color source with the addition-tinted version of it,
726+ // according to a parameter that is passed through with the help of proctex.
727+ proctex = C2DiF_ProcTex_Blend ;
728+
729+ // texenv0 = texclr + vtxcolor
730+ env = C3D_GetTexEnv (0 );
731+ C3D_TexEnvInit (env );
732+ C3D_TexEnvSrc (env , C3D_Both , GPU_TEXTURE0 , GPU_PRIMARY_COLOR , GPU_PRIMARY_COLOR );
733+ C3D_TexEnvFunc (env , C3D_RGB , GPU_ADD );
734+
735+ // texenv1.rgb = mix(texclr.rgb, texenv0.rgb, vtx.blend.y);
736+ env = C3D_GetTexEnv (1 );
737+ C3D_TexEnvInit (env );
738+ C3D_TexEnvSrc (env , C3D_RGB , GPU_TEXTURE0 , GPU_PREVIOUS , GPU_TEXTURE3 );
739+ C3D_TexEnvOpRgb (env , GPU_TEVOP_RGB_SRC_COLOR , GPU_TEVOP_RGB_SRC_COLOR , GPU_TEVOP_RGB_ONE_MINUS_SRC_ALPHA );
740+ C3D_TexEnvFunc (env , C3D_RGB , GPU_INTERPOLATE );
741+
742+ // Reset unused texenv stages
743+ C3D_TexEnvInit (C3D_GetTexEnv (2 ));
744+ C3D_TexEnvInit (C3D_GetTexEnv (3 ));
745+ break ;
746+ }
747+ case C2DiF_Mode_ImageSub :
748+ {
749+ // Use texenv to blend the color source with the subtraction-tinted version of it,
750+ // according to a parameter that is passed through with the help of proctex.
751+ proctex = C2DiF_ProcTex_Blend ;
752+
753+ // texenv0 = texclr - vtxcolor
754+ env = C3D_GetTexEnv (0 );
755+ C3D_TexEnvInit (env );
756+ C3D_TexEnvSrc (env , C3D_Both , GPU_TEXTURE0 , GPU_PRIMARY_COLOR , GPU_PRIMARY_COLOR );
757+ C3D_TexEnvFunc (env , C3D_RGB , GPU_SUBTRACT );
758+
759+ // texenv1.rgb = mix(texclr.rgb, texenv0.rgb, vtx.blend.y);
760+ env = C3D_GetTexEnv (1 );
761+ C3D_TexEnvInit (env );
762+ C3D_TexEnvSrc (env , C3D_RGB , GPU_TEXTURE0 , GPU_PREVIOUS , GPU_TEXTURE3 );
763+ C3D_TexEnvOpRgb (env , GPU_TEVOP_RGB_SRC_COLOR , GPU_TEVOP_RGB_SRC_COLOR , GPU_TEVOP_RGB_ONE_MINUS_SRC_ALPHA );
764+ C3D_TexEnvFunc (env , C3D_RGB , GPU_INTERPOLATE );
765+
766+ // Reset unused texenv stages
767+ C3D_TexEnvInit (C3D_GetTexEnv (2 ));
768+ C3D_TexEnvInit (C3D_GetTexEnv (3 ));
769+ break ;
770+ }
717771 }
718772
719773 if (proctex && proctex != (ctx -> flags & C2DiF_ProcTex_Mask ))
0 commit comments