### Run Development Server Source: https://github.com/agbrs/agb/blob/master/website/agb/README.md Commands to start the development server for a Next.js project. Use the package manager that corresponds to your project setup. ```bash npm run dev # or yarn dev # or pnpm dev # or bun dev ``` -------------------------------- ### Install Git on Fedora Source: https://github.com/agbrs/agb/blob/master/book/src/setup/linux.md Installs the Git version control system on Fedora. ```bash sudo dnf install git ``` -------------------------------- ### Install mGBA on Arch Linux Source: https://github.com/agbrs/agb/blob/master/book/src/setup/linux.md Installs the mGBA emulator on Arch Linux. ```bash sudo pacman -S mgba-qt ``` -------------------------------- ### Main Game Loop Setup Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/07_collision.md Initializes the game, including graphics, level loading, input handling, and player setup. This function demonstrates how to integrate the player's update method with the game loop and rendering. ```rust #[agb::entry] fn main(mut gba: agb::Gba) -> ! { let mut gfx = gba.graphics.get(); gfx.set_background_palettes(tiles::PALETTES); let level = levels::LEVELS[0]; let mut bg = World::new(level); let mut input = ButtonController::new(); let mut player = Player::new(level.player_start.into()); loop { input.update(); bg.set_pos(vec2(0, 0)); player.update(&input, level); let mut frame = gfx.frame(); bg.show(&mut frame); player.show(&mut frame); frame.commit(); } } ``` -------------------------------- ### Install agb-gbafix using Cargo Source: https://github.com/agbrs/agb/blob/master/book/src/setup/linux.md Installs the agb-gbafix utility using the Cargo package manager. Ensure Cargo's bin directory is in your PATH. ```bash cargo install agb-gbafix ``` -------------------------------- ### Install Git on Arch Linux Source: https://github.com/agbrs/agb/blob/master/book/src/setup/linux.md Installs the Git version control system on Arch Linux. ```bash sudo pacman -S git ``` -------------------------------- ### Install mgba-test-runner Source: https://github.com/agbrs/agb/blob/master/book/src/articles/unit_tests.md Install the test runner using cargo. Ensure cmake and libelf are installed, along with C and C++ compilers. ```sh cargo install --git https://github.com/agbrs/agb.git mgba-test-runner ``` -------------------------------- ### Setup Background Palettes Source: https://github.com/agbrs/agb/blob/master/book/src/articles/backgrounds.md Initialize the graphics system by setting the background palettes using the `set_background_palettes` method. This associates colors with the imported tile set. ```rust use agb:: include_background_gfx; include_background_gfx!( mod background, BEACH => deduplicate "gfx/beach-background.aseprite" ); #[agb::entry] fn main(mut gba: agb::Gba) -> ! { let mut gfx = gba.graphics.get(); gfx.set_background_palettes(background::PALETTES); loop {} } ``` -------------------------------- ### Install Git on Debian/Ubuntu Source: https://github.com/agbrs/agb/blob/master/book/src/setup/linux.md Installs the Git version control system on Debian-based Linux distributions. ```bash sudo apt install git ``` -------------------------------- ### Install mGBA on Debian/Ubuntu Source: https://github.com/agbrs/agb/blob/master/book/src/setup/linux.md Installs the mGBA emulator on Debian-based Linux distributions. ```bash sudo apt install mgba-qt ``` -------------------------------- ### Install agb-debug CLI Source: https://github.com/agbrs/agb/blob/master/book/src/articles/panics.md Install the `agb-debug` tool to help decode panic codes into stack traces. This requires Cargo and Git. ```sh cargo install --git=https://github.com/agbrs/agb.git agb-debug ``` -------------------------------- ### Run Full AGB Build with 'just ci' Source: https://github.com/agbrs/agb/blob/master/README.md Execute a full build of the AGB library and its components using the 'just ci' command. Ensure all necessary development tools are installed beforehand. ```sh just ci ``` -------------------------------- ### Initialize and Update ButtonController Source: https://github.com/agbrs/agb/blob/master/book/src/articles/input.md Create a `ButtonController` instance and update its state each frame to track button inputs. This is the fundamental setup for handling input. ```rust use agb::input::ButtonController; let mut button_controller = ButtonController::new(); loop { button_controller.update(); // Do your game logic using the button_controller let mut frame = gfx.frame(); // ... frame.commit(); } ``` -------------------------------- ### Initialize and Show Player in Main Loop Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/06_the_player.md Integrate player creation and rendering into the main game loop. The player is initialized with a starting position and shown in each frame. ```rust #[agb::entry] fn main(mut gba: agb::Gba) -> ! { let mut gfx = gba.graphics.get(); gfx.set_background_palettes(tiles::PALETTES); let level = levels::LEVELS[0]; let mut bg = World::new(level); let mut player = Player::new(level.player_start.into()); loop { bg.set_pos(vec2(0, 0)); let mut frame = gfx.frame(); bg.show(&mut frame); player.show(&mut frame); frame.commit(); } } ``` -------------------------------- ### Convert Binary to GBA File Source: https://github.com/agbrs/agb/blob/master/examples/amplitude/README.md After building in release mode, use `agb-gbafix` to convert the binary into a `.gba` file suitable for real hardware. Ensure `agb-gbafix` is installed via `cargo install agb-gbafix`. ```sh agb-gbafix target/thumbv4t-none-eabi/release/ -o .gba ``` -------------------------------- ### Run the agb Template Game Source: https://github.com/agbrs/agb/blob/master/book/src/setup/building.md Build and run the agb template in a single step using Cargo. Requires mgba-qt to be installed. ```sh cargo run --release ``` -------------------------------- ### Initialize Ball Instance Source: https://github.com/agbrs/agb/blob/master/book/src/pong/07_fixnums.md Creates a new Ball instance with initial position and velocity. Use this to set up the ball at the start of the game. ```rust let mut ball = Ball::new(vec2(50, 50), vec2(1, 1)); ``` -------------------------------- ### Define Levels Array in build.rs Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/08_multiple_levels.md Example of how to define the array of level files to be loaded by the game. This configuration is typically done in the `build.rs` file. ```rust static LEVELS: &[&str] = &["level_01.tmx", "level_02.tmx"]; ``` -------------------------------- ### Basic ObjectTextRenderer Setup Source: https://github.com/agbrs/agb/blob/master/book/src/articles/text_rendering.md Initialize `ObjectTextRenderer` with a palette and sprite size. The sprite size must be at least as large as the maximum group width defined in `LayoutSettings`. ```rust let text_layout = Layout::new( "Hello, this is some text that I want to display!", &FONT, &LayoutSettings::new() .with_alignment(AlignmentKind::Left) .with_max_group_width(16) // minimum group size is 16, so the sprite size I use should be at least 16 wide .with_max_line_length(200), ); // using an appropriate sprite size, palette should come from somewhere let text_render = ObjectTextRenderer::new(PALETTE.into(), Size::S16x16); let objects: Vec<_> = text_layout.map(|x| text_render.show(&x, vec2(16, 16))).collect(); // then show the objects in the usual way ``` -------------------------------- ### Verify Project Build Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/01_getting_started.md Build the project in release mode to ensure the toolchain is correctly set up and the template compiles successfully. ```sh cargo build --release ``` -------------------------------- ### Build the agb Template Project Source: https://github.com/agbrs/agb/blob/master/book/src/setup/building.md Navigate to the template directory and compile the project in release mode. The output binary will be in the target directory. ```sh cd template cargo build --release ``` -------------------------------- ### Import Background Graphics with `include_background_gfx!` Source: https://github.com/agbrs/agb/blob/master/book/src/pong/06_background.md Use this macro to import background assets from aseprite files. It automatically generates palettes and can deduplicate tiles to save space. Specify the module name and map static variable names to your asset files. ```rust use agb::include_background_gfx; include_background_gfx!( mod background, PLAY_FIELD => deduplicate "gfx/background.aseprite", ); ``` -------------------------------- ### Get D-Pad Directional Input Source: https://github.com/agbrs/agb/blob/master/book/src/articles/input.md Utilize `y_tri()` to get the vertical direction of the D-Pad as a `Tri` enum, which can be converted to an integer for movement. Handles simultaneous presses gracefully. ```rust paddle.move_by(button_controller.y_tri() as i32); ``` -------------------------------- ### Initialize Tracker Source: https://github.com/agbrs/agb/blob/master/book/src/pong/08_bgm.md Create a new Tracker instance, passing the imported BGM Track data. This prepares the tracker for playback. ```rust use agb_tracker::Tracker; let mut tracker = Tracker::new(&BGM); ``` -------------------------------- ### Initialize Tracker Instance Source: https://github.com/agbrs/agb/blob/master/book/src/articles/music_and_sfx.md Create a `Tracker` instance for playing a specific tracker music track. The `BGM` static variable should be defined using `include_xm!`. ```rust use agb_tracker::Tracker; let mut bgm_tracker = Tracker::new(&BGM); ``` -------------------------------- ### Run Unit Tests with mgba-test-runner Source: https://github.com/agbrs/agb/blob/master/book/src/articles/unit_tests.md Execute unit tests using the installed test runner by setting the CARGO_TARGET_THUMBV4T_NONE_EABI_RUNNER environment variable. ```sh CARGO_TARGET_THUMBV4T_NONE_EABI_RUNNER=mgba-test-runner cargo test ``` -------------------------------- ### Paddle Collision Rectangle Source: https://github.com/agbrs/agb/blob/master/book/src/pong/05_paddle_collision.md Implement a method to get the collision rectangle for a paddle. Requires importing Rect and rect from agb::fixnum. ```rust pub fn collision_rect(&self) -> Rect { rect(self.pos, vec2(16, 16 * 3)) } ``` ```rust use agb::fixnum::{Rect, Vector2D, rect, vec2}; ``` -------------------------------- ### Import Tile Set with agb Source: https://github.com/agbrs/agb/blob/master/book/src/articles/backgrounds.md Use the `include_background_gfx!` macro to import image files (aseprite, png, bmp) as tile sets. The `deduplicate` option merges identical tiles to save space. ```rust use agb::include_background_gfx; include_background_gfx!( mod background, BEACH => deduplicate "gfx/beach-background.aseprite" ); ``` -------------------------------- ### Update Button State Source: https://github.com/agbrs/agb/blob/master/book/src/pong/04_paddle_movement.md Call `update()` at the start of each game loop to refresh the state of all buttons. This ensures you are working with the latest input. ```rust button_controller.update(); ``` -------------------------------- ### Show Background on Screen Source: https://github.com/agbrs/agb/blob/master/book/src/articles/backgrounds.md Displays the prepared background on the screen by calling the `show` method within the main graphics frame loop. Ensure this is done before committing the frame. ```rust let mut gfx = gba.graphics.get(); loop { let mut frame = gfx.frame(); background.show(&mut frame); frame.commit(); } ``` -------------------------------- ### Clone AGB Template Project Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/01_getting_started.md Clone the AGB template repository to start a new platformer project. Navigate into the cloned directory. ```sh git clone https://github.com/agbrs/template.git platform cd platform ``` -------------------------------- ### Getting 2D Movement Vector Source: https://github.com/agbrs/agb/blob/master/book/src/articles/input.md Describes the `vector()` method for obtaining a 2D movement vector based on directional input, and its `just_pressed_vector()` variant. ```APIDOC ## `vector()` The `vector()` method is a combination of the `x_tri()` and `y_tri()` methods. It returns a vector with an `x` and `y` component of `-1`, `0` or `1` depending on whether that direction is pressed. This can be used to move a player around in a 2d-plane, or you can use the `just_pressed_vector()` to allow navigation of a 2d menu. ``` -------------------------------- ### Initializing and Updating ButtonController Source: https://github.com/agbrs/agb/blob/master/book/src/articles/input.md Demonstrates how to create a new `ButtonController` and update its state each frame to track button presses. ```APIDOC ## Initializing and Updating ButtonController To track the currently pressed buttons, you need a [`ButtonController`](https://docs.rs/agb/latest/agb/input/struct.ButtonController.html). Create one with the `ButtonController::new()` method, and then each frame use the `update()` method to update its current state. ```rust use agb::input::ButtonController; let mut button_controller = ButtonController::new(); loop { button_controller.update(); // Do your game logic using the button_controller let mut frame = gfx.frame(); // ... frame.commit(); } ``` In theory you could have multiple `ButtonController` instances across your game, but most will create one and pass it through as needed. ``` -------------------------------- ### Create and Fill a Regular Background Source: https://github.com/agbrs/agb/blob/master/book/src/pong/06_background.md Instantiate a `RegularBackground` specifying its priority, size, and tile format (e.g., `TileFormat::FourBpp` for 16-colour mode). Then, fill it with the imported background data using `fill_with()`. ```rust use agb::display::{ Priority, tiled::{RegularBackground, RegularBackgroundSize, TileFormat}, }; let mut bg = RegularBackground::new( Priority::P3, RegularBackgroundSize::Background32x32, TileFormat::FourBpp ); bg.fill_with(&background::PLAY_FIELD); ``` -------------------------------- ### Create and play a sound channel Source: https://github.com/agbrs/agb/blob/master/book/src/articles/music_and_sfx.md Instantiate a `SoundChannel` with `SoundData` and optionally configure stereo playback. Then, use `mixer.play_sound()` to play the sound. This returns a `ChannelId` if successful, allowing for later control of the sound. ```rust let mut background_music = SoundChannel::new(BACKGROUND_MUSIC); background_music.stereo(); mixer.play_sound(background_music); ``` -------------------------------- ### Initialize the agb sound mixer Source: https://github.com/agbrs/agb/blob/master/book/src/articles/music_and_sfx.md Create a sound mixer instance by calling the `.mixer()` method on the `gba.mixer` object, specifying the desired audio frequency. The chosen frequency cannot be changed during gameplay without dropping and recreating the mixer. ```rust use agb::sound::mixer::Frequency; let mut mixer = gba.mixer.mixer(Frequency::Hz18157); ``` -------------------------------- ### Define Doctest Function Source: https://github.com/agbrs/agb/blob/master/book/src/articles/unit_tests.md Mark a function with `#[agb::doctest]` to create a documentation test. The example code within the doc comment will be compiled and run. ```rust /// This is a cool rust function with some epic documentation which is checked /// at compile time and the doctest will run when running the tests. /// /// ```rust /// # #![no_std] /// # #![no_main] /// # /// # #[agb::doctest] /// # fn test(gba: agb::Gba) { /// assert_eq!(my_crate::my_cool_function(), 7); /// # } /// ``` fn my_cool_function() -> i32 { return 7; } ``` -------------------------------- ### Main Function to Initialize and Display the World Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/05_displaying_the_level.md The entry point of the application. It initializes the graphics, creates a `World` instance with the first level, and enters a loop to continuously update and display the game frame. ```rust #[agb::entry] fn main(mut gba: agb::Gba) -> ! { let mut gfx = gba.graphics.get(); gfx.set_background_palettes(tiles::PALETTES); let mut bg = World::new(levels::LEVELS[0]); loop { // We pass (0, 0) for now since the camera doesn't move yet. // We'll revisit this when we add a player. bg.set_pos(vec2(0, 0)); let mut frame = gfx.frame(); bg.show(&mut frame); frame.commit(); } } ``` -------------------------------- ### Get Combined D-Pad Vector Input Source: https://github.com/agbrs/agb/blob/master/book/src/articles/input.md The `vector()` method returns a 2D vector representing the D-Pad's direction, useful for 2D movement or menu navigation. ```rust vector() ``` -------------------------------- ### Load WAV sample data with include_wav! Source: https://github.com/agbrs/agb/blob/master/book/src/articles/music_and_sfx.md Load uncompressed WAV audio files into your project using the `include_wav!` macro. This macro returns `SoundData` which can be used with the mixer. Ensure the WAV file's sample rate matches the chosen mixer frequency. ```rust use agb:: include_wav!, sound::mixer::SoundData, static BACKGROUND_MUSIC: SoundData = include_wav!("sfx/audio.wav"); ``` -------------------------------- ### Play AGB Animation Sprite Source: https://github.com/agbrs/agb/blob/master/book/src/articles/objects_deep_dive.md Use the `.animation_sprite()` method to get the correct frame for an animation based on frame count. Divide the frame count to control animation speed. ```rust use agb::display::{GraphicsFrame, object::Object}; agb::include_aseprite!(mod sprites, "gfx/sprites.aseprite"); fn walk(frame: &mut GraphicsFrame, frame_count: usize) { // We divide the frame count by 4 here so that we only update once // every 4 frames rather than every frame. Object::new(sprites::WALKING.animation_sprite(frame_count / 4)) .set_pos((32, 32)) .show(frame); } ``` -------------------------------- ### Import Other Image Formats Source: https://github.com/agbrs/agb/blob/master/book/src/articles/objects_deep_dive.md Import PNG, GIF, and BMP files using `include_aseprite`. The static name is derived from the filename, formatted in all caps with hyphens replaced by underscores. GIF files automatically create multi-frame tags. ```rust agb::include_aseprite!(mod sprites, "my_sprite.png", "other-image.bmp"); ``` -------------------------------- ### Temporary Main Function for Verification Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/03_loading_levels.md This temporary main function can be used to test the `import_level` function. It loads a specified level and prints its dimensions and player start position as build warnings. ```rust fn main() -> Result<(), Box> { let level = import_level("tiled/level_01.tmx")?; println!("cargo::warning=Loaded level: {}x{}", level.size.0, level.size.1); println!("cargo::warning=Player starts at: {:?}", level.player_start); Ok(()) } ``` -------------------------------- ### Move Paddle Based on D-Pad Input Source: https://github.com/agbrs/agb/blob/master/book/src/pong/04_paddle_movement.md Use the `y_tri()` method of the `ButtonController` to get the state of the up/down D-Pad buttons and move the paddle accordingly. Cast the `Tri` enum to `i32` for movement. ```rust paddle_a.move_by(button_controller.y_tri() as i32); ``` -------------------------------- ### Import Level Function Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/03_loading_levels.md This function loads a .tmx map file, extracts tile and object data, and returns a structured Level object. It handles tile properties like collision and win conditions, and finds the player's starting position. ```rust fn import_level(level: &str) -> Result> { let level = tiled::Loader::with_reader(BuildResourceReader).load_tmx_map(level)?; let map = level.get_tile_layer("Level"); let objs = level.get_object_layer("Objects"); let width = map.width(); let height = map.height(); let mut tiles = Vec::new(); for y in 0..height { for x in 0..width { let tile = match map.get_tile(x as i32, y as i32) { Some(tile) => { let properties = &tile.get_tile().unwrap().properties; let colliding = properties["COLLISION"] == PropertyValue::BoolValue(true); let win = properties["WIN"] == PropertyValue::BoolValue(true); TileInfo { colliding, win, id: Some(tile.id()), } } None => TileInfo { colliding: false, win: false, id: None, }, }; tiles.push(tile); } } let player = objs .objects() .find(|x| x.name == "PLAYER") .expect("Should be able to find the player"); let player_x = player.x as i32; let player_y = player.y as i32; Ok(Level { size: (width, height), tiles, player_start: (player_x, player_y), }) } ``` -------------------------------- ### Intermediate Representation for Level Data Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/03_loading_levels.md Defines Rust structs `TileInfo` and `Level` to represent an intermediate format for parsed Tiled map data. `TileInfo` holds tile ID and properties, while `Level` stores dimensions, tile data, and player start position. ```rust #[derive(Debug, Clone, Copy)] struct TileInfo { id: Option, colliding: bool, win: bool, } #[derive(Debug, Clone)] struct Level { size: (u32, u32), tiles: Vec, player_start: (i32, i32), } ``` -------------------------------- ### Define Runtime Level Struct for GBA Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/04_converting_levels.md Defines the `Level` struct optimized for the GBA, using flat arrays and bit-packed maps for memory efficiency. This struct holds level dimensions, background tile data, collision information, winning conditions, and player start position. ```rust struct Level { width: u32, height: u32, background: &'static [TileSetting], collision_map: &'static [u8], winning_map: &'static [u8], player_start: (i32, i32), } ``` -------------------------------- ### Create and Clone SpriteVram Source: https://github.com/agbrs/agb/blob/master/book/src/articles/objects_deep_dive.md Demonstrates creating a `SpriteVram` from a static sprite and cloning it. Cloning `SpriteVram` is cheap and does not allocate more VRAM due to its reference-counted nature. ```rust use agb::display::object::SpriteVram; agb::include_aseprite!(mod sprites, "examples/chicken.aseprite"); let sprite = SpriteVram::from(sprites::IDLE.sprite(0)); let clone = sprite.clone(); ``` -------------------------------- ### Initialize RegularBackground Source: https://github.com/agbrs/agb/blob/master/book/src/articles/backgrounds.md Initializes a `RegularBackground` with a specified priority, size, and tile format. Ensure the tile format is correctly obtained from your imported assets. ```rust use agb:: display::Priority, display::tiled::{ RegularBackground, RegularBackgroundSize, }, include_background_gfx, ; include_background_gfx!( mod background, BEACH => deduplicate "gfx/beach-background.aseprite" ); #[agb::entry] fn main(mut gba: agb::Gba) -> ! { let mut gfx = gba.graphics.get(); gfx.set_background_palettes(background::PALETTES); // Create the background tiles ready for us to display on the screen let mut tiles = RegularBackground::new( Priority::P0, RegularBackgroundSize::Background32x32, background::BEACH.tiles.format() ); loop {} } ``` -------------------------------- ### Typical agb Game Loop Source: https://github.com/agbrs/agb/blob/master/book/src/articles/frame_lifecycle.md Illustrates the standard update-render loop in agb, showing how to obtain a graphics instance, update game state, and render each frame. ```rust let mut gfx = gba.graphics.get(); loop { my_game.update(); let mut frame = gfx.frame(); my_game.show(&mut frame); frame.commit(); } ``` -------------------------------- ### Create Text Layout Source: https://github.com/agbrs/agb/blob/master/book/src/articles/text_rendering.md Initialize a text layout with specified text, font, and settings. This includes alignment and maximum dimensions for text groups and lines. ```rust let text_layout = Layout::new( "Hello, this is some text that I want to display!", &FONT, &LayoutSettings::new() .with_alignment(AlignmentKind::Left) .with_max_group_width(32) .with_max_line_length(200), ); ``` -------------------------------- ### Create and Use Dynamic Tiles Source: https://github.com/agbrs/agb/blob/master/book/src/articles/backgrounds.md Initialize and set dynamic tiles on a background. Ensure the background uses 4 bits per pixel. Dynamic tiles are useful for rendering text or other runtime-determined tile content. ```rust // by default, `DynamicTile`s are left with whatever was in video RAM before it // was allocated. So you'll need to clear it if you're not planning on writing // to the entire tile. let dynamic_tile = DynamicTile16::new().fill_with(0); // my_background here must have FourBpp set as it's TileFormat or you won't be able // to use DynamicTile16 on it. let my_background = RegularBackground::new( Priority::P0, RegularBackgroundSize::Background32x32, TileFormat::FourBpp ); // Note that you can pass a TileEffect here which would allow you to flip the tile // vertically or horizontally if you choose to. my_background.set_tile_dynamic16((0, 5), dynamic_tile, TileEffect::default()); my_background.set_tile_dynamic16((0, 5), dynamic_tile, TileEffect::default().hflip(true)); // flip the tile horizontally ``` -------------------------------- ### Importing Affine Background Graphics Source: https://github.com/agbrs/agb/blob/master/book/src/articles/backgrounds.md Use `include_background_gfx!` to import tiles for affine backgrounds. Ensure you specify `256` for 256-color mode and do not use the `deduplicate` option. ```rust use agb::include_background_gfx; include_background_gfx!( mod background, TILES => 256 "gfx/background-tiles.aseprite", ); ``` -------------------------------- ### Configure debugger launch in launch.json Source: https://github.com/agbrs/agb/blob/master/book/src/articles/vscode_debugger.md Sets up the debugger configuration for VSCode. It specifies the debugger type, GDB server address, pre-launch task, and the program to run. The `linux` specific section includes commands to launch mGBA with the debugger attached. ```json { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "targetArchitecture": "arm", "args": [], "stopAtEntry": false, "environment": [ { "name": "CARGO_TARGET_DIR", "value": "${workspaceFolder}/target", }, ], "externalConsole": false, "MIMode": "gdb", "miDebuggerServerAddress": "localhost:2345", "preLaunchTask": "Rust build: debug", "program": "${workspaceFolder}/target/thumbv4t-none-eabi/debug/agb_template", "cwd": "${workspaceFolder}", "linux": { "miDebuggerPath": "arm-none-eabi-gdb", "setupCommands": [ { "text": "shell \"mgba-qt\" -g \"${workspaceFolder}/target/thumbv4t-none-eabi/debug/agb_template\" &" } ] }, }, ], } ``` -------------------------------- ### Generate Stack Trace with agb-debug Source: https://github.com/agbrs/agb/blob/master/book/src/articles/panics.md Use the `agb-debug` CLI with your ROM's elf file and the panic code to generate a full stack trace. This tool can also display code snippets from your filesystem. ```text $ agb-debug target/thumbv4t-none-eabi/release/the_hat_chooses_the_wizard 3K8CDNW010O2W013KgQFq05i05av1 0: __rustc::rust_begin_unwind /lib.rs:407 let frames = backtrace::unwind_exception(); ^ 1: core::panicking::panic_fmt /panicking.rs:75 2: the_hat_chooses_the_wizard::sfx::SfxPlayer::snail_death /sfx.rs:94 panic!("Unknown sound"); ^ 3: the_hat_chooses_the_wizard::enemies::Snail::update /enemies.rs:350 sfx_player.snail_death(); ^ (inlined into) the_hat_chooses_the_wizard::enemies::Enemy::update /enemies.rs:51 Enemy::Snail(snail) => snail.update(level, player_pos, hat_state, timer, sfx_player), ^ 4: the_hat_chooses_the_wizard::PlayingLevel::update_frame /lib.rs:681 match enemy.update( ^ (inlined into) the_hat_chooses_the_wizard::main /lib.rs:813 match level.update_frame(&mut sfx) { ^ 5: the_hat_chooses_the_wizard::_agb_main_func_2381583852303396514::inner /main.rs:9 the_hat_chooses_the_wizard::main(gba); ^ 6: main /main.rs:7 #[agb::entry] ^ ``` -------------------------------- ### GBA Entry Point Placeholder Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/04_converting_levels.md Provides a basic entry point for the GBA application using the `#[agb::entry]` macro. This ensures the game compiles while a main loop is not yet implemented. ```rust #[agb::entry] fn main(_gba: agb::Gba) -> ! { loop { agb::halt(); } } ``` -------------------------------- ### Import Background GFX in Rust Source: https://github.com/agbrs/agb/blob/master/book/src/platformer/04_converting_levels.md Imports background tiles from a PNG file using `include_background_gfx!`. Specify the transparency color and the name for the resulting tileset. ```rust use agb:: display::tiled::TileSetting, include_background_gfx, }; extern crate alloc; include_background_gfx!(mod tiles, "2ce8f4", TILES => "gfx/tileset.png"); ``` -------------------------------- ### Basic agb Game Entry Point Source: https://github.com/agbrs/agb/blob/master/book/src/pong/01_the_gba_struct.md This is the standard entry point for an agb game. It creates an infinite loop that halts the CPU to save battery life when no operations are pending. ```rust #[agb::entry] fn main() { // infinite loop for now loop { agb::halt(); } } ``` -------------------------------- ### Configure Backgrounds in Window Areas Source: https://github.com/agbrs/agb/blob/master/book/src/articles/blending_and_windows.md Enables background 1 within Win0 and background 2 within WinOut. Pixels inside the 64x64 area will show background 1, while those outside will show background 2. ```rust let bg1_id = background1.show(&mut frame); let bg2_id = background2.show(&mut frame); let mut window = frame.windows(); window .win_in(WinIn::Win0) .enable_background(bg1_id) .set_pos(rect(pos, vec2(64, 64))); window.win_out().enable_background(bg2_id); ``` -------------------------------- ### Create Hardlink for mGBA Qt Source: https://github.com/agbrs/agb/blob/master/book/src/setup/windows.md Creates a hardlink for mgba-qt.exe to mgba-qt.exe, useful for aliasing the executable. ```powershell New-Item -itemtype hardlink -path "C:\Program Files\mGBA\mgba-qt.exe" -value "C:\Program Files\mGBA\mGBA.exe" ``` -------------------------------- ### Build Project with Cargo Source: https://github.com/agbrs/agb/blob/master/examples/amplitude/README.md Use `cargo build` to compile your project. For an optimized release build, use `cargo build --release`. ```sh cargo build ``` ```sh cargo build --release ``` -------------------------------- ### Show Background on Screen Source: https://github.com/agbrs/agb/blob/master/book/src/pong/06_background.md Make the background visible by calling `bg.show()` just before committing the frame. This integrates the background into the current frame buffer. ```rust bg.show(&mut frame); frame.commit(); ``` -------------------------------- ### Initialize Flash Save System with Timer Source: https://github.com/agbrs/agb/blob/master/book/src/articles/saving.md Initializes the save system using 128K Flash memory, requiring a timer for timeout handling. This is useful for larger save data or when dealing with slower storage media. ```rust let timers = gba.timers.timers(); let mut save_manager: SaveSlotManager = gba .save .init_flash_128k(3, SAVE_MAGIC, Some(timers.timer2)) .expect("Failed to initialize save"); ``` -------------------------------- ### Display Sprite as an Object Source: https://github.com/agbrs/agb/blob/master/book/src/articles/objects_deep_dive.md Shows how to create and display an `Object` on the screen. `Object::new` accepts anything that implements `Into`, allowing direct use of static sprites. The object's position and horizontal flip can be configured before showing it on the frame. ```rust use agb::display::{GraphicsFrame, object::Object}; agb::include_aseprite!(mod sprites, "examples/chicken.aseprite"); fn chicken(frame: &mut GraphicsFrame) { // Object::new takes anything that implements Into, so we can pass in a static sprite. Object::new(sprites::IDLE.sprite(0)) .set_pos((32, 32)) .set_hflip(true) .show(frame); } ``` -------------------------------- ### Import 15-Color Sprites with include_aseprite Source: https://github.com/agbrs/agb/blob/master/book/src/articles/objects_deep_dive.md Use the `include_aseprite` macro to import 15-color sprites from Aseprite files. Palettes are optimized together. This creates a module with static tags for animations. ```rust agb::include_aseprite!(mod sprites, "sprites.aseprite", "other_sprites.aseprite"); ``` -------------------------------- ### Initialize ButtonController Source: https://github.com/agbrs/agb/blob/master/book/src/pong/04_paddle_movement.md Instantiate a `ButtonController` to manage GBA button inputs. This controller is not part of the `Gba` struct as it's read-only. ```rust let mut button_controller = agb::input::ButtonController::new(); ``` -------------------------------- ### Import 255-Color Sprites with include_aseprite_256 Source: https://github.com/agbrs/agb/blob/master/book/src/articles/objects_deep_dive.md Import 255-color sprites using `include_aseprite_256`. This macro has the same syntax as `include_aseprite` but uses more memory and ROM space. Prefer 15-color sprites when possible. ```rust agb::include_aseprite_256!(mod sprites_256, "sprites_256.aseprite"); ``` -------------------------------- ### Import 256-Color Background Graphics Source: https://github.com/agbrs/agb/blob/master/book/src/articles/backgrounds.md Use the `256` modifier with `include_background_gfx!` to import graphics that use 8 bits per pixel. Ensure the `RegularBackground` is created with `TileFormat::EightBpp`. ```rust use agb::include_background_gfx; include_background_gfx!( mod background, BEACH => 256 deduplicate "gfx/beach-background.aseprite" ); ``` -------------------------------- ### Add agb_tracker Crate Source: https://github.com/agbrs/agb/blob/master/book/src/articles/music_and_sfx.md Include the `agb_tracker` crate in your project to enable support for tracker music files. ```bash cargo add agb_tracker ```