mirror of
https://github.com/kittywitch/katgba.git
synced 2025-12-22 00:09:17 -08:00
feat: make build :o
This commit is contained in:
commit
3c055d49e9
13 changed files with 521 additions and 0 deletions
8
.cargo/config.toml
Normal file
8
.cargo/config.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
[build]
|
||||||
|
target = "thumbv4t-none-eabi"
|
||||||
|
|
||||||
|
[unstable]
|
||||||
|
build-std = ["core"]
|
||||||
|
|
||||||
|
[target.thumbv4t-none-eabi]
|
||||||
|
runner = "mgba-qt" # sets the emulator to run bins/examples with
|
||||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
/target
|
||||||
|
/result
|
||||||
|
/.direnv
|
||||||
|
/vendor
|
||||||
56
Cargo.lock
generated
Normal file
56
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitfrob"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4de3bf9292416bc27b97603d1af580e4253138851ce3898f878807b898e90d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bracer"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "00248d542917c4ef013367c0907300e9befbbc1f99b12938c9e5a356ab50582d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.23.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gba"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dff72a04df599de9991069ab6807f00e02dc24840e13d16f92dfa2929c4e6950"
|
||||||
|
dependencies = [
|
||||||
|
"bitfrob",
|
||||||
|
"bracer",
|
||||||
|
"bytemuck",
|
||||||
|
"voladdress",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gbafix"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7e47af9d5377b8b0def53d9916f6c28521f2e5b97c5fec137797417c26ab4b7"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "katgba"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"gba",
|
||||||
|
"gbafix",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "voladdress"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75f4a9a7c7e717541992e2405d44d12fb019db4117ec9fcca84b784060b27084"
|
||||||
13
Cargo.toml
Normal file
13
Cargo.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "katgba"
|
||||||
|
description = "kat video game"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
include = ["src/foo.txt", "/build/linker_scripts"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
gba = "0.14.1"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
gbafix = "1.0.4"
|
||||||
6
build.rs
Normal file
6
build.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rustc-link-arg=-Tbuild/linker_scripts/mono_boot.ld");
|
||||||
|
println!("cargo:rustc-linker=arm-none-eabi-ld");
|
||||||
|
println!("cargo::rerun-if-changed=build.rs");
|
||||||
|
println!("cargo::rerun-if-changed=src/foo.txt");
|
||||||
|
}
|
||||||
99
build/linker_scripts/mono_boot.ld
Normal file
99
build/linker_scripts/mono_boot.ld
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* THIS LINKER SCRIPT FILE IS RELEASED TO THE PUBLIC DOMAIN (SPDX: CC0-1.0) */
|
||||||
|
|
||||||
|
ENTRY(__start)
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
ewram (w!x) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||||
|
iwram (w!x) : ORIGIN = 0x3000000, LENGTH = 32K
|
||||||
|
rom (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.text : {
|
||||||
|
/* be sure that the ROM header is the very first */
|
||||||
|
*(.text.gba_rom_header);
|
||||||
|
*(.text .text.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >rom = 0x00
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >rom = 0x00
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__iwram_position_in_rom = .;
|
||||||
|
.data : {
|
||||||
|
__iwram_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.data .data.*);
|
||||||
|
*(.iwram .iwram.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
__iwram_end = ABSOLUTE(.);
|
||||||
|
} >iwram AT>rom = 0x00
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__ewram_position_in_rom = __iwram_position_in_rom + (__iwram_end - __iwram_start);
|
||||||
|
.ewram : {
|
||||||
|
__ewram_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.ewram .ewram.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
__ewram_end = ABSOLUTE(.);
|
||||||
|
} >ewram AT>rom = 0x00
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_position_in_rom = __ewram_position_in_rom + (__ewram_end - __ewram_start);
|
||||||
|
.bss : {
|
||||||
|
__bss_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.bss .bss.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
__bss_end = ABSOLUTE(.);
|
||||||
|
} >iwram
|
||||||
|
|
||||||
|
__iwram_word_copy_count = (__iwram_end - __iwram_start) / 4;
|
||||||
|
__ewram_word_copy_count = (__ewram_end - __ewram_start) / 4;
|
||||||
|
__bss_word_clear_count = (__bss_end - __bss_start) / 4;
|
||||||
|
|
||||||
|
/* rust-lld demands we keep the `section header string table` */
|
||||||
|
.shstrtab 0 : { *(.shstrtab) }
|
||||||
|
|
||||||
|
/* debugging sections */
|
||||||
|
/* Stabs */
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
.stab.excl 0 : { *(.stab.excl) }
|
||||||
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||||
|
.stab.index 0 : { *(.stab.index) }
|
||||||
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
/* DWARF 1 */
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
/* GNU DWARF 1 extensions */
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
/* DWARF 2 */
|
||||||
|
.debug_info 0 : { *(.debug_info) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_frame 0 : { *(.debug_frame) }
|
||||||
|
.debug_str 0 : { *(.debug_str) }
|
||||||
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
/* SGI/MIPS DWARF 2 extensions */
|
||||||
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||||
|
.debug_typenames 0 : { *(.debug_typenames) }
|
||||||
|
.debug_varnames 0 : { *(.debug_varnames) }
|
||||||
|
|
||||||
|
/* discard anything not already mentioned */
|
||||||
|
/DISCARD/ : { *(*) }
|
||||||
|
}
|
||||||
98
flake.lock
generated
Normal file
98
flake.lock
generated
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"crane": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1752946753,
|
||||||
|
"narHash": "sha256-g5uP3jIj+STUcfTJDKYopxnSijs2agRg13H0SGL5iE4=",
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"rev": "544d09fecc8c2338542c57f3f742f1a0c8c71e13",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1753151930,
|
||||||
|
"narHash": "sha256-XSQy6wRKHhRe//iVY5lS/ZpI/Jn6crWI8fQzl647wCg=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "83e677f31c84212343f4cc553bab85c2efcad60a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"crane": "crane",
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1753238793,
|
||||||
|
"narHash": "sha256-jmQeEpgX+++MEgrcikcwoSiI7vDZWLP0gci7XiWb9uQ=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "0ad7ab4ca8e83febf147197e65c006dff60623ab",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
64
flake.nix
Normal file
64
flake.nix
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
description = "gba";
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
crane.url = "github:ipetkov/crane";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
rust-overlay = {
|
||||||
|
url = "github:oxalica/rust-overlay";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{
|
||||||
|
nixpkgs,
|
||||||
|
flake-utils,
|
||||||
|
rust-overlay,
|
||||||
|
crane,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
rustTriple = "thumbv4t-none-eabi";
|
||||||
|
nixTriple = "arm-none-eabi";
|
||||||
|
in flake-utils.lib.eachDefaultSystem (system: let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [ (import rust-overlay) ];
|
||||||
|
};
|
||||||
|
pkgsCross = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
config = {
|
||||||
|
allowUnsupportedSystem = true;
|
||||||
|
#replaceStdenv = ({ pkgs }: pkgs.clangStdenvNoLibs );
|
||||||
|
};
|
||||||
|
crossSystem = {
|
||||||
|
config = nixTriple;
|
||||||
|
libc = "newlib";
|
||||||
|
#rust.rustcTarget = rustTriple;
|
||||||
|
gcc = {
|
||||||
|
arch = "armv4t";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
rustToolchainFor =
|
||||||
|
p:
|
||||||
|
p.rust-bin.selectLatestNightlyWith (
|
||||||
|
toolchain:
|
||||||
|
toolchain.minimal.override {
|
||||||
|
extensions = [ "rust-src" ];
|
||||||
|
targets = [ ];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
rustToolchain = rustToolchainFor pkgs;
|
||||||
|
|
||||||
|
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchainFor;
|
||||||
|
|
||||||
|
myPackage = pkgs.callPackage ./package.nix { inherit craneLib rustToolchain rustTriple; };
|
||||||
|
in {
|
||||||
|
inherit pkgsCross;
|
||||||
|
packages.default = myPackage;
|
||||||
|
});
|
||||||
|
}
|
||||||
56
package.nix
Normal file
56
package.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
{ lib, craneLib, rustToolchain, rustTriple, gcc-arm-embedded }: let
|
||||||
|
linkerFilter = path: _type: builtins.match ".ld$" path != null;
|
||||||
|
txtFilter = path: _type: builtins.match ".txt$" path != null;
|
||||||
|
linkerOrCargo = path: type:
|
||||||
|
(linkerFilter path type) || (txtFilter path type ) || (craneLib.filterCargoSources path type);
|
||||||
|
commonArgs = let
|
||||||
|
unfilteredRoot = ./.;
|
||||||
|
src = lib.fileset.toSource {
|
||||||
|
root = unfilteredRoot;
|
||||||
|
fileset = lib.fileset.unions [
|
||||||
|
# Default files from crane (Rust and cargo files)
|
||||||
|
(craneLib.fileset.commonCargoSources unfilteredRoot)
|
||||||
|
# Also keep any linker files
|
||||||
|
(lib.fileset.fileFilter (file: file.hasExt "ld") unfilteredRoot)
|
||||||
|
# Also keep any txt files
|
||||||
|
(lib.fileset.fileFilter (file: file.hasExt "txt") unfilteredRoot)
|
||||||
|
# Example of a folder for images, icons, etc
|
||||||
|
(lib.fileset.maybeMissing ./src/foo.txt)
|
||||||
|
(lib.fileset.maybeMissing ./build.rs)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
inherit src;
|
||||||
|
strictDeps = true;
|
||||||
|
cargoVendorDir = craneLib.vendorMultipleCargoDeps rec {
|
||||||
|
inherit (craneLib.findCargoFiles src) cargoConfigs;
|
||||||
|
cargoLockList = [
|
||||||
|
"${unfilteredRoot}/Cargo.lock"
|
||||||
|
# Unfortunately this approach requires IFD (import-from-derivation)
|
||||||
|
# otherwise Nix will refuse to read the Cargo.lock from our toolchain
|
||||||
|
# (unless we build with `--impure`).
|
||||||
|
#
|
||||||
|
# Another way around this is to manually copy the rustlib `Cargo.lock`
|
||||||
|
# to the repo and import it with `./path/to/rustlib/Cargo.lock` which
|
||||||
|
# will avoid IFD entirely but will require manually keeping the file
|
||||||
|
# up to date!
|
||||||
|
"${rustToolchain.passthru.availableComponents.rust-src}/lib/rustlib/src/rust/library/Cargo.lock"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
cargoExtraArgs = "-Z build-std --target ${rustTriple}";
|
||||||
|
nativeBuildInputs = [
|
||||||
|
# Add additional build inputs here
|
||||||
|
gcc-arm-embedded
|
||||||
|
];
|
||||||
|
doCheck = false;
|
||||||
|
};
|
||||||
|
artifacts = craneLib.buildDepsOnly(commonArgs // {
|
||||||
|
pname = "katgba-deps";
|
||||||
|
});
|
||||||
|
package = craneLib.buildPackage (commonArgs // rec{
|
||||||
|
cargoArtifacts = artifacts;
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
});
|
||||||
|
in package
|
||||||
5
rust-toolchain.toml
Normal file
5
rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
|
targets = ["thumbv4t-none-eabi"]
|
||||||
|
profile = "minimal"
|
||||||
|
components = ["rust-src", "clippy", "rustfmt"]
|
||||||
10
shell.nix
Normal file
10
shell.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
mkShell,
|
||||||
|
mgba,
|
||||||
|
rust-bin
|
||||||
|
}: mkShell {
|
||||||
|
packages = [
|
||||||
|
rust-bin.selectLatestNightlyWith (toolchain: toolchain.default)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
1
src/foo.txt
Normal file
1
src/foo.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
usedinhello.rs
|
||||||
101
src/main.rs
Normal file
101
src/main.rs
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use gba::prelude::*;
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Fatal) {
|
||||||
|
writeln!(logger, "{info}").ok();
|
||||||
|
}
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
const FOO: Align4<[u8; 14]> = include_aligned_bytes!("foo.txt");
|
||||||
|
|
||||||
|
#[unsafe(link_section = ".ewram")]
|
||||||
|
static FRAME_KEYS: GbaCell<KeyInput> = GbaCell::new(KeyInput::new());
|
||||||
|
|
||||||
|
#[unsafe(link_section = ".iwram")]
|
||||||
|
extern "C" fn irq_handler(_: IrqBits) {
|
||||||
|
// We'll read the keys during vblank and store it for later.
|
||||||
|
FRAME_KEYS.write(KEYINPUT.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
extern "C" fn main() -> ! {
|
||||||
|
RUST_IRQ_HANDLER.write(Some(irq_handler));
|
||||||
|
DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
|
||||||
|
IE.write(IrqBits::VBLANK);
|
||||||
|
IME.write(true);
|
||||||
|
|
||||||
|
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Debug) {
|
||||||
|
writeln!(logger, "hello!").ok();
|
||||||
|
|
||||||
|
let fx_u: Fixed<u32, 8> =
|
||||||
|
Fixed::<u32, 8>::wrapping_from(7) + Fixed::<u32, 8>::from_bits(12);
|
||||||
|
writeln!(logger, "fixed unsigned: {fx_u:?}").ok();
|
||||||
|
|
||||||
|
let fx_i1: Fixed<i32, 8> =
|
||||||
|
Fixed::<i32, 8>::wrapping_from(8) + Fixed::<i32, 8>::from_bits(15);
|
||||||
|
writeln!(logger, "fixed signed positive: {fx_i1:?}").ok();
|
||||||
|
|
||||||
|
let fx_i2: Fixed<i32, 8> = Fixed::<i32, 8>::wrapping_from(0)
|
||||||
|
- Fixed::<i32, 8>::wrapping_from(3)
|
||||||
|
- Fixed::<i32, 8>::from_bits(17);
|
||||||
|
writeln!(logger, "fixed signed negative: {fx_i2:?}").ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// get our tile data into memory.
|
||||||
|
Cga8x8Thick.bitunpack_4bpp(CHARBLOCK0_4BPP.as_region(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// set up the tilemap
|
||||||
|
let tsb = TEXT_SCREENBLOCKS.get_frame(31).unwrap();
|
||||||
|
for y in 0..16 {
|
||||||
|
let row = tsb.get_row(y).unwrap();
|
||||||
|
for (x, addr) in row.iter().enumerate().take(16) {
|
||||||
|
let te = TextEntry::new().with_tile((y * 16 + x) as u16);
|
||||||
|
addr.write(te);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Set BG0 to use the tilemap we just made, and set it to be shown.
|
||||||
|
BG0CNT.write(BackgroundControl::new().with_screenblock(31));
|
||||||
|
DISPCNT.write(DisplayControl::new().with_show_bg0(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut x_off = 0_u32;
|
||||||
|
let mut y_off = 0_u32;
|
||||||
|
let mut backdrop_color = Color(0);
|
||||||
|
loop {
|
||||||
|
VBlankIntrWait();
|
||||||
|
// show current frame
|
||||||
|
BACKDROP_COLOR.write(backdrop_color);
|
||||||
|
BG0HOFS.write(x_off as u16);
|
||||||
|
BG0VOFS.write(y_off as u16);
|
||||||
|
|
||||||
|
// prep next frame
|
||||||
|
let k = FRAME_KEYS.read();
|
||||||
|
backdrop_color = Color(k.to_u16());
|
||||||
|
if k.up() {
|
||||||
|
y_off = y_off.wrapping_add(1);
|
||||||
|
}
|
||||||
|
if k.down() {
|
||||||
|
y_off = y_off.wrapping_sub(1);
|
||||||
|
}
|
||||||
|
if k.left() {
|
||||||
|
x_off = x_off.wrapping_add(1);
|
||||||
|
}
|
||||||
|
if k.right() {
|
||||||
|
x_off = x_off.wrapping_sub(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue