67 lines
3.1 KiB
Rust
67 lines
3.1 KiB
Rust
//! The macro palette: scene-appropriate actions, and the executor that runs them.
|
|
//!
|
|
//! `docs/design/macros.md` is the binding contract. This module is agent B's
|
|
//! (`Palette::for_scene`, A* pathing, the macro scripts, `MacroExecutor`); [`state`] is the seam
|
|
//! it is written against and belongs to agent A, who implements it in
|
|
//! [`crate::pokemon_red::state`].
|
|
//!
|
|
//! In one paragraph: the population decoder and its six channels do not change, and palette mode
|
|
//! gives those same channels a *scene-dependent meaning* in the game layer. UP is slot 0, DOWN
|
|
//! slot 1, LEFT slot 2, RIGHT slot 3, A slot 4, B slot 5; [`Palette::for_scene`] says what each
|
|
//! slot means in the current scene and leaves a slot unbound when its precondition fails;
|
|
//! [`MacroMachine`] runs the chosen slot's script with the same button register the fly's raw
|
|
//! presses use, for at most six hundred frames, giving the buttons back the moment the scene
|
|
//! changes.
|
|
//!
|
|
//! What is *not* here is as much the point as what is:
|
|
//!
|
|
//! - **No choosing.** Nothing in this module picks a macro. `start` is handed a slot, and the
|
|
//! slot comes from the readout. There is no default, no fallback on timeout and no objective
|
|
//! (`docs/design/macros.md` section 1).
|
|
//! - **No addresses.** Every read goes through [`state::GameState`] and [`cartridge::MacroState`].
|
|
//! The executor cannot drift from the decomp because it never names an offset.
|
|
//! - **No new button path.** A macro presses the emulator's button register, the same one the
|
|
//! decoder's raw masks go to. There is still no button endpoint on the control API.
|
|
//!
|
|
//! ## Wiring it (agent C)
|
|
//!
|
|
//! [`cartridge::MacroState`] is one extension of agent A's trait for the four things section 3
|
|
//! names and the seam does not carry, and every method is defaulted, so agent A's reader needs
|
|
//! one line:
|
|
//!
|
|
//! ```ignore
|
|
//! impl MacroState for PokeState<'_> {}
|
|
//! ```
|
|
//!
|
|
//! That compiles today, and it is checked: a trial merge of `feat/macros-executor` and
|
|
//! `feat/macros-scene` builds and passes both halves' tests, conflicting only in the two module
|
|
//! lists. Overriding a default is what turns `BUY POTION` on, gives `ATTACK` the real move table
|
|
//! and type chart, and points the three ways out at the adapter's exploration ledger; until then the
|
|
//! palette offers less rather than guessing.
|
|
//!
|
|
//! ```text
|
|
//! decoder channels --> MacroId --> Palette::for_scene --> MacroMachine::start
|
|
//! |
|
|
//! per frame: MacroMachine::step --> button mask --> emulator
|
|
//! ```
|
|
|
|
pub mod cartridge;
|
|
pub mod driver;
|
|
pub mod executor;
|
|
pub mod geography;
|
|
pub mod palette;
|
|
pub mod path;
|
|
pub mod plan;
|
|
pub mod state;
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
pub use cartridge::{Edge, ExitId, Listing, MacroState, Tile};
|
|
pub use driver::PokemonPalette;
|
|
pub use executor::{
|
|
Executor, FRAME_CAP, MAX_FAILED_STEPS, MacroAbort, MacroExecutor, MacroMachine, MacroRefused,
|
|
Refusal, StateSource,
|
|
};
|
|
pub use palette::{MacroId, MacroKind, MacroSpec, Palette, SLOTS};
|
|
pub use path::{Exit, Route, exits, route};
|