From 1893073af01fa86ffa1916135240cd1f9fa1b08a Mon Sep 17 00:00:00 2001 From: KansaiGaijin <83641841+KansaiGaijin@users.noreply.github.com> Date: Tue, 7 Jul 2026 13:25:27 +1200 Subject: [PATCH] =?UTF-8?q?Add=20pc/=20=E2=80=94=20PyInstaller=20build=20s?= =?UTF-8?q?cripts,=20.ico=20icon,=20and=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pc/README.md | 28 ++++++++++++++++++++++++++++ pc/build.bat | 20 ++++++++++++++++++++ pc/build.sh | 19 +++++++++++++++++++ pc/generate_icon.py | 35 +++++++++++++++++++++++++++++++++++ pc/kanjin.ico | Bin 0 -> 782 bytes 5 files changed, 102 insertions(+) create mode 100644 pc/README.md create mode 100644 pc/build.bat create mode 100644 pc/build.sh create mode 100644 pc/generate_icon.py create mode 100644 pc/kanjin.ico diff --git a/pc/README.md b/pc/README.md new file mode 100644 index 0000000..e5d9be7 --- /dev/null +++ b/pc/README.md @@ -0,0 +1,28 @@ +# pc/ — Kanjin Windows Standalone + +Build a single `.exe` that players can double-click to play — no Python, no IDE, no dependencies. + +## Build it + +```batch +cd pc +build.bat +``` + +Deliver `pc\Kanjin.exe` (~35 MB). The player double-clicks it, a console window opens, the game starts. + +## What's inside + +| File | Purpose | +|---|---| +| `build.bat` | Windows batch script — runs PyInstaller with the right flags | +| `build.sh` | Linux/macOS equivalent (for cross-builds) | +| `kanjin.ico` | Application icon embedded in the .exe | +| `generate_icon.py` | Creates `kanjin.ico` from a solid-colour PNG (run once) | + +## Requirements + +- Python 3.11+ installed on the **build** machine +- `pip install pyinstaller` (installed automatically by build.bat) + +The **player's** machine needs nothing — the .exe is fully self-contained. diff --git a/pc/build.bat b/pc/build.bat new file mode 100644 index 0000000..b3a6b87 --- /dev/null +++ b/pc/build.bat @@ -0,0 +1,20 @@ +@echo off +cd /d "%~dp0" +echo Installing PyInstaller... +pip install pyinstaller + +echo Building Kanjin.exe... +REM --onefile: single executable +REM --name: output filename +REM --icon: application icon +REM --distpath=. : place .exe in this directory (pc/) +REM --workpath: temp build folder (cleaned up) +python -m PyInstaller --onefile --name Kanjin --icon=kanjin.ico --distpath=. --workpath=build_temp ..\main.py + +echo Cleaning up... +rd /s /q build_temp __pycache__ 2>nul +del Kanjin.spec 2>nul + +echo. +echo Done! Deliver pc\Kanjin.exe to players. +pause diff --git a/pc/build.sh b/pc/build.sh new file mode 100644 index 0000000..99c6313 --- /dev/null +++ b/pc/build.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# Cross-platform PyInstaller build (run from pc/ on any OS) +set -euo pipefail +cd "$(dirname "$0")" + +pip install pyinstaller + +python -m PyInstaller \ + --onefile \ + --name Kanjin \ + --icon=kanjin.ico \ + --distpath=. \ + --workpath=build_temp \ + ../main.py + +rm -rf build_temp __pycache__ Kanjin.spec + +echo "" +echo "Done! Deliver pc/Kanjin.exe to players." diff --git a/pc/generate_icon.py b/pc/generate_icon.py new file mode 100644 index 0000000..6780b6c --- /dev/null +++ b/pc/generate_icon.py @@ -0,0 +1,35 @@ +"""Generate kanjin.ico from a solid-colour PNG embedded in an ICO container.""" +import struct +import zlib +from pathlib import Path + + +def _png_chunk(chunk_type, data): + c = chunk_type + data + crc = struct.pack(">I", zlib.crc32(c) & 0xFFFFFFFF) + return struct.pack(">I", len(data)) + c + crc + + +def solid_png_bytes(width, height, r, g, b): + header = b"\x89PNG\r\n\x1a\n" + ihdr = _png_chunk(b"IHDR", struct.pack(">IIBBBBB", width, height, 8, 2, 0, 0, 0)) + raw = bytearray() + for _ in range(height): + raw.append(0) + raw.extend(bytes([r, g, b]) * width) + idat = _png_chunk(b"IDAT", zlib.compress(bytes(raw))) + iend = _png_chunk(b"IEND", b"") + return header + ihdr + idat + iend + + +def make_ico(png_data): + header = struct.pack("W22Kc%2a!GLknY^AJECd?Dk7%uTR l%wqH~9u*u7kO5B&b_t2B`}ZHZTm?+g44$rjF6*2UngG?}+7|!- literal 0 HcmV?d00001