Merge pull request #100 from gwilymk/dedicated-entrypoint

Dedicated #[agb::entry] macro
This commit is contained in:
Gwilym Kuiper 2021-08-07 18:24:25 +01:00 committed by GitHub
commit 7b122b431a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 334 additions and 22 deletions

20
.github/workflows/publish-agb-entry.yml vendored Normal file
View file

@ -0,0 +1,20 @@
name: Publish agb-entry
on:
push:
tags:
- agb-entry/v*
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Install build tools
run: sudo apt-get update && sudo apt-get install build-essential binutils-arm-none-eabi -y
- name: Check out repository
uses: actions/checkout@v2
- name: Login to crates.io
run: cargo login ${{ secrets.CRATE_API }}
- name: Publish agb-entry
run: cargo publish
working-directory: ./agb-entry

View file

@ -38,6 +38,9 @@ jobs:
- name: Run Clippy on agb image converter - name: Run Clippy on agb image converter
working-directory: agb-image-converter working-directory: agb-image-converter
run: cargo clippy --verbose run: cargo clippy --verbose
- name: Run Clippy on agb entry
working-directory: agb-entry
run: cargo clippy --verbose
- name: Run Tests for agb in debug mode - name: Run Tests for agb in debug mode
working-directory: agb working-directory: agb
run: cargo test --verbose run: cargo test --verbose

123
agb-entry/Cargo.lock generated Normal file
View file

@ -0,0 +1,123 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "agb_entry"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"rand",
"syn",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "libc"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "syn"
version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

16
agb-entry/Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "agb_entry"
version = "0.1.0"
authors = ["Gwilym Kuiper <gw@ilym.me>"]
edition = "2018"
license = "MPL-2.0"
description = "Macro for declaring the entry point for a game using the agb library"
[lib]
proc-macro = true
[dependencies]
syn = { version = "1.0.73", features = ["full", "extra-traits"] }
proc-macro2 = "1.0.27"
quote = "1.0.9"
rand = "0.8.4"

62
agb-entry/src/lib.rs Normal file
View file

@ -0,0 +1,62 @@
// This macro is based very heavily on the entry one in rust-embedded
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use rand::Rng;
use syn::{Ident, ItemFn, ReturnType, Type, Visibility};
#[proc_macro_attribute]
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
let f: ItemFn = syn::parse(input).expect("#[agb::entry] must be applied to a function");
// Check that the function signature is correct
assert!(
f.sig.constness.is_none()
&& f.vis == Visibility::Inherited
&& f.sig.abi.is_none()
&& f.sig.inputs.is_empty()
&& f.sig.generics.params.is_empty()
&& f.sig.generics.where_clause.is_none()
&& match f.sig.output {
ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)),
_ => false,
},
"#[agb::entry] must have signature [unsafe] fn () -> !"
);
assert!(
args.to_string() == "",
"Must pass no args to #[agb::entry] macro"
);
let fn_name = random_ident();
let attrs = f.attrs;
let stmts = f.block.stmts;
quote!(
#[export_name = "main"]
#(#attrs)*
pub fn #fn_name() -> ! {
#(#stmts)*
}
)
.into()
}
fn random_ident() -> Ident {
let mut rng = rand::thread_rng();
Ident::new(
&(0..16)
.map(|i| {
if i == 0 || rng.gen() {
(b'a' + rng.gen::<u8>() % 25) as char
} else {
(b'0' + rng.gen::<u8>() % 10) as char
}
})
.collect::<String>(),
Span::call_site(),
)
}

80
agb/Cargo.lock generated
View file

@ -12,10 +12,21 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
name = "agb" name = "agb"
version = "0.6.0" version = "0.6.0"
dependencies = [ dependencies = [
"agb_entry",
"agb_image_converter", "agb_image_converter",
"bitflags", "bitflags",
] ]
[[package]]
name = "agb_entry"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"rand",
"syn",
]
[[package]] [[package]]
name = "agb_image_converter" name = "agb_image_converter"
version = "0.6.0" version = "0.6.0"
@ -83,6 +94,17 @@ dependencies = [
"byteorder", "byteorder",
] ]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "image" name = "image"
version = "0.23.14" version = "0.23.14"
@ -98,6 +120,12 @@ dependencies = [
"png", "png",
] ]
[[package]]
name = "libc"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.3.7" version = "0.3.7"
@ -160,6 +188,12 @@ dependencies = [
"miniz_oxide", "miniz_oxide",
] ]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.28" version = "1.0.28"
@ -178,6 +212,46 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.127" version = "1.0.127"
@ -223,3 +297,9 @@ name = "unicode-xid"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

View file

@ -20,6 +20,7 @@ debug = true
[dependencies] [dependencies]
bitflags = "1.2" bitflags = "1.2"
agb_image_converter = { version = "0.6.0", path = "../agb-image-converter" } agb_image_converter = { version = "0.6.0", path = "../agb-image-converter" }
agb_entry = { version = "0.1.0", path = "../agb-entry" }
[package.metadata.docs.rs] [package.metadata.docs.rs]
default-target = "thumbv6m-none-eabi" default-target = "thumbv6m-none-eabi"

View file

@ -5,8 +5,8 @@ extern crate agb;
use agb::sound; use agb::sound;
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let gba = agb::Gba::new(); let gba = agb::Gba::new();
gba.sound.enable(); gba.sound.enable();

View file

@ -10,8 +10,8 @@ struct Vector2D {
y: i32, y: i32,
} }
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = agb::Gba::new(); let mut gba = agb::Gba::new();
let mut bitmap = gba.display.video.bitmap3(); let mut bitmap = gba.display.video.bitmap3();
let vblank = agb::interrupt::VBlank::get(); let vblank = agb::interrupt::VBlank::get();

View file

@ -5,8 +5,8 @@ extern crate agb;
use agb::display; use agb::display;
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = agb::Gba::new(); let mut gba = agb::Gba::new();
let mut bitmap = gba.display.video.bitmap4(); let mut bitmap = gba.display.video.bitmap4();
let vblank = agb::interrupt::VBlank::get(); let vblank = agb::interrupt::VBlank::get();

View file

@ -35,8 +35,8 @@ fn frame_ranger(count: u32, start: u32, end: u32, delay: u32) -> u16 {
(((count / delay) % (end + 1 - start)) + start) as u16 (((count / delay) % (end + 1 - start)) + start) as u16
} }
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let map_as_grid: &[[u16; 32]; 32] = unsafe { let map_as_grid: &[[u16; 32]; 32] = unsafe {
(&MAP_MAP as *const [u16; 1024] as *const [[u16; 32]; 32]) (&MAP_MAP as *const [u16; 1024] as *const [[u16; 32]; 32])
.as_ref() .as_ref()

View file

@ -11,8 +11,8 @@ use agb::Gba;
// Music - "I will not let you let me down" by Josh Woodward, free download at http://joshwoodward.com // Music - "I will not let you let me down" by Josh Woodward, free download at http://joshwoodward.com
const I_WILL_NOT_LET_YOU_LET_ME_DOWN: &[u8] = include_bytes!("i-will-not-let-you-let-me-down.raw"); const I_WILL_NOT_LET_YOU_LET_ME_DOWN: &[u8] = include_bytes!("i-will-not-let-you-let-me-down.raw");
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = Gba::new(); let mut gba = Gba::new();
let mut input = ButtonController::new(); let mut input = ButtonController::new();
let vblank_provider = agb::interrupt::VBlank::get(); let vblank_provider = agb::interrupt::VBlank::get();

View file

@ -10,8 +10,8 @@ struct Vector2D {
y: i32, y: i32,
} }
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = agb::Gba::new(); let mut gba = agb::Gba::new();
let vblank = agb::interrupt::VBlank::get(); let vblank = agb::interrupt::VBlank::get();
let mut input = agb::input::ButtonController::new(); let mut input = agb::input::ButtonController::new();

View file

@ -2,8 +2,9 @@
#![no_main] #![no_main]
extern crate agb; extern crate agb;
#[no_mangle]
pub fn main() -> ! { #[agb::entry]
fn main() -> ! {
let count = agb::interrupt::Mutex::new(0); let count = agb::interrupt::Mutex::new(0);
agb::add_interrupt_handler!(agb::interrupt::Interrupt::VBlank, |key| { agb::add_interrupt_handler!(agb::interrupt::Interrupt::VBlank, |key| {
let mut count = count.lock_with_key(&key); let mut count = count.lock_with_key(&key);

View file

@ -5,8 +5,8 @@ extern crate agb;
use agb::display; use agb::display;
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = agb::Gba::new(); let mut gba = agb::Gba::new();
let mut bitmap = gba.display.video.bitmap3(); let mut bitmap = gba.display.video.bitmap3();

View file

@ -4,8 +4,8 @@
extern crate agb; extern crate agb;
use agb::{display, syscall}; use agb::{display, syscall};
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = agb::Gba::new(); let mut gba = agb::Gba::new();
let mut bitmap = gba.display.video.bitmap3(); let mut bitmap = gba.display.video.bitmap3();

View file

@ -5,8 +5,8 @@ extern crate agb;
use agb::display::example_logo; use agb::display::example_logo;
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = agb::Gba::new(); let mut gba = agb::Gba::new();
let mut gfx = gba.display.video.tiled0(); let mut gfx = gba.display.video.tiled0();

View file

@ -14,8 +14,8 @@ struct BackCosines {
row: usize, row: usize,
} }
#[no_mangle] #[agb::entry]
pub fn main() -> ! { fn main() -> ! {
let mut gba = agb::Gba::new(); let mut gba = agb::Gba::new();
let mut gfx = gba.display.video.tiled0(); let mut gfx = gba.display.video.tiled0();

View file

@ -22,6 +22,8 @@ pub mod sound;
pub use agb_image_converter::include_gfx; pub use agb_image_converter::include_gfx;
pub use agb_entry::entry;
mod bitarray; mod bitarray;
pub mod interrupt; pub mod interrupt;
mod memory_mapped; mod memory_mapped;

View file

@ -28,6 +28,10 @@ case "$PROJECT" in
DIRECTORY="agb-image-converter" DIRECTORY="agb-image-converter"
TAGNAME="agb-image-converter/v$VERSION" TAGNAME="agb-image-converter/v$VERSION"
;; ;;
agb-entry)
DIRECTORY="agb-entry"
TAGNAME="agb-entry/v$VERSION"
;;
mgba-test-runner) mgba-test-runner)
DIRECTORY="mgba-test-runner" DIRECTORY="mgba-test-runner"
TAGNAME="mgba-test-runner/v$VERSION" TAGNAME="mgba-test-runner/v$VERSION"