Compare commits

..

10 Commits

11 changed files with 226 additions and 55 deletions

1
.gitattributes vendored
View File

@ -4,6 +4,7 @@
*.html text eol=lf diff=html *.html text eol=lf diff=html
*.java text eol=lf diff=java *.java text eol=lf diff=java
*.js text eol=lf diff=js *.js text eol=lf diff=js
*.sh text eol=lf
*.txt text eol=lf *.txt text eol=lf
*.class binary *.class binary

View File

@ -1,42 +0,0 @@
name: Release New Version
run-name: ${{ gitea.actor }} is releasing a new version
on: [push]
jobs:
Release:
runs-on: lemur-build
steps:
- name: Check out repository code
uses: taiki-e/checkout-action@v1
- name: Prepare artifacts dir
run: mkdir -p /artifacts
- name: Build for Linux
run: |
cargo build --release
cp target/release/lemur /artifacts/lemur-linux
- name: Bundle for Linux
run: |
cargo bundle --release --format deb
cp target/release/bundle/deb/*.deb /artifacts
- name: Build for Windows
run: |
cargo build --release --target x86_64-pc-windows-msvc
cp target/x86_64-pc-windows-msvc/release/lemur.exe /artifacts
- name: Bundle for Windows
run: |
cargo bundle --release --target x86_64-pc-windows-msvc --format msi
cp target/x86_64-pc-windows-msvc/release/bundle/msi/Lemur.msi /artifacts
- name: Build for MacOS
run: |
cargo build --release --target x86_64-apple-darwin
cp target/x86_64-apple-darwin/release/lemur /artifacts/lemur-osx
- name: Bundle for MacOS
run: |
cargo bundle --release --target x86_64-apple-darwin --format osx
genisoimage -V lemur -D -R -apple -no-pad -o /artifacts/Lemur.dmg target/x86_64-apple-darwin/release/bundle/osx/Lemur.app
- name: Create Release
uses: https://gitea.com/actions/release-action@main
with:
files: |-
/artifacts/**
api-key: '${{secrets.RELEASE_TOKEN}}'

39
Cargo.lock generated
View File

@ -1770,7 +1770,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]] [[package]]
name = "lemur" name = "lemur"
version = "0.1.0" version = "0.1.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitflags 2.6.0", "bitflags 2.6.0",
@ -1800,6 +1800,7 @@ dependencies = [
"wgpu", "wgpu",
"windows 0.58.0", "windows 0.58.0",
"winit", "winit",
"winresource",
] ]
[[package]] [[package]]
@ -2879,6 +2880,15 @@ dependencies = [
"syn 2.0.90", "syn 2.0.90",
] ]
[[package]]
name = "serde_spanned"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"
@ -3132,11 +3142,26 @@ dependencies = [
"zerovec", "zerovec",
] ]
[[package]]
name = "toml"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.8" version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
@ -3145,6 +3170,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"serde",
"serde_spanned",
"toml_datetime", "toml_datetime",
"winnow", "winnow",
] ]
@ -4085,6 +4112,16 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "winresource"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7276691b353ad4547af8c3268488d1311f4be791ffdc0c65b8cfa8f41eed693b"
dependencies = [
"toml",
"version_check",
]
[[package]] [[package]]
name = "write16" name = "write16"
version = "1.0.0" version = "1.0.0"

View File

@ -1,7 +1,10 @@
[package] [package]
name = "lemur" name = "lemur"
description = "An emulator for the Virtual Boy." description = "An emulator for the Virtual Boy."
version = "0.1.0" repository = "https://git.virtual-boy.com/PVB/lemur"
publish = false
license = "MIT"
version = "0.1.2"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
@ -37,6 +40,7 @@ windows = { version = "0.58", features = ["Win32_System_Threading"] }
[build-dependencies] [build-dependencies]
cc = "1" cc = "1"
winresource = "0.1"
[profile.release] [profile.release]
lto = true lto = true
@ -45,4 +49,4 @@ lto = true
name = "Lemur" name = "Lemur"
identifier = "com.virtual-boy.Lemur" identifier = "com.virtual-boy.Lemur"
icon = ["assets/lemur-256x256.png"] icon = ["assets/lemur-256x256.png"]
category = "games" category = "games"

View File

@ -12,4 +12,14 @@ Run
cargo build --release cargo build --release
``` ```
The executable will be in `target/release/lemur[.exe]` The executable will be in `target/release/lemur[.exe]`
## Release
Bump the version number in `Cargo.toml`, then run this script:
```sh
./scripts/release.sh
```
It uses docker to cross compile for Windows, MacOS, and Linux. All binaries are left in the `output` directory.

BIN
assets/lemur.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -6,18 +6,29 @@ FROM crazymax/osxcross:latest-ubuntu AS osxcross
FROM rust:latest FROM rust:latest
RUN rustup target add x86_64-pc-windows-msvc && \ RUN rustup target add x86_64-pc-windows-msvc && \
rustup target add x86_64-apple-darwin && \ rustup target add x86_64-apple-darwin && \
rustup target add aarch64-apple-darwin && \
apt-get update && \ apt-get update && \
apt-get install -y clang lld libc6-dev libasound2-dev libudev-dev genisoimage && \ apt-get install -y clang-19 lld-19 libc6-dev libasound2-dev libudev-dev genisoimage mingw-w64 && \
cargo install cargo-bundle xwin cargo install cargo-bundle xwin && \
xwin --accept-license splat --output xwin && \
rm -rf .xwin-cache && \
ln -s $(which clang-19) /usr/bin/clang && \
ln -s $(which clang++-19) /usr/bin/clang++
COPY --from=osxcross /osxcross /osxcross COPY --from=osxcross /osxcross /osxcross
RUN xwin --accept-license splat --output xwin && rm -rf .xwin-cache
ENV PATH="/osxcross/bin:$PATH" \ ENV PATH="/osxcross/bin:$PATH" \
LD_LIBRARY_PATH="/osxcross/lib" \ LD_LIBRARY_PATH="/osxcross/lib" \
CC="clang" CXX="clang++" AR="llvm-ar-14" \ CC="clang-19" CXX="clang++-19" AR="llvm-ar-19" \
CC_x86_64-apple-darwin="o64-clang" \ CC_x86_64-apple-darwin="o64-clang" \
CXX_x86_64-apple-darwin="o64-clang++" \ CXX_x86_64-apple-darwin="o64-clang++" \
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER="lld-link" \ CC_aarch64-apple-darwin="oa64-clang" \
CXX_aarch64-apple-darwin="o6a4-clang++" \
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER="lld-link-19" \
CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER="o64-clang" \ CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER="o64-clang" \
CARGO_TARGET_X86_64_APPLE_DARWIN_AR="llvm-ar-14" \ CARGO_TARGET_X86_64_APPLE_DARWIN_AR="llvm-ar-19" \
CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER="oa64-clang" \
CARGO_TARGET_AARCH64_APPLE_DARWIN_AR="llvm-ar-19" \
CROSS_COMPILE="setting-this-to-silence-a-warning-" \
RC_PATH="llvm-rc-19" \
RUSTFLAGS="-Lnative=/xwin/crt/lib/x86_64 -Lnative=/xwin/sdk/lib/um/x86_64 -Lnative=/xwin/sdk/lib/ucrt/x86_64" \ RUSTFLAGS="-Lnative=/xwin/crt/lib/x86_64 -Lnative=/xwin/sdk/lib/um/x86_64 -Lnative=/xwin/sdk/lib/ucrt/x86_64" \
MACOSX_DEPLOYMENT_TARGET="14.5" MACOSX_DEPLOYMENT_TARGET="14.5"

View File

@ -1,6 +1,12 @@
use std::path::Path; use std::{error::Error, path::Path};
fn main() -> Result<(), Box<dyn Error>> {
if std::env::var("CARGO_CFG_TARGET_OS")? == "windows" {
let mut res = winresource::WindowsResource::new();
res.set_icon("assets/lemur.ico");
res.compile()?;
}
fn main() {
println!("cargo::rerun-if-changed=shrooms-vb-core"); println!("cargo::rerun-if-changed=shrooms-vb-core");
cc::Build::new() cc::Build::new()
.include(Path::new("shrooms-vb-core/core")) .include(Path::new("shrooms-vb-core/core"))
@ -11,4 +17,6 @@ fn main() {
.define("VB_DIV_GENERIC", None) .define("VB_DIV_GENERIC", None)
.file(Path::new("shrooms-vb-core/core/vb.c")) .file(Path::new("shrooms-vb-core/core/vb.c"))
.compile("vb"); .compile("vb");
Ok(())
} }

35
scripts/do-bundle.sh Normal file
View File

@ -0,0 +1,35 @@
# Set everything up
rm -rf output
mkdir -p output
cargo clean
# Build for linux
cargo build --release
cp target/release/lemur output/lemur-linux
# Bundle for Linux
cargo bundle --release --format deb
cp target/release/bundle/deb/*.deb output
# Build for Windows
cargo build --release --target x86_64-pc-windows-msvc
cp target/x86_64-pc-windows-msvc/release/lemur.exe output
# Build for MacOS Intel
cargo build --release --target x86_64-apple-darwin
cp target/x86_64-apple-darwin/release/lemur output/lemur-osx-intel
# Bundle for MacOS Intel
cargo bundle --release --target x86_64-apple-darwin --format osx
genisoimage -V lemur -D -R -apple -no-pad -o output/Lemur-Intel.dmg target/x86_64-apple-darwin/release/bundle/osx
# Build for MacOS Apple Silicon
cargo build --release --target aarch64-apple-darwin
cp target/aarch64-apple-darwin/release/lemur output/lemur-osx-apple-silicon
# Bundle for MacOS Apple Silicon
cargo bundle --release --target aarch64-apple-darwin --format osx
genisoimage -V lemur -D -R -apple -no-pad -o output/Lemur-Apple-Silicon.dmg target/aarch64-apple-darwin/release/bundle/osx
# Clean up after ourselves
cargo clean

65
scripts/release.sh Executable file
View File

@ -0,0 +1,65 @@
version=$(cat Cargo.toml | sed -n -e '/version/ {s/.* = *//p;q}' | tr -d '"')
read -p "You wanted to release $version, right? [Y/n] " -n 1 -r
echo
case "$REPLY" in
n|N ) exit 1;;
esac
if [ -z "${RELEASE_TOKEN}" ]; then
echo "Please set the RELEASE_TOKEN env var."
exit 1
fi
if ! command -v curl 2>&1 >/dev/null; then
echo "Please install curl."
exit 1
fi
if ! command -v jq 2>&1 >/dev/null; then
echo "Please install jq."
exit 1
fi
docker build -f build.Dockerfile -t lemur-build .
MSYS_NO_PATHCONV=1 docker run -it --rm -v .:/app -w /app --entrypoint bash lemur-build /app/scripts/do-bundle.sh
read -r -d EOF 'body' <<EOF
## How to install
The emulator can be found in the "Downloads" section of this release.
### Windows users
Download \`lemur.exe\`.
### MacOS users
If your Mac uses an Intel processor, download and install \`Lemur-Intel.dmg\`.
If it uses Apple Silicon, download and install \`Lemur-Apple-Silicon.dmg\`.
If you're not sure which to choose, use [this guide](https://support.apple.com/en-us/116943) to find out.
### Linux users
You can either download and run \`lemur-linux\`, or download and install the attached .deb file.
EOF
read -r -d EOF 'payload' <<EOF
{
"body": $(echo "$body" | jq -Rsa .),
"draft": false,
"name": "v${version}",
"prerelease": false,
"tag_name": "v${version}"
}
EOF
echo "Creating release..."
response=$(curl -s --json "$payload" "https://git.virtual-boy.com/api/v1/repos/PVB/lemur/releases?token=$RELEASE_TOKEN")
echo "$response"
upload_url=$(echo "$response" | jq -r '.upload_url')
for file in output/*; do
echo "Uploading $(basename "$file")..."
upload_res=$(curl -s -F "attachment=@$file" "$upload_url?name=$(basename "$file")&token=$RELEASE_TOKEN")
echo "$upload_res"
done

View File

@ -1,4 +1,7 @@
use std::{path::PathBuf, process}; // hide console in release mode
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use std::{path::PathBuf, process, time::SystemTime};
use anyhow::Result; use anyhow::Result;
use app::Application; use app::Application;
@ -21,6 +24,43 @@ struct Args {
rom: Option<PathBuf>, rom: Option<PathBuf>,
} }
fn set_panic_handler() {
std::panic::set_hook(Box::new(|info| {
let mut message = String::new();
if let Some(msg) = info.payload().downcast_ref::<&str>() {
message += &format!("{}\n", msg);
} else if let Some(msg) = info.payload().downcast_ref::<String>() {
message += &format!("{}\n", msg);
}
if let Some(location) = info.location() {
message += &format!(
" in file '{}' at line {}\n",
location.file(),
location.line()
);
}
let backtrace = std::backtrace::Backtrace::force_capture();
message += &format!("stack trace:\n{:#}\n", backtrace);
eprint!("{}", message);
let Some(project_dirs) = directories::ProjectDirs::from("com", "virtual-boy", "Lemur")
else {
return;
};
let data_dir = project_dirs.data_dir();
if std::fs::create_dir_all(data_dir).is_err() {
return;
}
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis();
let logfile_name = format!("crash-{}.txt", timestamp);
let _ = std::fs::write(data_dir.join(logfile_name), message);
}));
}
#[cfg(windows)] #[cfg(windows)]
fn set_process_priority_to_high() -> Result<()> { fn set_process_priority_to_high() -> Result<()> {
use windows::Win32::{Foundation, System::Threading}; use windows::Win32::{Foundation, System::Threading};
@ -31,6 +71,8 @@ fn set_process_priority_to_high() -> Result<()> {
} }
fn main() -> Result<()> { fn main() -> Result<()> {
set_panic_handler();
#[cfg(windows)] #[cfg(windows)]
set_process_priority_to_high()?; set_process_priority_to_high()?;