package main import "core:fmt" import "core:math" import "core:math/ease" import rl "vendor:raylib" SFX: []u8 : #load("sfx.mp3") OTF: []u8 : #load("a.otf") color_mul_rgb :: proc(a, b: rl.Color) -> rl.Color { return { u8((f32(a.r) * f32(b.r)) / 255), u8((f32(a.g) * f32(b.g)) / 255), u8((f32(a.b) * f32(b.b)) / 255), 255, } } with_alpha :: proc(c: rl.Color, alpha: f32) -> rl.Color { out := c out.a = u8(clamp(alpha, 0, 1) * 255) return out } ease_out_back :: proc(t: f32, s: f32 = 1.70158) -> f32 { t1 := clamp(t, 0, 1) return 1 + s * math.pow(t1 - 1, 3) + s * (t1 - 1) * math.pow(t1 - 1, 2) } adsr :: proc(t, attack, decay, sustain: f32, r_start: f32, r_dur: f32) -> f32 { if t <= 0 {return 0} if t < attack { return ease.cubic_out(t / attack) } if t < attack + decay { return f32(math.lerp(f32(1), sustain, ease.cubic_in_out((t - attack) / decay))) } if t < r_start { return sustain } return sustain * (1 - ease.cubic_out((t - r_start) / math.max(r_dur, 0.0001))) } draw_noun_verbed_sheen :: proc( font: rl.Font, text: string, center: rl.Vector2, base_font_size: f32, spacing: f32, text_color: rl.Color, text_opacity: f32, sheen_tint: rl.Color, blur_size_: f32, blur_opacity: f32, ) { blur_size := blur_size_ screen_h := rl.GetScreenHeight() s := f32(screen_h) / 1080.0 if blur_size <= 1.0001 { blur_size = 1.0001 } steps_f := 20.0 * blur_size * math.pow(s, 0.25) zoomSteps := i32(math.floor(steps_f)) if zoomSteps < 6 { zoomSteps = 6 } voff := s / (blur_size - 1.0) base_size := rl.MeasureTextEx(font, fmt.ctprintf("{}", text), base_font_size, spacing) base_origin := rl.Vector2{base_size.x * 0.5, base_size.y * 0.5} glow_base := color_mul_rgb(text_color, sheen_tint) rl.BeginBlendMode(.ADDITIVE) for i := zoomSteps; i >= 0; i -= 1 { t := f32(i) / f32(zoomSteps) scale_factor := f32(math.pow(blur_size, t)) denom := f32(math.log2_f32(blur_size) / math.log2_f32(2)) if denom == 0 { denom = 0.000001 } fat_product := f32(math.pow(scale_factor, 1.0 / denom)) alpha := blur_opacity / fat_product if alpha <= 0.001 { continue } fs := base_font_size * scale_factor sp := spacing * scale_factor size := rl.MeasureTextEx(font, fmt.ctprintf("{}", text), fs, sp) origin := rl.Vector2{size.x * 0.5, size.y * 0.5} y_offset := voff * (scale_factor - 1.0) rl.DrawTextPro( font, fmt.ctprintf("{}", text), rl.Vector2{center.x, center.y + y_offset}, origin, 0.0, fs, sp, with_alpha(glow_base, alpha), ) } rl.EndBlendMode() rl.DrawTextPro( font, fmt.ctprintf("{}", text), center, base_origin, 0.0, base_font_size, spacing, with_alpha(text_color, text_opacity), ) } draw_shadow_bar :: proc( center_y: f32, rel_size: f32, opacity: f32, offset: f32, softness: f32, tint: rl.Color, ) { if rel_size <= 0.0 || opacity <= 0.0 { return } w := rl.GetScreenWidth() hf := f32(rl.GetScreenHeight()) shadow_h := rel_size * 0.25 * hf center := center_y + offset * hf top := center - shadow_h * 0.5 c_tint := rl.Color{tint.r, tint.g, tint.b, u8(clamp(opacity, 0, 1) * 255)} c_clear := rl.Color{tint.r, tint.g, tint.b, 0} y0 := i32(math.round(top)) total_h := i32(math.round(shadow_h)) if total_h <= 0 { return } y3 := y0 + total_h fade_h := shadow_h * clamp(softness, 0, 1) * 0.5 fade_i := i32(math.round(fade_h)) if fade_i * 2 > total_h { fade_i = total_h / 2 } y1 := y0 + fade_i y2 := y3 - fade_i mid_h := y2 - y1 rl.BeginBlendMode(.ALPHA) if fade_i > 0 { rl.DrawRectangleGradientV(0, y0, w, y1 - y0, c_clear, c_tint) } if mid_h > 0 { rl.DrawRectangle(0, y1, w, mid_h, c_tint) } if fade_i > 0 { rl.DrawRectangleGradientV(0, y2, w, y3 - y2, c_tint, c_clear) } rl.EndBlendMode() } draw_sheen_sweep :: proc( font: rl.Font, text: string, center: rl.Vector2, font_size: f32, spacing: f32, tint: rl.Color, progress: f32, core_frac: f32, soft_frac: f32, core_alpha: f32, soft_alpha: f32, ) { size := rl.MeasureTextEx(font, fmt.ctprintf("{}", text), font_size, spacing) origin := rl.Vector2{size.x * 0.5, size.y * 0.5} left := center.x - origin.x top := center.y - origin.y width := size.x height := size.y p := clamp(progress, 0, 1) x_center := left + width * p core_w := width * core_frac soft_w := width * soft_frac bright := rl.Color{255, 235, 210, 255} rl.BeginBlendMode(.ADDITIVE) rl.BeginScissorMode(i32(x_center - soft_w * 0.5), i32(top), i32(soft_w), i32(height)) rl.DrawTextPro( font, fmt.ctprintf("{}", text), center, origin, 0, font_size, spacing, with_alpha(bright, soft_alpha), ) rl.EndScissorMode() rl.BeginScissorMode(i32(x_center - core_w * 0.5), i32(top), i32(core_w), i32(height)) rl.DrawTextPro( font, fmt.ctprintf("{}", text), center, origin, 0, font_size, spacing, with_alpha(bright, core_alpha), ) rl.EndScissorMode() rl.EndBlendMode() } main :: proc() { mon := rl.GetCurrentMonitor() w, h := rl.GetMonitorWidth(mon), rl.GetMonitorHeight(mon) rl.SetConfigFlags( { .WINDOW_TRANSPARENT, .WINDOW_RESIZABLE, .WINDOW_MOUSE_PASSTHROUGH, .WINDOW_HIGHDPI, .WINDOW_TOPMOST, .WINDOW_UNFOCUSED, .WINDOW_UNDECORATED, .FULLSCREEN_MODE, }, ) rl.InitWindow(w, h, "amongus") rl.InitAudioDevice() music := rl.LoadMusicStreamFromMemory(".mp3", raw_data(SFX), i32(len(SFX))) rl.PlayMusicStream(music) rt := rl.LoadRenderTexture(rl.GetScreenWidth(), rl.GetScreenHeight()) rl.SetTextureFilter(rt.texture, .BILINEAR) font := rl.LoadFontFromMemory(".otf", raw_data(OTF), i32(len(OTF)), 256, nil, 0) text := "NIXOS REBUILT" //base_font_size0 := f32(128) spacing := f32(2) text_color := rl.Color{235, 200, 120, 255} sheen_tint := rl.Color{255, 178, 153, 255} // base durations fade_in_dur := f32(0.55) scale_dur := f32(1.10) sweep_delay := f32(0.20) sweep_dur := f32(1.20) glow_rise_dur := f32(0.70) post_fade_in_dur := f32(0.25) post_hold_after_sweep := f32(0.35) post_fade_out_dur := f32(0.60) DUR_SCALE :: f32(2.0) blur_base := f32(1.0) blur_opacity_base := f32(0.08) // overlay appears 7s into the mp3 OVERLAY_DELAY :: f32(5.0) SHEEN_GAIN :: 0.3 // overall intensity (0..1) SHEEN_W_SCALE :: 0.5 // width scaler (<1 = thinner) SHEEN_SOFT_ALPHA_CAP :: 0.10 // upper cap for soft halo SHEEN_CORE_ALPHA_CAP :: 0.28 // upper cap for core prev_mt := f32(0) ended := false len_s := f32(rl.GetMusicTimeLength(music)) running := true for !rl.WindowShouldClose() && running { free_all(context.temp_allocator) if rl.IsWindowResized() { rl.UnloadRenderTexture(rt) rt = rl.LoadRenderTexture(rl.GetScreenWidth(), rl.GetScreenHeight()) rl.SetTextureFilter(rt.texture, .BILINEAR) } rl.UpdateMusicStream(music) mt_raw := f32(rl.GetMusicTimePlayed(music)) if !ended { if mt_raw < prev_mt - 0.02 || mt_raw >= len_s - 0.01 || (!rl.IsMusicStreamPlaying(music) && mt_raw > 0) { ended = true rl.StopMusicStream(music) } } mt := mt_raw if ended { mt = len_s running = false } prev_mt = mt_raw visible := mt >= OVERLAY_DELAY t := mt - OVERLAY_DELAY if t < 0 {t = 0} fade_in := fade_in_dur * DUR_SCALE scale_len := scale_dur * DUR_SCALE sweep_dly := sweep_delay * DUR_SCALE sweep_len := sweep_dur * DUR_SCALE glow_len := glow_rise_dur * DUR_SCALE post_in := post_fade_in_dur * DUR_SCALE post_hold := post_hold_after_sweep * DUR_SCALE post_out := post_fade_out_dur * DUR_SCALE alpha := ease.cubic_out(t / fade_in) scale_bump := 0.06 * ease_out_back(t / scale_len, 1.3) base_font_size0 := 0.6 * 0.25 * f32(rl.GetScreenHeight()) font_size := base_font_size0 * (1.0 + scale_bump) glow_in := ease.cubic_out(t / glow_len) glow_pulse := 0.5 + 0.5 * f32(math.sin(t * 2.0)) sweep_end_time := sweep_dly + sweep_len fade_out_start := sweep_end_time + post_hold blur_env := adsr( t, 0.18 * DUR_SCALE, // attack 0.35 * DUR_SCALE, // decay 0.70, // sustain level fade_out_start, // release start post_out, // release dur ) blur_size := blur_base * f32(math.lerp(f32(1.00), 1.30, ease.cubic_in_out(blur_env))) blur_opacity := blur_opacity_base blur_opacity *= (0.60 + 0.40 * blur_env) // grow with env blur_opacity *= clamp(glow_in * (0.8 + 0.2 * glow_pulse), 0.0, 1.0) sheen_t := t - sweep_dly raw_env := adsr( sheen_t, 0.10 * DUR_SCALE, 0.22 * DUR_SCALE, 0.65, sweep_len, 0.28 * DUR_SCALE, ) sheen_env := f32(math.pow(clamp(raw_env, 0, 1), 0.75) * SHEEN_GAIN) core_frac := f32(math.lerp(f32(0.12), 0.18, sheen_env) * SHEEN_W_SCALE) soft_frac := f32(math.lerp(f32(0.24), 0.34, sheen_env) * SHEEN_W_SCALE) core_alpha_dyn := f32( math.min(math.lerp(f32(0.10), 0.26, sheen_env), SHEEN_CORE_ALPHA_CAP), ) soft_alpha_dyn := f32( math.min(math.lerp(f32(0.03), 0.09, sheen_env), SHEEN_SOFT_ALPHA_CAP), ) center := rl.Vector2{f32(rl.GetScreenWidth()) * 0.5, f32(rl.GetScreenHeight()) * 0.5} rl.BeginTextureMode(rt) rl.ClearBackground(rl.BLANK) if visible { draw_shadow_bar(center.y, 1.4, 0.95, -0.002, 0.5, rl.BLACK) draw_noun_verbed_sheen( font, text, center, font_size, spacing, text_color, alpha, sheen_tint, blur_size, blur_opacity, ) sweep_p := clamp((t - sweep_dly) / sweep_len, 0, 1) if sweep_p > 0 && sweep_p <= 1 { draw_sheen_sweep( font, text, center, font_size, spacing, sheen_tint, sweep_p, core_frac, soft_frac, core_alpha_dyn, soft_alpha_dyn, ) } } rl.EndTextureMode() post_alpha := f32(1.0) if !visible { post_alpha = 0 } else { if t < post_in { post_alpha = ease.cubic_out(t / post_in) } else if t >= fade_out_start { post_alpha = 1.0 - ease.cubic_out((t - fade_out_start) / post_out) } post_alpha = clamp(post_alpha, 0, 1) } rl.BeginDrawing() rl.ClearBackground(rl.BLANK) src := rl.Rectangle{0, 0, f32(rt.texture.width), -f32(rt.texture.height)} dst := rl.Rectangle{0, 0, f32(rl.GetScreenWidth()), f32(rl.GetScreenHeight())} rl.DrawTexturePro( rt.texture, src, dst, rl.Vector2{0, 0}, 0, with_alpha(rl.WHITE, post_alpha), ) rl.EndDrawing() } rl.UnloadRenderTexture(rt) rl.UnloadFont(font) rl.UnloadMusicStream(music) rl.CloseAudioDevice() rl.CloseWindow() }