github lukexor/tetanes tetanes-v0.15.0
TetaNES v0.15.0

3 hours ago

⛰️ Features

  • (mapper) Add Taito TC0190/TC0350 and TC0690 (Mappers 33, 48) - (b127fe6)
  • (mapper) Serve tier 3a bank-switchers from page tables - (9b63b40)

🐛 Bug Fixes

  • (audio) Ramp the output in and out instead of cutting - (5d25e83)

  • (audio) Pace on a deadline and hold the buffer with rate control - (8d27d27)

  • (audio) Prime the output stream before it starts consuming - (e67a133)

  • (core) [breaking] Hand out one nes frame per clock_frame call - (7cca0af)
    BREAKING: ControlDeck::clock_frame returns Result<Clocked> rather than Result<()> and clocks at most one NES frame per call; drive it with while deck.clock_frame()? == Clocked::Continue {} to clock a whole display frame as before.

  • (input) Add enter/shift defaults for start/select - (68776d2)

  • (input) Stop bindings colliding and buttons sticking - (d2a6bf7)

  • (input) Fixed shortcuts to be on press instead of on release - (099462f)

  • (input) Fixed modifier rolling and stuck joypad keys - (568023c)

  • (libretro) Six defects found in review, and the claims that hid them - (28b97dd)

  • (ppu-viewer) Fixed oam tab zoom - (f150119)

  • (preferences) Fixed game-genie entry closing when focused in menu - (2e4b9d6)

  • (renderer) Sync wgpu surface to window size so menu clicks land - (a39fede)

  • (rewind) Render every rewound frame below 1x - (ae4d19b)

  • Drop Game Genie codes when the cart is swapped - (3ae10ff)

🚜 Refactor

  • (core) [breaking] Take readers and writers, not paths - (04bc7ae)
    BREAKING: fs and ControlDeck save/load now take Read/Write, the path-taking forms are *_path, fs::load_bytes is gone since &[u8] is already a reader, and Config::data_dir is replaced by Config::sram_dir: Option<PathBuf>.
  • (core) [breaking] Flatten ownership so Bus holds the console - (c34e8b8)
    BREAKING: ControlDeck::cpu() returns registers only; the console is ControlDeck::bus(), and save states, rewind and replay are now Bus rather than Cpu. ControlDeck::load_cpu is load_bus. Mapper and Memory moved from Ppu to Bus, as did the debugger. PpuDebugger is Debugger and its callback takes &Bus. Ppu::load_nametables/load_pattern_tables/load_oam take the CHR window to read from. The memory::Read and memory::Write traits are removed in favor of inherent methods. Save states from earlier builds will not load.
  • (core) [breaking] Make video::Frame a fixed-size buffer - (b79a2fe)
    BREAKING: video::Frame no longer derefs to Vec<u8>. Callers using it as a Vec should use as_slice, as_array, or indexing; callers that resized it have no replacement, as the size is now part of the type.
  • (core) [breaking] Collapse the clocking API and clean up public surface - (2b4fd1e)
    BREAKING: MSRV is now 1.88; 1.85 could not build the crate at all. Map::sync is Map::update_banks, Ppu::sync_mapper is Ppu::rebuild_mapper_state, and MMC5's colliding update_chr_banks is select_chr_set. Frame buffers are fixed-size: Ppu::frame_buffer and ControlDeck::frame_buffer_raw return &[u16; ppu::size::FRAME], ControlDeck::frame_buffer returns &[u8; Frame::SIZE], and frame_buffer_into takes &mut [u8; Frame::SIZE]. ControlDeck::apu_mut returns &mut Apu, joypad takes &self, and wram returns &[u8; bus::size::WRAM]. Clocking clears the previous call's audio samples instead of accumulating; opt out with Config::clear_audio_on_clock = false. The five older clock_* entry points are deprecated shims rather than removals.
  • (core) [breaking] Delete the convention-only traits from common.rs - (61cedf4)
    BREAKING: the Clock, Reset, Regional, Sample and Sram traits are gone, and the prelude drops them. clock, reset, region, set_region, output, save and load are inherent methods on each component and forward exactly as before, so a call like deck.cpu_mut().clock() is unchanged - only the trait import goes away.
  • (core) [breaking] Delete the pre-page-table memory path - (9ca8ae6)
    BREAKING: mapper::Banks, mapper::BankAccess, ppu::CIRam and the mem module are gone. mem::Memory<D> is now memory::Buffer<D>, and memory::Memory is the page-table address space. The Cart::prg_rom and Cart::chr_rom fields become the Cart::memory arena, with prg_rom() and chr_rom() accessors returning the unpadded bytes. Ppu::ciram is gone - nametables are page entries. Map's read hooks lose their _hook suffix: prg_read, prg_peek, chr_read, chr_peek.
  • (ppu) [breaking] Hold the PPU registers as fields, not structs - (145a954)
    BREAKING: ppu::ctrl::Ctrl, ppu::mask::Mask and ppu::status::Status are gone; read the ctrl_*, mask_* and status_* fields on Ppu instead.
  • (ui) Follow the debugger accessors, and stop building one to discard it - (2606f3e)

📚 Documentation

  • (core) Describe the code as it stands, not its history - (5a5b65b)

  • Correct the supported-mapper table's counts, VRC4f and percentages - (ebcc66c)

  • Correct stale facts in CLAUDE.md, the mapper docs and the README table - (b702137)

  • Fix stale references and drop history from the branch's comments - (97a2850)

⚡ Performance

  • (core) [breaking] Keep the cart's ROM out of save states - (12156e5)
    BREAKING: save states and rewind snapshots no longer carry the cart's ROM, so a state can only be applied to the game it came from. Cpu::load and ControlDeck::load_cpu are fallible, returning cpu::StateMismatch when the state does not belong to the loaded cart.
  • (rewind) Re-render rewound frames instead of storing them - (1ba7f48)

⚙️ Miscellaneous Tasks

  • Clear the must_use, const fn and rustdoc warnings - (5ef3404)
  • Fixed cd - (0022029)

Don't miss a new tetanes release

NewReleases is sending notifications on new releases.