Replace the Godot loading screen with the Mat Games mascot on black
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
Copyright 2011, The VT323 Project Authors (peter.hull@oikoi.com)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
[remap]
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://dl68sx8ti22de"
|
||||
path="res://.godot/imported/VT323-Regular.ttf-bf92192fbafeb12c09857a075677f081.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://tools/branding/fonts/VT323-Regular.ttf"
|
||||
dest_files=["res://.godot/imported/VT323-Regular.ttf-bf92192fbafeb12c09857a075677f081.fontdata"]
|
||||
|
||||
[params]
|
||||
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
allow_system_fallback=true
|
||||
force_autohinter=false
|
||||
modulate_color_glyphs=false
|
||||
hinting=3
|
||||
subpixel_positioning=4
|
||||
keep_rounding_remainders=true
|
||||
oversampling=0.0
|
||||
Fallbacks=null
|
||||
fallbacks=[]
|
||||
Compress=null
|
||||
compress=true
|
||||
preload=[]
|
||||
language_support={}
|
||||
script_support={}
|
||||
opentype_features={}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"boot_splash": {
|
||||
"file": "assets/branding/boot_splash.png",
|
||||
"size": [
|
||||
1024,
|
||||
1218
|
||||
],
|
||||
"mode": "P",
|
||||
"palette_colors": 256,
|
||||
"sha256": "78524be4ba17ab04afe56d16b00954989457f9af247367f7c4b0f9ed8ea2dec4"
|
||||
},
|
||||
"mascot_source": {
|
||||
"file": "tools/branding/raw/agy_generate_20261010234423_0.jpg",
|
||||
"sha256": "5929495ff606fbcdd74f52a37304f3b569315bcd1fc0fef812b5fd7689dc1396"
|
||||
},
|
||||
"generator": {
|
||||
"tool": "agy_generate (Antigravity direct API)",
|
||||
"model": "gemini-3.1-flash-image",
|
||||
"date": "2026-10-11",
|
||||
"prompt": "single cartoon zombie head-and-bust mascot, unsettling wide grin, thumbs up, 2D cartoon style with bold outlines, flat magenta chroma-key background, no text and no logo",
|
||||
"terms_note": "generated from no third-party source material; the provider terms do not claim ownership of the output. The generator emits no real alpha channel, so the background is keyed out locally by this script."
|
||||
},
|
||||
"chroma_key": {
|
||||
"background_rgb": [
|
||||
250,
|
||||
4,
|
||||
247
|
||||
],
|
||||
"transparent_below": 55,
|
||||
"opaque_above": 130
|
||||
},
|
||||
"title": {
|
||||
"text": "Mat Games",
|
||||
"font": "tools/branding/fonts/VT323-Regular.ttf",
|
||||
"license": "SIL Open Font License 1.1 (tools/branding/fonts/OFL.txt)"
|
||||
},
|
||||
"bottom_fade_px": 50
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 616 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c04sjmptejokb"
|
||||
path="res://.godot/imported/agy_generate_20261010234423_0.jpg-9704405d701d25c0ec3a2821bf90d456.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://tools/branding/raw/agy_generate_20261010234423_0.jpg"
|
||||
dest_files=["res://.godot/imported/agy_generate_20261010234423_0.jpg-9704405d701d25c0ec3a2821bf90d456.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -0,0 +1,122 @@
|
||||
"""Compose the boot splash: chroma-keyed mascot plus VT323 "Mat Games" lettering.
|
||||
|
||||
The raw mascot comes from an image generator on a flat magenta background (generators
|
||||
do not emit real alpha). This script keys that background to transparency, removes
|
||||
magenta spill, then draws the title with the OFL-licensed VT323 font and saves a
|
||||
transparent PNG ready for application/boot_splash/image.
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import pathlib
|
||||
from PIL import Image, ImageDraw, ImageFilter, ImageFont
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('raw', type=pathlib.Path, help='raw generated image (magenta background)')
|
||||
parser.add_argument('--title', default='Mat Games')
|
||||
parser.add_argument('--canvas', type=int, default=1024)
|
||||
parser.add_argument('--title-height', type=int, default=190)
|
||||
parser.add_argument('--bottom-fade', type=int, default=50,
|
||||
help='soften the generator frame cut at the bottom of the bust')
|
||||
parser.add_argument('--colors', type=int, default=256,
|
||||
help='palette colors for the shipped PNG; 0 keeps 32-bit RGBA')
|
||||
args = parser.parse_args()
|
||||
args.raw = args.raw.resolve()
|
||||
root = pathlib.Path(__file__).resolve().parents[1]
|
||||
branding = root / 'assets/branding'
|
||||
branding.mkdir(parents=True, exist_ok=True)
|
||||
source_tools = root / 'tools/branding'
|
||||
font_path = source_tools / 'fonts/VT323-Regular.ttf'
|
||||
|
||||
# ---------------------------------------------------------------- chroma key
|
||||
source = Image.open(args.raw).convert('RGB')
|
||||
corners = [source.getpixel(p) for p in
|
||||
[(2, 2), (source.width - 3, 2), (2, source.height - 3), (source.width - 3, source.height - 3)]]
|
||||
background = tuple(sorted(channel)[1] for channel in zip(*corners)) # median per channel
|
||||
T0, T1 = 55, 130
|
||||
alpha = Image.new('L', source.size)
|
||||
spill = Image.new('L', source.size)
|
||||
pixels = source.load()
|
||||
alpha_pixels = alpha.load()
|
||||
spill_pixels = spill.load()
|
||||
for y in range(source.height):
|
||||
for x in range(source.width):
|
||||
r, g, b = pixels[x, y]
|
||||
distance = ((r - background[0]) ** 2 + (g - background[1]) ** 2 + (b - background[2]) ** 2) ** 0.5
|
||||
alpha_pixels[x, y] = max(0, min(255, round((distance - T0) / (T1 - T0) * 255)))
|
||||
# Magenta contamination raises both red and blue above green.
|
||||
spill_pixels[x, y] = max(0, min(r, b) - g)
|
||||
mask = alpha.filter(ImageFilter.MedianFilter(3))
|
||||
fixed = Image.new('RGB', source.size)
|
||||
fixed_pixels = fixed.load()
|
||||
for y in range(source.height):
|
||||
for x in range(source.width):
|
||||
r, g, b = pixels[x, y]
|
||||
amount = spill_pixels[x, y]
|
||||
fixed_pixels[x, y] = (max(0, r - amount), g, max(0, b - amount))
|
||||
mascot = fixed.convert('RGBA')
|
||||
mascot.putalpha(mask)
|
||||
mascot = mascot.crop(mascot.getbbox())
|
||||
if args.bottom_fade > 0:
|
||||
fade = min(args.bottom_fade, mascot.height)
|
||||
ramp = Image.new('L', (1, fade))
|
||||
for y in range(fade):
|
||||
ramp.putpixel((0, y), round(255 * (1.0 - y / fade)))
|
||||
band = mascot.crop((0, mascot.height - fade, mascot.width, mascot.height))
|
||||
band.putalpha(Image.composite(band.getchannel('A'), Image.new('L', band.size, 0), ramp.resize((1, fade)).resize(band.size, Image.NEAREST)))
|
||||
mascot.paste(band, (0, mascot.height - fade))
|
||||
|
||||
# ---------------------------------------------------------------- composition
|
||||
canvas_width = args.canvas
|
||||
title_area = args.title_height
|
||||
scale = (canvas_width - 2 * 40) / mascot.width
|
||||
mascot = mascot.resize((round(mascot.width * scale), round(mascot.height * scale)), Image.LANCZOS)
|
||||
height = mascot.height + title_area
|
||||
canvas = Image.new('RGBA', (canvas_width, height), (0, 0, 0, 0))
|
||||
canvas.alpha_composite(mascot, ((canvas_width - mascot.width) // 2, 0))
|
||||
|
||||
font_size = int(title_area * 0.95)
|
||||
font = ImageFont.truetype(str(font_path), font_size)
|
||||
text = args.title
|
||||
while font.getbbox(text)[2] - font.getbbox(text)[0] > canvas_width - 60 and font_size > 8:
|
||||
font_size -= 2
|
||||
font = ImageFont.truetype(str(font_path), font_size)
|
||||
box = font.getbbox(text)
|
||||
text_width = box[2] - box[0]
|
||||
position = ((canvas_width - text_width) // 2 - box[0], mascot.height + (title_area - box[3]) // 2 - box[1])
|
||||
glow = Image.new('RGBA', canvas.size, (0, 0, 0, 0))
|
||||
ImageDraw.Draw(glow).text(position, text, font=font, fill=(255, 150, 20, 190))
|
||||
glow = glow.filter(ImageFilter.GaussianBlur(9))
|
||||
canvas.alpha_composite(glow)
|
||||
ImageDraw.Draw(canvas).text(position, text, font=font, fill=(255, 196, 64, 255))
|
||||
|
||||
out = branding / 'boot_splash.png'
|
||||
if args.colors > 0:
|
||||
# Flat cartoon art tolerates a palette well; keeps ~95 alpha levels for edges.
|
||||
canvas = canvas.quantize(colors=args.colors, method=Image.FASTOCTREE, dither=Image.Dither.NONE)
|
||||
canvas.save(out, optimize=True)
|
||||
manifest = json.loads((source_tools / 'manifest.json').read_text()) if (source_tools / 'manifest.json').exists() else {}
|
||||
manifest.update({
|
||||
'boot_splash': {'file': str(out.relative_to(root)), 'size': list(canvas.size), 'mode': canvas.mode,
|
||||
'palette_colors': args.colors,
|
||||
'sha256': hashlib.sha256(out.read_bytes()).hexdigest()},
|
||||
'mascot_source': {'file': str(args.raw.relative_to(root)),
|
||||
'sha256': hashlib.sha256(args.raw.read_bytes()).hexdigest()},
|
||||
'generator': {
|
||||
'tool': 'agy_generate (Antigravity direct API)',
|
||||
'model': 'gemini-3.1-flash-image',
|
||||
'date': '2026-10-11',
|
||||
'prompt': ('single cartoon zombie head-and-bust mascot, unsettling wide grin, thumbs up, '
|
||||
'2D cartoon style with bold outlines, flat magenta chroma-key background, '
|
||||
'no text and no logo'),
|
||||
'terms_note': ('generated from no third-party source material; the provider terms do not claim '
|
||||
'ownership of the output. The generator emits no real alpha channel, so the '
|
||||
'background is keyed out locally by this script.'),
|
||||
},
|
||||
'chroma_key': {'background_rgb': list(background), 'transparent_below': T0, 'opaque_above': T1},
|
||||
'title': {'text': args.title, 'font': 'tools/branding/fonts/VT323-Regular.ttf',
|
||||
'license': 'SIL Open Font License 1.1 (tools/branding/fonts/OFL.txt)'},
|
||||
'bottom_fade_px': args.bottom_fade,
|
||||
})
|
||||
(source_tools / 'manifest.json').write_text(json.dumps(manifest, indent=2) + '\n')
|
||||
print(out, canvas.size, canvas.mode, 'mascot', mascot.size)
|
||||
Reference in New Issue
Block a user