⛰️ 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_framereturnsResult<Clocked>rather thanResult<()>and clocks at most one NES frame per call; drive it withwhile 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:fsandControlDecksave/load now takeRead/Write, the path-taking forms are*_path,fs::load_bytesis gone since&[u8]is already a reader, andConfig::data_diris replaced byConfig::sram_dir: Option<PathBuf>. - (core) [breaking] Flatten ownership so Bus holds the console - (c34e8b8)
BREAKING:ControlDeck::cpu()returns registers only; the console isControlDeck::bus(), and save states, rewind and replay are nowBusrather thanCpu.ControlDeck::load_cpuisload_bus.MapperandMemorymoved fromPputoBus, as did the debugger.PpuDebuggerisDebuggerand its callback takes&Bus.Ppu::load_nametables/load_pattern_tables/load_oamtake the CHR window to read from. Thememory::Readandmemory::Writetraits 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::Frameno longer derefs toVec<u8>. Callers using it as aVecshould useas_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::syncisMap::update_banks,Ppu::sync_mapperisPpu::rebuild_mapper_state, and MMC5's collidingupdate_chr_banksisselect_chr_set. Frame buffers are fixed-size:Ppu::frame_bufferandControlDeck::frame_buffer_rawreturn&[u16; ppu::size::FRAME],ControlDeck::frame_bufferreturns&[u8; Frame::SIZE], andframe_buffer_intotakes&mut [u8; Frame::SIZE].ControlDeck::apu_mutreturns&mut Apu,joypadtakes&self, andwramreturns&[u8; bus::size::WRAM]. Clocking clears the previous call's audio samples instead of accumulating; opt out withConfig::clear_audio_on_clock = false. The five olderclock_*entry points are deprecated shims rather than removals. - (core) [breaking] Delete the convention-only traits from common.rs - (61cedf4)
BREAKING: theClock,Reset,Regional,SampleandSramtraits are gone, and the prelude drops them.clock,reset,region,set_region,output,saveandloadare inherent methods on each component and forward exactly as before, so a call likedeck.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::CIRamand thememmodule are gone.mem::Memory<D>is nowmemory::Buffer<D>, andmemory::Memoryis the page-table address space. TheCart::prg_romandCart::chr_romfields become theCart::memoryarena, withprg_rom()andchr_rom()accessors returning the unpadded bytes.Ppu::ciramis gone - nametables are page entries.Map's read hooks lose their_hooksuffix: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::Maskandppu::status::Statusare gone; read thectrl_*,mask_*andstatus_*fields onPpuinstead. - (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::loadandControlDeck::load_cpuare fallible, returningcpu::StateMismatchwhen the state does not belong to the loaded cart. - (rewind) Re-render rewound frames instead of storing them - (1ba7f48)