Skip to content

Commit aa60807

Browse files
committed
Brought back in some jank stuff for TSTLT because it legitimately was working better before.
1 parent 660491e commit aa60807

File tree

4 files changed

+420
-320
lines changed

4 files changed

+420
-320
lines changed

FinModelUtility/Games/MarioArtist/MarioArtist/src/api/ChosenPart0Util.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace marioartist.api;
1919
/// really nothing else to be done. Just have to suck it up and include their
2020
/// same bullshit here too.
2121
/// </summary>
22-
internal class ChosenPart0Util {
22+
public static class ChosenPart0Util {
2323
public static void SetUp(
2424
IN64Hardware n64Hardware,
2525
ChosenPart0 chosenPart0,
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
using System.Drawing;
2+
3+
using f3dzex2.combiner;
4+
using f3dzex2.displaylist.opcodes;
5+
using f3dzex2.image;
6+
using f3dzex2.io;
7+
8+
using fin.math;
9+
using fin.model;
10+
11+
using marioartist.schema.talent_studio;
12+
13+
using OneOf;
14+
15+
namespace marioartist.api;
16+
17+
public static class JankTstltUtil {
18+
public static void ResetRspAndRdp(IN64Hardware n64Hardware) {
19+
// TODO: The way these are reset in the original game is actually really, really, really complicated
20+
var rsp = n64Hardware.Rsp;
21+
rsp.UvType = N64UvType.LINEAR;
22+
rsp.EnvironmentColor = Color.White;
23+
rsp.PrimColor = Color.White;
24+
25+
var rdp = n64Hardware.Rdp;
26+
rdp.ForceBlending = false;
27+
rdp.P0 = BlenderPm.G_BL_CLR_MEM;
28+
rdp.A0 = BlenderA.G_BL_0;
29+
rdp.M0 = BlenderPm.G_BL_CLR_IN;
30+
rdp.B0 = BlenderB.G_BL_1;
31+
rdp.P1 = BlenderPm.G_BL_CLR_MEM;
32+
rdp.A1 = BlenderA.G_BL_0;
33+
rdp.M1 = BlenderPm.G_BL_CLR_IN;
34+
rdp.B1 = BlenderB.G_BL_1;
35+
rdp.CycleType = CycleType.TWO_CYCLE;
36+
37+
rdp.UseCoverageForAlpha = true;
38+
}
39+
40+
public static void SetAdditiveBlending(IN64Hardware n64Hardware) {
41+
var rsp = n64Hardware.Rsp;
42+
rsp.UvType = N64UvType.LINEAR;
43+
rsp.UvType = N64UvType.STANDARD;
44+
rsp.EnvironmentColor = Color.White;
45+
rsp.PrimColor = Color.White;
46+
47+
var rdp = n64Hardware.Rdp;
48+
rdp.ForceBlending = true;
49+
rdp.P0 = BlenderPm.G_BL_CLR_MEM;
50+
rdp.A0 = BlenderA.G_BL_A_IN;
51+
rdp.M0 = BlenderPm.G_BL_CLR_IN;
52+
rdp.B0 = BlenderB.G_BL_1MA;
53+
rdp.P1 = BlenderPm.G_BL_CLR_MEM;
54+
rdp.A1 = BlenderA.G_BL_A_IN;
55+
rdp.M1 = BlenderPm.G_BL_CLR_IN;
56+
rdp.B1 = BlenderB.G_BL_1MA;
57+
rdp.CycleType = CycleType.TWO_CYCLE;
58+
59+
rdp.UseCoverageForAlpha = false;
60+
}
61+
62+
public static void SetCombiner(
63+
IN64Hardware n64Hardware,
64+
bool withTexture0,
65+
bool withAlpha,
66+
OneOf<uint, Color>? patternSegmentedOffsetOrColor = null,
67+
PatternMaterialType patternMaterialType = PatternMaterialType.BLEND_1X1) {
68+
var rdp = n64Hardware.Rdp;
69+
var rsp = n64Hardware.Rsp;
70+
71+
// Based on decomp, early in function at 0x801150e8
72+
rsp.PrimLodFraction = 1f * 0x7f / 0x100;
73+
74+
ushort shift = patternMaterialType switch {
75+
PatternMaterialType.BLEND_2X2
76+
or PatternMaterialType.MULTIPLY_2X2 => 0xf,
77+
_ => 0,
78+
};
79+
80+
rsp.UvType = patternMaterialType == PatternMaterialType.SPHERICAL
81+
? N64UvType.SPHERICAL
82+
: N64UvType.STANDARD;
83+
rdp.Tmem.GsSpTexture(BitLogic.ConvertDoubleToBinaryFraction(1),
84+
BitLogic.ConvertDoubleToBinaryFraction(1),
85+
0,
86+
TileDescriptorIndex.TX_LOADTILE,
87+
withTexture0
88+
? TileDescriptorState.ENABLED
89+
: TileDescriptorState.DISABLED);
90+
91+
switch (withTexture0, patternSegmentedOffsetOrColor) {
92+
case (true, not null): {
93+
if (patternSegmentedOffsetOrColor.Value.TryPickT0(
94+
out var patternSegmentedOffset,
95+
out var color)) {
96+
rdp.Tmem.SetImageSimple(
97+
patternSegmentedOffset,
98+
N64ColorFormat.RGBA,
99+
BitsPerTexel._16BPT,
100+
32,
101+
32,
102+
F3dWrapMode.REPEAT,
103+
F3dWrapMode.REPEAT,
104+
1,
105+
shift);
106+
107+
rdp.SetCombinerCycleParams(
108+
FromBlendingTexture0AndTexture1WithEnvColorAndShade(
109+
patternMaterialType,
110+
withAlpha));
111+
112+
// From decomp, 0x801162a4 onwards
113+
var (envValue, envAlpha) = patternMaterialType switch {
114+
PatternMaterialType.BLEND_1X1
115+
or PatternMaterialType.BLEND_2X2 => (0xc8, 0xff),
116+
PatternMaterialType.MULTIPLY_1X1
117+
or PatternMaterialType.MULTIPLY_2X2 => (0xd7, 0xff),
118+
PatternMaterialType.SPHERICAL => (0xff, 0x30),
119+
};
120+
rsp.EnvironmentColor = Color.FromArgb(envAlpha,
121+
envValue,
122+
envValue,
123+
envValue);
124+
} else {
125+
rdp.SetCombinerCycleParams(
126+
CombinerCycleParams
127+
.FromTexture0AndLightingAndPrimitive(withAlpha));
128+
rsp.PrimColor = color;
129+
}
130+
131+
break;
132+
}
133+
case (true, null): {
134+
rdp.SetCombinerCycleParams(
135+
CombinerCycleParams.FromTexture0AndShade(withAlpha));
136+
break;
137+
}
138+
case (false, not null): {
139+
if (patternSegmentedOffsetOrColor.Value.TryPickT0(
140+
out var patternSegmentedOffset,
141+
out var color)) {
142+
rdp.Tmem.SetImageSimple(
143+
patternSegmentedOffset,
144+
N64ColorFormat.RGBA,
145+
BitsPerTexel._16BPT,
146+
32,
147+
32,
148+
F3dWrapMode.REPEAT,
149+
F3dWrapMode.REPEAT,
150+
0,
151+
shift);
152+
153+
rdp.SetCombinerCycleParams(
154+
CombinerCycleParams.FromTexture0AndShade(withAlpha));
155+
} else {
156+
rdp.SetCombinerCycleParams(
157+
CombinerCycleParams.FromPrimitiveAndLighting(withAlpha));
158+
rsp.PrimColor = color;
159+
}
160+
161+
break;
162+
}
163+
default: {
164+
rdp.SetCombinerCycleParams(
165+
CombinerCycleParams.FromTexture0AndShade(withAlpha));
166+
break;
167+
}
168+
}
169+
}
170+
171+
// From decomp, 0x801162a4 onwards
172+
public static (CombinerCycleParams, CombinerCycleParams)
173+
FromBlendingTexture0AndTexture1WithEnvColorAndShade(
174+
PatternMaterialType patternMaterialType,
175+
bool withAlpha)
176+
=> (patternMaterialType switch {
177+
PatternMaterialType.BLEND_1X1 or PatternMaterialType.BLEND_2X2 =>
178+
new() {
179+
ColorMuxA = GenericColorMux.G_CCMUX_TEXEL1,
180+
ColorMuxB = GenericColorMux.G_CCMUX_ENVIRONMENT,
181+
ColorMuxC = GenericColorMux.G_CCMUX_TEXEL0,
182+
ColorMuxD = GenericColorMux.G_CCMUX_TEXEL0,
183+
AlphaMuxA = GenericAlphaMux.G_ACMUX_0,
184+
AlphaMuxB = GenericAlphaMux.G_ACMUX_0,
185+
AlphaMuxC = GenericAlphaMux.G_ACMUX_0,
186+
AlphaMuxD = withAlpha
187+
? GenericAlphaMux.G_ACMUX_TEXEL0
188+
: GenericAlphaMux.G_ACMUX_1,
189+
},
190+
PatternMaterialType.MULTIPLY_1X1
191+
or PatternMaterialType.MULTIPLY_2X2 =>
192+
new() {
193+
ColorMuxA = GenericColorMux.G_CCMUX_TEXEL1,
194+
ColorMuxB = GenericColorMux.G_CCMUX_ENVIRONMENT,
195+
ColorMuxC = GenericColorMux.G_CCMUX_PRIM_LOD_FRAC,
196+
ColorMuxD = GenericColorMux.G_CCMUX_TEXEL0,
197+
AlphaMuxA = GenericAlphaMux.G_ACMUX_0,
198+
AlphaMuxB = GenericAlphaMux.G_ACMUX_0,
199+
AlphaMuxC = GenericAlphaMux.G_ACMUX_0,
200+
AlphaMuxD = withAlpha
201+
? GenericAlphaMux.G_ACMUX_TEXEL0
202+
: GenericAlphaMux.G_ACMUX_1,
203+
},
204+
PatternMaterialType.SPHERICAL =>
205+
new() {
206+
ColorMuxA = GenericColorMux.G_CCMUX_1,
207+
ColorMuxB = GenericColorMux.G_CCMUX_TEXEL1,
208+
ColorMuxC = GenericColorMux.G_CCMUX_ENV_ALPHA,
209+
ColorMuxD = GenericColorMux.G_CCMUX_TEXEL1,
210+
AlphaMuxA = GenericAlphaMux.G_ACMUX_0,
211+
AlphaMuxB = GenericAlphaMux.G_ACMUX_0,
212+
AlphaMuxC = GenericAlphaMux.G_ACMUX_0,
213+
AlphaMuxD = withAlpha
214+
? GenericAlphaMux.G_ACMUX_TEXEL0
215+
: GenericAlphaMux.G_ACMUX_1,
216+
},
217+
},
218+
new() {
219+
ColorMuxA = GenericColorMux.G_CCMUX_COMBINED,
220+
ColorMuxB = GenericColorMux.G_CCMUX_0,
221+
ColorMuxC = GenericColorMux.G_CCMUX_SHADE,
222+
ColorMuxD = GenericColorMux.G_CCMUX_0,
223+
AlphaMuxA = GenericAlphaMux.G_ACMUX_0,
224+
AlphaMuxB = GenericAlphaMux.G_ACMUX_0,
225+
AlphaMuxC = GenericAlphaMux.G_ACMUX_0,
226+
AlphaMuxD = GenericAlphaMux.G_ACMUX_COMBINED,
227+
});
228+
229+
public static CullingMode GetCullingModeForMeshSetId(uint meshSetId)
230+
=> meshSetId switch {
231+
// HACK: Disables culling for glasses
232+
8 => CullingMode.SHOW_BOTH,
233+
// HACK: Disables culling for head accessories
234+
10 => CullingMode.SHOW_BOTH,
235+
// By default, only shows front face
236+
_ => CullingMode.SHOW_FRONT_ONLY,
237+
};
238+
239+
public static CullingMode GetCullingModeForChosenPartId(int chosenPartId)
240+
=> chosenPartId switch {
241+
// HACK: Disables culling for hats
242+
3 => CullingMode.SHOW_BOTH,
243+
// HACK: Disables culling for accessories worn on back
244+
6 => CullingMode.SHOW_BOTH,
245+
// By default, only shows front face
246+
_ => CullingMode.SHOW_FRONT_ONLY,
247+
};
248+
249+
public static void SetCombinerForPattern(
250+
IN64Hardware n64Hardware,
251+
ChosenPart0 chosenPart0,
252+
int patternI,
253+
bool withTexture) {
254+
if (!(patternI is 1 or 2 or 3)) {
255+
return;
256+
}
257+
258+
var isMark = patternI == 2;
259+
SetCombiner(n64Hardware,
260+
withTexture,
261+
isMark,
262+
OneOf<uint, Color>.FromT0(
263+
patternI switch {
264+
1 => chosenPart0.Pattern0Params.ImageSegmentedAddress,
265+
2 => chosenPart0.Pattern1Params.ImageSegmentedAddress,
266+
3 => chosenPart0.MarkParams.ImageSegmentedAddress,
267+
}),
268+
patternI switch {
269+
1 => chosenPart0.Pattern0Params.MaterialType,
270+
2 => chosenPart0.Pattern1Params.MaterialType,
271+
3 => PatternMaterialType.BLEND_1X1,
272+
});
273+
274+
if (isMark) {
275+
SetAdditiveBlending(n64Hardware);
276+
}
277+
}
278+
}

0 commit comments

Comments
 (0)