diff options
Diffstat (limited to 'src/studio.cpp')
| -rw-r--r-- | src/studio.cpp | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/src/studio.cpp b/src/studio.cpp index bee6db5..07ebec3 100644 --- a/src/studio.cpp +++ b/src/studio.cpp | |||
| @@ -248,6 +248,15 @@ void chams_color(void *mat, float r, float g, float b) { | |||
| 248 | vfunc<ColorFn>(mat, 28)(mat, r, g, b); | 248 | vfunc<ColorFn>(mat, 28)(mat, r, g, b); |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | void chams_alpha(void *mat, float a) { | ||
| 252 | using FindVarFn = void *(*)(void *, const char *, bool *, bool); | ||
| 253 | using SetFloatFn = void (*)(void *, float); | ||
| 254 | bool found = false; | ||
| 255 | void *var = vfunc<FindVarFn>(mat, 11)(mat, "$alpha", &found, false); | ||
| 256 | if (var) | ||
| 257 | vfunc<SetFloatFn>(var, 3)(var, a); | ||
| 258 | } | ||
| 259 | |||
| 251 | void chams_apply(void *mat, bool ignorez, int style, bool force_white, | 260 | void chams_apply(void *mat, bool ignorez, int style, bool force_white, |
| 252 | const int *rgb, bool znearer) { | 261 | const int *rgb, bool znearer) { |
| 253 | using FlagFn = void (*)(void *, int, bool); | 262 | using FlagFn = void (*)(void *, int, bool); |
| @@ -255,10 +264,12 @@ void chams_apply(void *mat, bool ignorez, int style, bool force_white, | |||
| 255 | float g = force_white ? 1.0f : (float)rgb[1] / 255.0f; | 264 | float g = force_white ? 1.0f : (float)rgb[1] / 255.0f; |
| 256 | float b = force_white ? 1.0f : (float)rgb[2] / 255.0f; | 265 | float b = force_white ? 1.0f : (float)rgb[2] / 255.0f; |
| 257 | chams_color(mat, r, g, b); | 266 | chams_color(mat, r, g, b); |
| 267 | chams_alpha(mat, (float)rgb[3] / 255.0f); | ||
| 258 | // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright | 268 | // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright |
| 259 | // (additive white glow), 6 Glow outline (solid base; the wireframe overlay | 269 | // (additive white glow), 6 Glow outline (solid base; the wireframe overlay |
| 260 | // is a second draw with ZNEARER so its contour is not hidden by the base). | 270 | // is a second draw with ZNEARER so its contour is not hidden by the base). |
| 261 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez); | 271 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez); |
| 272 | vfunc<FlagFn>(mat, 29)(mat, 1 << 21 /* TRANSLUCENT */, rgb[3] < 255); | ||
| 262 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10 /* ZNEARER */, znearer); | 273 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10 /* ZNEARER */, znearer); |
| 263 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1); | 274 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1); |
| 264 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7 /* ADDITIVE */, | 275 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7 /* ADDITIVE */, |
| @@ -270,12 +281,14 @@ void chams_apply(void *mat, bool ignorez, int style, bool force_white, | |||
| 270 | void chams_reset(void *mat) { | 281 | void chams_reset(void *mat) { |
| 271 | using FlagFn = void (*)(void *, int, bool); | 282 | using FlagFn = void (*)(void *, int, bool); |
| 272 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15, false); | 283 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15, false); |
| 284 | vfunc<FlagFn>(mat, 29)(mat, 1 << 21, false); | ||
| 273 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10, false); | 285 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10, false); |
| 274 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28, false); | 286 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28, false); |
| 275 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7, false); | 287 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7, false); |
| 276 | vfunc<FlagFn>(mat, 29)(mat, 1 << 12, false); | 288 | vfunc<FlagFn>(mat, 29)(mat, 1 << 12, false); |
| 277 | vfunc<FlagFn>(mat, 29)(mat, 1 << 6, false); | 289 | vfunc<FlagFn>(mat, 29)(mat, 1 << 6, false); |
| 278 | chams_color(mat, 1.0f, 1.0f, 1.0f); | 290 | chams_color(mat, 1.0f, 1.0f, 1.0f); |
| 291 | chams_alpha(mat, 1.0f); | ||
| 279 | } | 292 | } |
| 280 | 293 | ||
| 281 | void hkdModelExecute(void *self, const void *state, const void *info, | 294 | void hkdModelExecute(void *self, const void *state, const void *info, |
| @@ -306,20 +319,24 @@ void hkdModelExecute(void *self, const void *state, const void *info, | |||
| 306 | // Fullbright is an additive, self-illuminated version of the | 319 | // Fullbright is an additive, self-illuminated version of the |
| 307 | // chosen colour: lift it toward white so it reads brighter than | 320 | // chosen colour: lift it toward white so it reads brighter than |
| 308 | // the plain additive style. | 321 | // the plain additive style. |
| 309 | int brgb[3]; | 322 | int brgb[4]; |
| 310 | const int *use_rgb = rgb; | 323 | const int *use_rgb = rgb; |
| 311 | if (style == 5) { | 324 | if (style == 5) { |
| 312 | for (int i = 0; i < 3; i++) | 325 | for (int i = 0; i < 3; i++) |
| 313 | brgb[i] = rgb[i] + (255 - rgb[i]) / 2; | 326 | brgb[i] = rgb[i] + (255 - rgb[i]) / 4; |
| 327 | brgb[3] = rgb[3]; | ||
| 314 | use_rgb = brgb; | 328 | use_rgb = brgb; |
| 315 | } | 329 | } |
| 316 | // Additive blending vanishes against bright backgrounds (sky, | 330 | // Additive blending vanishes against bright backgrounds (sky, |
| 317 | // white walls, strong fog), which made the viewmodel disappear in | 331 | // white walls, strong fog), which made the viewmodel disappear in |
| 318 | // some places. Lay down a dim opaque base first so the first-person | 332 | // some places. Lay down a faint translucent base so the first-person |
| 319 | // model always has a visible silhouette; the additive pass still | 333 | // model keeps a silhouette on bright backgrounds without turning |
| 320 | // adds the glow on top. | 334 | // into an opaque blob; the additive pass still provides the glow. |
| 321 | if (is_vm && (style == 2 || style == 5)) { | 335 | if (is_vm && (style == 2 || style == 5) && rgb[3] > 0) { |
| 322 | int drgb[3] = {rgb[0] / 2, rgb[1] / 2, rgb[2] / 2}; | 336 | int ba = rgb[3] / 8; |
| 337 | if (ba < 16) | ||
| 338 | ba = 16; | ||
| 339 | int drgb[4] = {rgb[0], rgb[1], rgb[2], ba}; | ||
| 323 | chams_apply(mat, ignorez, 3, false, drgb, false); | 340 | chams_apply(mat, ignorez, 3, false, drgb, false); |
| 324 | g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); | 341 | g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); |
| 325 | g_orig_model_exec(self, state, info, bone); | 342 | g_orig_model_exec(self, state, info, bone); |
| @@ -333,8 +350,8 @@ void hkdModelExecute(void *self, const void *state, const void *info, | |||
| 333 | // the contour and bias it forward so the base cannot bury it. | 350 | // the contour and bias it forward so the base cannot bury it. |
| 334 | void *wire = g_style_mats[1]; | 351 | void *wire = g_style_mats[1]; |
| 335 | if (wire && wire != mat) { | 352 | if (wire && wire != mat) { |
| 336 | int wrgb[3] = {(rgb[0] + 255) / 2, (rgb[1] + 255) / 2, | 353 | int wrgb[4] = {(rgb[0] + 255) / 2, (rgb[1] + 255) / 2, |
| 337 | (rgb[2] + 255) / 2}; | 354 | (rgb[2] + 255) / 2, rgb[3]}; |
| 338 | chams_apply(wire, ignorez, 1, false, wrgb, true); | 355 | chams_apply(wire, ignorez, 1, false, wrgb, true); |
| 339 | g_force_override(self, wire, 0); | 356 | g_force_override(self, wire, 0); |
| 340 | g_orig_model_exec(self, state, info, bone); | 357 | g_orig_model_exec(self, state, info, bone); |
