Compare commits

...
61 Commits
Author SHA1 Message Date
Near 4428bb70e9 Update to ares v121 release.
I've released ares v121. Because it is not fully complete or stable, it is
released as source code only.

The license is now once again ISC instead of CC-BY-NC-ND.

Master System, WonderSwan, and WonderSwan Color compatibility have increased to
100%, with no remaining known bugs.

The Neo Geo Pocket is very close to 100% now with one issue remaining, where
sound effects sometimes mute in games.

Nintendo 64 compatibility has increased to above 80% thanks to corrections to
controller pak handling.

Several NES and Mega CD fixes have been added. EEPROM support has been added for
the Mega Drive.

Memory cards and paks now pre-format themselves, so you don't have to do so in-
game or in BIOS settings.

The new Neo Geo emulation is slowly improving, but it's still very preliminary
with only seven games fully playable so far.

The Nintendo 64 SM5K and PlayStation HC05 processor cores have been emulated,
but not connected yet due to a lack of information.

Added mouse input support and connected peripheral selection to the GUI, so mice
and light gun games can now be used.

There is now per-system input mapping overlays, so you can map controllers based
on the original system button names.

And lastly as promised, the SNES core has gained optional widescreen support.

Changelog (since v120):

  - Nintendo 64: added Windows ABI support to dynamic recompilers
  - PlayStation: added Windows ABI support to dynamic recompiler
  - Nintendo 64: temporarily disabled 64-bit addressing mode due to issues
  - Nintendo 64: corrected analog stick ranges and emulated octagonal
    boundaries
  - Nintendo 64: code cleanups around memory access functions
  - Nintendo 64: started to implement RDRAM broadcasting (very incomplete
    still)
  - Mega Drive: improved VDP scanline renderer timing
  - M68K: corrected clipping bug in ADD,CMP,SUB instructions
  - Nintendo 64: improved SI scanning of PIF RAM and emulated more flags
  - Nintendo 64: added very accurate controller pak initialization code
  - Nintendo 64: improved controller analog stick approximations [MerryMage]
  - Nintendo 64: added priority queue to delay SI and PI DMA transfers
  - Master System: added bit-perfect YM2413 instrument patch sets
  - Mega Drive: fixed a bug with LINEA and LINEF instructions (should not
    decrement PC)
  - Mega Drive: added EEPROM emulation
  - mia: added Mega Drive and Mega 32X EEPROM database entries
  - nall: added priority_queue::remove(T) support
  - Nintendo 64: reverted 64-bit TLB (not actually present)
  - Neo Geo: initial implementation
  - Neo Geo: many emulation improvements
  - nall: add workaround for compilers that lack __has_builtin
  - Nintendo 64: ignore A15 on controller pak reads and writes
  - Master System: implemented Codemasters, Korea, MSX, Janggun mappers
  - Master System: improved Sega mapper emulation
  - Master System: added initial emulation of port $3e
  - Master System: added support to load BIOSes
  - Master System: initialize stack pointer to 0xfffd when no BIOS loaded
    [Luke Usher]
  - Game Boy Advance: emulated BIOS swap register [MerryMage]
  - Mega Drive: cancel pending IRQs when they are disabled [Jonas Quinn]
  - Mega Drive: fixed handling of VDP field flag [Jonas Quinn]
  - Mega Drive: mask upper bit of VDP sprite Y value when in progressive
    display mode [Jonas Quinn]
  - X24C01, M24Cxx: improve emulation of EEPROM command sequences
  - Famicom: added database entries for Jajamaru Gekimaden and Mazase Top
    Pro PRG-RAM
  - M24Cx: rewrote emulation to be more complete; though still not working
    for Cxx/Cxxx sizes
  - Nintendo 64: try stopping SI polling on recv=0xfe
  - Mega Drive: improved EEPROM emulation
  - Nintendo 64: fixed CPU SCC counter rate [simer]
  - Nintendo 64: added initial emulation of the SM5K processor (not connected
    yet)
  - lucia: update frame rate from the main thread to prevent a race condition
    with GTK
  - Master System: emulated sprite zoom and fifth-sprite status flag
  - Master System: corrected VDP background emulation for mode 4 [fixes
    Codemasters games]
  - Master System: latch VDP background nametable address and scroll registers
    [fixes Desert Speedtrap]
  - Master System: mask CRAM reads to 6-bit in Master System mode [fixes Mercs]
  - Master System: refactored VDP code
  - Z80: swapped IND/INI to post-decrement B, and OUTD/OUTI to pre-decrement B
  - lucia: fixed a crash when loading Game Gear games due to stubbing out
    the BIOS
  - Nintendo 64: fixed cartridge flash memory support
  - Master System: VDP line coincidence should be initialized to $ff [fixes
    Shadow Dancer]
  - Master System: VDP sprite overflow index defaults to $1f, not $00 [fixes
    PGA Tour Golf]
  - SN76489: corrected port latching behavior and noise volume writes [fixes
    Micro Machines]
  - TMS9918: greatly refactored code
  - V9938: greatly refactored code
  - Z80: disassembler fixes
  - lucia: corrected mapping of Master System pause button [fixes Baku
    Baku Panic]
  - nall: disable -Wstringop-overflow for GCC due to compiler heuristics error
  - M68HC05: initial core implementation added
  - M68000: renamed core from M68K
  - Super Famicom: clearing $4200.d0 stops active joypad polling for the rest
    of the frame [Jonas Quinn]
  - Master System: don't evaluate sprites past active display area [fixes
    Rescue Mission]
  - Mega Drive: don't acknowledge VDP IRQs until the CPU triggers them [fixes
    Mega Lo Mania]
  - lucia: begin refactoring input mapping to allow per-system mappings and
    multiple controller types
  - Game Gear: set CPU::in() unmapped return value to MDR; fixes RoboCop 3
    [Jonas Quinn]
  - WonderSwan Color: do not mask screen tilemap base address; fixes Sorobang
    [FPGAzumSpass]
  - Mega Drive: set supervisor mode and clear trace mode for all exceptions;
    fixes Gouketsuji Ichizoku [Jonas Quinn]
  - Mega CD: format BRAM instead of leaving it uninitialized; fixes Popful Mail
    (US)
  - WonderSwan: add patch for Meitantei Conan: Nishi no Meitantei Saidai
    no Kiki!
  - Game Boy: add MBC1#M mapper database entries; fixes Bomber Man Collection,
    Genjin Collection, Momotarou Collection, and Mortal Kombat I & II
  - Neo Geo Pocket: $8118 background register exists even in the K1GE GPU;
    fixes Samurai Shodown
  - Neo Geo Pocket Color: return 0xFF acknowledge byte after flash erase
    command; fixes Puzzle Link 2 and Memories off: Pure
  - Neo Geo Pocket: clear watchdog timer counter on trigger to prevent
    infinite triggering; fixes Neo Baccarat, Neo Cherry Master Color, and
    Neo Mystery Bonus
  - TLCS900H: do not allow interrupts to run between CPDR, LDIR, LDDR
    instructions; fixes Fantastic Night Dreams Cotton
  - Neo Geo Pocket: add all remaining missing I/O registers (not emulated,
    but registers are readable and writable now)
  - Neo Geo Pocket Color: above changes also fixed in-game audio in Crush
    Roller and Dynamite Slugger
  - Mega CD: added 1M mode WRAM swap request flag; fxies AX-101, Earnest Evans,
    and Might & Magic III [TascoDLX]
  - lucia: added input mapping overlays for all remaining systems
  - lucia: added two-player support to all remaining systems
  - TLCS900H: refactored instruction decoder and disassembler using range-case
  - TLCS900H: improved emulation of (PC+d16) addressing mode (LDAR)
  - TMS9918, V9938, SMS VDP: corrected sprite zoom emulation [Jonas Quinn]
  - Neo Geo Pocket: added new debugging modules (flash ROM, I/O accesses,
    system calls)
  - Neo Geo Pocket: improved CPU interrupt logger (prints name of interrupt
    now)
  - Neo Geo Pocket: fixed a critical issue with interrupt priority levels;
    fixes many games
  - Neo Geo Pocket: added stubs for all remaining TMP95C061F I/O registers
    (not emulated yet)
  - Neo Geo Pocket: set CPU I/O port $b1.d2 reads to return 1 (fixes SNK
    Gals' Fighter)
  - Neo Geo Pocket: added stubs for undocumented CPU I/O ports $b6 and $b7
  - Super Famicom: PPU code restructuring
  - Super Famicom: added widescreen (16:9 and 21:9) support to the scanline
    renderer
  - WonderSwan: refactored I/O handlers to use switch/case instead of if tests
  - WonderSwan: rewrote PPU renderer to modularize each component (screen1,
    screen2, sprite, dac, etc)
  - WonderSwan: corrected timers to count down instead of up; fixes timing
    in many games [FPGAzumSpass]
  - WonderSwan: improved screen two window emulation [FPGAzumSpass]
  - hiro: TableView::onContext() is now TableView::onContext(TableViewCell)
    (not supported for Cocoa or Qt yet)
  - lucia: merged code to handle input assignment overlays and controller
    polling for each emulation core
  - lucia: added virtual mouse emulation and added mouse capture support
  - lucia: added support to change devices connected to controller ports
  - Neo Geo Pocket: added database workaround for underdumped Prize Game:
    PP-AA01 Pusher Program (Japan)
  - Neo Geo Pocket: fixed fast boot mode for Neo Cherry Pocket
  - nall/range: added new within() templates
  - V30MZ: emulated instruction prefetch
  - V30MZ: greatly improved instruction timings (thanks to FPGAzumSpass'
    test ROM)
  - WonderSwan: disabling an interrupt source does clear its pending status
    (fixes Digimon Tamers)
  - TLCS900H: improved prefetch handling and instruction timing (still
    imperfect)
  - TLCS900H: improved timing further (still imperfect)
2021-06-26 23:49:00 +00:00
Near 4e82321182 Update to ares v120r18 release.
Just slight 'improvements' to TLCS900/H timing.
2021-06-23 14:58:00 +00:00
Near b2fc626854 Update to ares v120r17 release.
- WonderSwan: disabling an interrupt source does clear its pending status
    (fixes Digimon Tamers)
  - TLCS900H: improved prefetch handling and instruction timing (still
    imperfect)
2021-06-20 21:35:00 +00:00
Near 189147fc31 Update to ares v120r16 release.
This gets a 100% pass on FPGAzumSpass' WonderSwan instruction timing tests, and
emulates CPU prefetch as well, but it seems to make games less stable rather
than more =(
2021-06-16 08:01:00 +00:00
Near 532aafe074 Update to ares v120r15 release.
- TLCS900H: refactored instruction decoder and disassembler using range-case
  - TLCS900H: improved emulation of (PC+d16) addressing mode (LDAR)
  - TMS9918, V9938, SMS VDP: corrected sprite zoom emulation [Jonas Quinn]
  - Neo Geo Pocket: added new debugging modules (flash ROM, I/O accesses,
    system calls)
  - Neo Geo Pocket: improved CPU interrupt logger (prints name of interrupt
    now)
  - Neo Geo Pocket: fixed a critical issue with interrupt priority levels;
    fixes many games
  - Neo Geo Pocket: added stubs for all remaining TMP95C061F I/O registers
    (not emulated yet)
  - Neo Geo Pocket: set CPU I/O port $b1.d2 reads to return 1 (fixes SNK
    Gals' Fighter)
  - Neo Geo Pocket: added stubs for undocumented CPU I/O ports $b6 and $b7
  - Super Famicom: PPU code restructuring
  - Super Famicom: added widescreen (16:9 and 21:9) support to the scanline
    renderer
  - WonderSwan: refactored I/O handlers to use switch/case instead of if tests
  - WonderSwan: rewrote PPU renderer to modularize each component (screen1,
    screen2, sprite, dac, etc)
  - WonderSwan: corrected timers to count down instead of up; fixes timing
    in many games [FPGAzumSpass]
  - WonderSwan: improved screen two window emulation [FPGAzumSpass]
  - hiro: TableView::onContext() is now TableView::onContext(TableViewCell)
    (not supported for Cocoa or Qt yet)
  - lucia: merged code to handle input assignment overlays and controller
    polling for each emulation core
  - lucia: added virtual mouse emulation and added mouse capture support
  - lucia: added support to change devices connected to controller ports
  - Neo Geo Pocket: added database workaround for underdumped Prize Game:
    PP-AA01 Pusher Program (Japan)
  - Neo Geo Pocket: fixed fast boot mode for Neo Cherry Pocket
  - nall/range: added new within() templates
2021-06-14 08:07:00 +00:00
Near eefd470752 Update to ares v120r14 release.
- Game Gear: set CPU::in() unmapped return value to MDR; fixes RoboCop 3
    [Jonas Quinn]
  - WonderSwan Color: do not mask screen tilemap base address; fixes Sorobang
    [FPGAzumSpass]
  - Mega Drive: set supervisor mode and clear trace mode for all exceptions;
    fixes Gouketsuji Ichizoku [Jonas Quinn]
  - Mega CD: format BRAM instead of leaving it uninitialized; fixes Popful Mail
    (US)
  - WonderSwan: add patch for Meitantei Conan: Nishi no Meitantei Saidai
    no Kiki!
  - Game Boy: add MBC1#M mapper database entries; fixes Bomber Man Collection,
    Genjin Collection, Momotarou Collection, and Mortal Kombat I & II
  - Neo Geo Pocket: $8118 background register exists even in the K1GE GPU;
    fixes Samurai Shodown
  - Neo Geo Pocket Color: return 0xFF acknowledge byte after flash erase
    command; fixes Puzzle Link 2 and Memories off: Pure
  - Neo Geo Pocket: clear watchdog timer counter on trigger to prevent
    infinite triggering; fixes Neo Baccarat, Neo Cherry Master Color, and
    Neo Mystery Bonus
  - TLCS900H: do not allow interrupts to run between CPDR, LDIR, LDDR
    instructions; fixes Fantastic Night Dreams Cotton
  - Neo Geo Pocket: add all remaining missing I/O registers (not emulated,
    but registers are readable and writable now)
  - Neo Geo Pocket Color: above changes also fixed in-game audio in Crush
    Roller and Dynamite Slugger
  - Mega CD: added 1M mode WRAM swap request flag; fxies AX-101, Earnest Evans,
    and Might & Magic III [TascoDLX]
  - Nintendo 64: added ISViewer support
  - lucia: added input mapping overlays for all remaining systems
  - lucia: added two-player support to all remaining systems
2021-06-07 09:45:00 +00:00
Near 9d6d3612a7 Update to ares v120r13 release.
- Game Gear: fix inputs
  - Master System: don't evaluate sprites past active display area [fixes
    Rescue Mission]
  - Mega Drive: don't acknowledge VDP IRQs until the CPU triggers them [fixes
    Mega Lo Mania]
  - lucia: begin refactoring input mapping to allow per-system mappings and
    multiple controller types
2021-06-04 09:21:00 +00:00
Near e867dbd380 Update to ares v120r12 release.
- M68HC05: initial core implementation added
  - M68000: renamed core from M68K
  - Super Famicom: clearing $4200.d0 stops active joypad polling for the rest
    of the frame [Jonas Quinn]
2021-06-03 03:21:00 +00:00
Near cf25b04854 Update to ares v120r11 release.
- Nintendo 64: fixed cartridge flash memory support
  - Master System: VDP line coincidence should be initialized to $ff [fixes
    Shadow Dancer]
  - Master System: VDP sprite overflow index defaults to $1f, not $00 [fixes
    PGA Tour Golf]
  - SN76489: corrected port latching behavior and noise volume writes [fixes
    Micro Machines]
  - TMS9918: greatly refactored code
  - V9938: greatly refactored code
  - Z80: disassembler fixes
  - lucia: corrected mapping of Master System pause button [fixes Baku
    Baku Panic]
  - nall: disable -Wstringop-overflow for GCC due to compiler heuristics error
2021-06-01 00:24:00 +00:00
Near 02028d8fe2 Update to ares v120r10 release.
- Master System: emulated sprite zoom and fifth-sprite status flag
  - Master System: corrected VDP background emulation for mode 4 [fixes
    Codemasters games]
  - Master System: latch VDP background nametable address and scroll registers
    [fixes Desert Speedtrap]
  - Master System: mask CRAM reads to 6-bit in Master System mode [fixes Mercs]
  - Master System: refactored VDP code
  - Z80: swapped IND/INI to post-decrement B, and OUTD/OUTI to pre-decrement B
  - lucia: fixed a crash when loading Game Gear games due to stubbing out
    the BIOS
2021-05-31 05:15:00 +00:00
Near 47c2fca103 Update to ares v120r09 release.
- Mega Drive: improved EEPROM emulation
  - Nintendo 64: fixed CPU SCC counter rate [simer]
  - Nintendo 64: added initial emulation of the SM5K processor (not connected
    yet)
  - lucia: update frame rate from the main thread to prevent a race condition
    with GTK
2021-05-29 23:42:00 +00:00
Near b8dfb68f6b Update to ares v120r08 release.
- Famicom: added database entries for Jajamaru Gekimaden and Mazase Top
    Pro PRG-RAM
  - M24Cx: rewrote emulation to be more complete; though still not working
    for Cxx/Cxxx sizes
  - Nintendo 64: try stopping SI polling on recv=0xfe
2021-05-27 00:12:00 +00:00
Near 960d8a8dcb Update to ares v120r07 release.
- Nintendo 64: ignore A15 on controller pak reads and writes
  - Master System: implemented Codemasters, Korea, MSX, Janggun mappers
  - Master System: improved Sega mapper emulation
  - Master System: added initial emulation of port $3e
  - Master System: added support to load BIOSes
  - Master System: initialize stack pointer to 0xfffd when no BIOS loaded
    [Luke Usher]
  - Game Boy Advance: emulated BIOS swap register [MerryMage]
  - Mega Drive: cancel pending IRQs when they are disabled [Jonas Quinn]
  - Mega Drive: fixed handling of VDP field flag [Jonas Quinn]
  - Mega Drive: mask upper bit of VDP sprite Y value when in progressive
    display mode [Jonas Quinn]
  - X24C01, M24Cxx: improve emulation of EEPROM command sequences
2021-05-24 16:24:00 +00:00
Near ca273d320e Update to ares v120r06 release.
Metal Slug should be fully playable in AES mode now, but still no sound.
2021-05-21 16:58:00 +00:00
Near 54159cf95e Update to ares v120r05 release.
- Nintendo 64: reverted 64-bit TLB (not actually present)
  - Neo Geo: initial implementation
2021-05-19 01:23:00 +00:00
Near 3cebf21a5e Update to ares 20210516a release.
This one is an experiment to ignore A15 on memory pak reads+writes. If possible,
I'd like to know if any games with controller pak issues start working with this
change that didn't before ^-^;
2021-05-16 17:05:00 +00:00
Near 28a57b9347 Update to ares v120r04 release.
- Mega Drive: fixed a bug with LINEA and LINEF instructions (should not
    decrement PC)
  - Mega Drive: added EEPROM emulation
  - mia: added Mega Drive and Mega 32X EEPROM database entries
  - nall: added priority_queue::remove(T) support
2021-05-16 16:49:00 +00:00
Near 64857906b3 Update to ares 20210516 release.
Fixes *Super Bubble Bobble (Taiwan) (En) (Unl)* for the Mega Drive3
2021-05-16 06:02:00 +00:00
Near c5583ade47 Update to ares 20210513 release.
This doesn't justify a new WIP release yet, but it changes the PI DMA delay
timing which seems to make Aidyn Chronicles work again, so let's see how it
does.
2021-05-13 09:09:00 +00:00
Near 8c7bad148c Update to ares v120r03 release.
- Nintendo 64: improved SI scanning of PIF RAM and emulated more flags
  - Nintendo 64: added very accurate controller pak initialization code
  - Nintendo 64: improved controller analog stick approximations [MerryMage]
  - Nintendo 64: added priority queue to delay SI and PI DMA transfers
  - Master System: added bit-perfect YM2413 instrument patch sets
2021-05-12 10:37:00 +00:00
Near a290c96899 Update to ares v120r02 release.
This fixes a major issue with the 68K ADD,CMP,SUB instructions not clipping, and
improves the VDP scanline renderer timing somewhat.

This fixes Alien Solder, and I also moved the DMA run below the FIFO/prefetch to
fix Comix Zone's graphics. It regresses several Titan Overdrive 2 screens, but
oh well.

I'm trying to track down a bug in Popful Mail (US) where the CPU crashes right
after the title screen. It seems like the CPU is getting stuck in a loop that
keeps calling the same function, so the stack keeps decrementing until it ends
up overwriting the currently executing code with a bad instruction.

Without an I/O tracer it's really difficult to try and understand what the CPU
is stuck waiting on and looping on. I'll have to add an I/O tracer to the Mega
CD registers.

The CPU fixes sadly didn't improve anything in the 32X space. Metal Head gets in
a loop until it overwrites the stack frame return address with 0x1fff1fff that
causes a return to an unaligned address that crashes the SH2 master.

After Burner Complete doesn't boot at all. Amazing Spider-Man still has screwed
up graphics priority ordering for the 32X VDP.

Space Harrier still shows a bunch of junk lines at the top and bottom of the
screen.

The scanline VDP can now run Lemmings 1&2, Alien Soldier, etc. But it still does
horrifically bad with Titan Overdrive, especially 2.
2021-05-10 13:31:00 +00:00
Near 034468c384 Update to ares v120r01 release.
I started to implement N64 RDRAM broadcasting with this WIP, but it's only about
1% complete.
2021-05-07 05:33:00 +00:00
Near 340f48d029 Update to ares v120 release.
This release provides improved Nintendo 64 and Mega Drive emulation, plus some
emulation speedups and new features like keyboard-mapping for all Nintendo 64
controls.

The infamous Titan Overdrive demos now run with the exception of one glitched
screen each, but you will need to compile with profile=accuracy to enable the
required cycle-based VDP renderer for this to work. I'll try in the future to
support as much of it as I can with the default scanline renderer as well.

Changelog (since v119):

  - SH2: added support for Windows ABI to the recompiler
  - SH2: MAC must increment R[n] before reading from R[m]; fixes Virtua
    Fighter and Toughman Contest
  - SH2: fixed dynarec MOV @Rm+,Rn to not increment when Rm==Rn
  - SH2: fixed dynarec TST instruction
  - SH2: improved dynarec accuracy by breaking blocks on delay slot branches
  - SH2: improved dynarec accuracy by decreasing the underclocking amount
  - Mega Drive: implemented undocumented VSRAM and CRAM DMA fill
  - Mega Drive: simplified scanline VDP renderer; fixes TMNT: Tournament
    Fighters graphics
  - Mega Drive: improved region detection; correctly identifies Alien Soldier
    region now
  - Mega CD: fixed crash on game load
  - Super Famicom: fixed direct color mode; fixes Secret of Mana world map
  - WonderSwan Color: fixed initial state for new EEPROMs plus EEPROM size;
    fixes missing sound
  - lucia: fixed saving RAM files when a manual save path was specified
  - ruby: fixed library dependency detection for Arch Linux and other
    distributions
  - SH2: additional correction for dynarec MOV @Rm+,Rn instructions
  - hiro/GTK3: added CSS stylesheet overrides to improve appearance [Screwtape]
  - N64: VMRG was not clearing VCO in C++ version [Rasky]
  - N64: fixed "ctc2" in the disassembler
  - Mega Drive: VDP address/command bits are set even for non-register writes
    [Eke]
  - Mega Drive: implemented VDP FIFO with approximated timings
  - Mega Drive: implemented CPU bus arbitrator
  - N64: fixed RSP vector unit register values in the disassembler
  - Mega Drive: implemented proper VDP FIFO timings for both reads and writes
    (hopefully)
  - Mega Drive: enabled external and RAM refresh timing
  - Mega Drive: added (Mega Drive | Mega 32X) + Mega CD mode 1 emulation
  - Mega Drive: refactored dot-based VDP renderer
  - ares: added Thread::restart() function to reset a thread without resetting
    its clock
  - Mega Drive: improved DRAM refresh timings
  - Mega Drive: added VDP I/O logger
  - Mega Drive: fixed VDP counter emulation (still inaccurate)
  - Mega Drive: improved VDP DMA and FIFO emulation
  - Nintendo 64: report 64DD as missing for now; fixes F-Zero X
  - Nintendo 64: improved TLB emulation; fixes Conker's Bad Fur Day
  - Nintendo 64: PI DMA from flash always reads data, never the status;
    fixes Paper Mario
  - Mega Drive: improved VDP FIFO emulation
  - Mega Drive: improved VDP dot-renderer
  - nall/bit-range: fixed bug with bit indexes >= 32
  - Mega Drive: fixed VDP read buffer indexing for VSRAM and CRAM
  - Mega Drive: fixed 68K to VDP DMA so that it instantly freezes the CPU
  - Mega Drive: emulated VDP left window hardware glitch where hscroll&15!=0
  - Mega Drive: improved CPU interrupt handling
  - Mega Drive: added APU bus mirrorings
  - Mega Drive: emulated the VDP debug register
  - Mega Drive: fixed VDP VRAM DMA copy
  - Mega Drive: improved 128KB VRAM mode support
  - Mega Drive: mask sprite attribute table address in H40 mode [Sik]
  - Mega Drive: VDP timing improvements
  - Nintendo 64: improved EEPROM support; fixes Perfect Dark
  - Nintendo 64: improved VI interrupt support; fixes Star Wars: Rogue Squadron
    title screen [nodev]
  - Nintendo 64: emulated CIC-NUS-6105 copy protection; fixes Banjo-Tooie
    [XScale]
  - Nintendo 64: added serrate (interlace) support and fixed bug when
    supersampling in serrate mode
  - Nintendo 64: emulated CPU instruction cache
  - Nintendo 64: emulated CPU data cache
  - Nintendo 64: emulated CPU CACHE instruction
  - Nintendo 64: fixed CPU TLB bug; fixes GoldenEye
  - Nintendo 64: began adapting CPU cached interpreter into a dynamic
    recompiler
  - Nintendo 64: began adapting RSP cached interpreter into a dynamic
    recompiler
  - Nintendo 64: added 64-bit addressing and TLB supporting
  - Nintendo 64: added endian support to [LS][WD][LR] instructions
  - Nintendo 64: improved dynamic recompiler
  - PlayStation: began adapting CPU cached interpreter into a dynamic
    recompiler
  - lucia: allow mapping analog axes separately (allows mapping sticks to
    the keyboard)
  - Nintendo 64: corrected analog stick ranges
  - Nintendo 64: emulate the analog stick as an octagon rather than a circle
    [YetAnotherEmuDev]

[This is actually the second release of v120; the change since the first release
is the N64 analog stick ranges and the octagon gate. -Ed.]
2021-05-06 02:14:00 +00:00
Near 1b574d0bb5 Update to ares v119r16 release.
- Mega Drive: VDP scanline renderer compiles once more
  - Nintendo 64: improved dynamic recompiler
  - PlayStation: began adapting CPU cached interpreter into a dynamic
    recompiler
  - lucia: allow mapping analog axes separately (allows mapping sticks to
    the keyboard)

All that's left now is fixing the call() function in the N64/PS1 to support >3
(4) arguments on Windows and we can release v120
2021-05-05 03:10:00 +00:00
Near 25771ba202 Update to ares v119r15 release.
- Nintendo 64: began adapting CPU cached interpreter into a dynamic
    recompiler
  - Nintendo 64: began adapting RSP cached interpreter into a dynamic
    recompiler
  - Nintendo 64: added 64-bit addressing and TLB supporting
  - Nintendo 64: added endian support to [LS][WD][LR] instructions

I could really use a hand with my CPU dynarec, n64/cpu/recompiler.cpp line 1335.

When calling an FPU instruction without SCC coprocessor 1 enabled, it throws an
exception.

If I call the exception function, the emulator crashes hard and I don't
understand why at all.

The stack is aligned, but it seems if I modify rbx/rbp/r13 as I do with the
RSP+SH2 just fine, it seems to die. Yet even if I make that code restore
rbx/rbp/r13 before calling the coprocessor exception function, it still dies.
Really at a loss >_>

Also, this will only work on Linux/BSD at the moment. The RSP vector functions
pass four parameters, and my Windows call wrapper can only handle 3 arguments
because after that the argument has to go on the stack. I'll fix that later.
2021-05-04 08:31:00 +00:00
Near 02180bad08 Update to ares v119r14 release.
Working Nintendo 64 data cache emulation (still don't know the memory access
timings for it) and improved Mega Drive VDP emulation (still can't run TO1&2)
2021-04-30 07:34:00 +00:00
Near 8b7daf3c26 Update to ares v119r13 release.
GoldenEye 007 and Jet Force Gemini run now. Right now, known N64 bugs are:
Donkey Kong 64 hangs when the EEPROM support is enabled, Indiana Jones doesn't
boot (probably anti-emulator code?), Blast Corps blinks a lot (though less than
it did before.)

This WIP has CPU instruction and data cache emulation, though I had to disable
the data cache as it's not working yet.
2021-04-28 04:17:00 +00:00
Near 32ce9a54db Update to ares v119r12 release.
Three N64 game fixes. Refactored Mega Drive profile=accuracy vdp more, still
can't pass Titan Overdrive 1 or 2 ._. Really getting demotivated on that one.
2021-04-25 22:48:00 +00:00
Near f80efd1c05 Update to ares 20210422 release.
This has really really really improved timings.
2021-04-22 04:52:00 +00:00
Near 88714763ca Update to ares v119r10 release.
[Previously, Near said "Now to fix sprite fetching on Y=-1"]

Should be substantially better now.

Titan Overdrive 2 shows distorted graphics on the "Overdrive 2" logo screen
(after the ship crash and maze run), and the only way to get that working is to
double the VDP FIFO speed. It already runs twice as fast in 128K VRAM mode. The
same FIFO speed doubling is required to not crash after the Titancade screen.

Unless I'm really fundamentally misunderstanding something, I'm not sure what's
going on here.
2021-04-20 07:10:00 +00:00
Near 1b67ca2b79 Update to ares v119r09 release.
This gets us a lot further with the Mega Drive, but still some major issues.
Lemmings 2 will sometimes crash when you load it (not threading related), and
Titan Overdrive 2 crashes after the arcade scene. Ran out of steam to work on
this more today though, 12 hours in already.
2021-04-18 06:10:00 +00:00
Near a657ddf23d Update to ares 20210418a release.
This has VDP debug register emulation, well one of the 16 debug registers anyway

I fixed sound in TO2, was mirroring like crazy in the APU space, also fixed
sprites not rendering all the way in the rain scene.

So what you'll see I'm doing is setting an irq.(vh)blank.pending=1 flag, and
then whenever you have hvirq enabled AND a pending flag, it sends an IRQ to the
CPU and clears the pending flag, and when the CPU triggers it, the CPU marks it
as acknowledged.

Apparently BlastEm links bit 7 of the control status register to the
vblank.pending flag, so I'm copying that.

[Near then posted a screenshot of Titan Overdrive 2 running inside ares. In
white text on a blue background, it says:

    0D2 B50D

    D0 00000001
    D1 00FF2700
    D2 93979301
    D3 40000002
    D4 0D12001C
    D5 00000000
    D6 00000001
    D7 0000FFFF
    A0 00C00004
    A1 00C00000
    A2 00000CBC
    A3 00000DEC
    A4 00FF1464
    A5 00FF0C1A
    A6 00FF0C1A
    A7 00FFFFFE

-Ed.]

Crashes here if I don't lower the CPU H/VIRQ lines on Vblank/Hblank=0

Also I am faking the Vcounter incrementing early when reading the Vcounter,
easier that way.
2021-04-18 01:59:00 +00:00
Near a986fafb69 Update to ares 20210418 release.
Here's a snapshot, gets Titan Overdrive 2 music playing.
2021-04-17 22:02:00 +00:00
Near f45ccd4b7d Update to ares v119r08 release.
Really substantial Mega Drive profile=accuracy timing improvements, but still
Titan Overdrive 2 performs much worse than the default performance profile, and
that fucking audio driver still won't play any sound.
2021-04-15 19:58:00 +00:00
Near 1b6b4f1ae2 Update to ares v119r06 release.
- Nintendo 64: report 64DD as missing for now; fixes F-Zero X
  - Nintendo 64: improved TLB emulation; fixes Conker's Bad Fur Day
  - Mega Drive: improved VDP FIFO emulation
2021-04-10 23:07:00 +00:00
Near bd8a1b5155 Update to ares v119r05 release.
- ares: added Thread::restart() function to reset a thread without resetting
    its clock
  - Mega Drive: improved DRAM refresh timings
  - Mega Drive: added VDP I/O logger
  - Mega Drive: fixed VDP counter emulation (still inaccurate)
  - Mega Drive: improved VDP DMA and FIFO emulation
2021-04-08 21:28:00 +00:00
Near 21d3983b4d Update to ares v119r04 release.
- N64: fixed RSP vector unit register values in the disassembler
  - Mega Drive: implemented proper VDP FIFO timings for both reads and writes
    (hopefully)
  - Mega Drive: enabled external and RAM refresh timing
  - Mega Drive: added (Mega Drive | Mega 32X) + Mega CD mode 1 emulation
  - Mega Drive: refactored dot-based VDP renderer
2021-04-06 16:38:00 +00:00
Near c9d2f41bdb Update to ares v119r03 release.
A working VDP FIFO implementation (write slots only), but probably wildly
inaccurate. Rough timing approximations for the slots.

This build fixes some issues in MD Sonic the Hedgehog (forgot to undo the
background color register bit twiddling when reverting some overly aggressive
VDP-performance optimizations) and also fixes MD Golden Axe II.

I spent a few hours trying to fix Lemmings 2 from locking up immediately. What
happens is I get a fourth Hblank IRQ before it clears a RAM value, whereas
Mednafen only gets three. And that desyncs something and it never gets out of a
loop.
2021-04-04 08:31:00 +00:00
Near 787417cf2b Update to ares v119r2 release.
Unfortunately a few critical issues crept in between v118 and v119, so here is a
bugfix release for all reported issues.

It also fixes some game bugs while I'm at it, and boosts 32X compatibility from
50% to a little over 60%.

Please do upgrade if you have v119, this one's important.

  - SH2: MAC must increment R[n] before reading from R[m]; fixes Virtua
    Fighter and Toughman Contest
  - SH2: fixed dynarec MOV @Rm+,Rn to not increment when Rm==Rn
  - SH2: fixed dynarec TST instruction
  - SH2: improved dynarec accuracy by breaking blocks on delay slot branches
  - SH2: improved dynarec accuracy by decreasing the underclocking amount
  - Mega Drive: implemented undocumented VSRAM and CRAM DMA fill
  - Mega Drive: simplified scanline VDP renderer; fixes TMNT: Tournament
    Fighters graphics
  - Mega Drive: improved region detection; correctly identifies Alien Soldier
    region now
  - Mega CD: fixed crash on game load
  - Super Famicom: fixed direct color mode; fixes Secret of Mana world map
  - WonderSwan Color: fixed initial state for new EEPROMs plus EEPROM size;
    fixes missing sound
  - lucia: fixed saving RAM files when a manual save path was specified
  - ruby: fixed library dependency detection for Arch Linux and other
    distributions
  - hiro/GTK3: added CSS stylesheet overrides to improve appearance [Screwtape]
2021-04-02 07:23:00 +00:00
Near b3aeb41ee5 Update to ares v119 release.
I'm releasing ares v119 today, which includes very preliminary Sega 32X
emulation support. Compatibility is currently at around 50% with the dynamic
recompiler, probably closer to 75% with the cached interpreter, and since the
system requirements were a bit too steep (on account of my Mega Drive core being
cycle/dot-accurate), I downclocked the SH2s a bit until I can speed up the
emulator more. You'll currently need about a Ryzen 5 2600 to hit 60fps reliably.
With the underclock, my Ryzen 7 5800X hits 120fps, and without it, 85fps.

Although the compatibility for the new 32X core is a bit low, this is mostly due
to pesky CPU bugs. The accuracy is quite high and I've emulated as much of the
32X and SH7604 peripheral functions as possible. I pass all 161 tests from the
Mars Check Program. It should not take much more work to reach 98% compatibility
in the future. Sega CD 32X emulation support is present, but is likely not
functional, as I haven't tested it yet.

Other major features in this release include Sega SVP support for Virtua Racing,
plus improved Nintendo 64, Mega Drive, and Mega CD emulation compatibility.

I'm going to start working on Sega Saturn emulation now, while Luke Usher works
on Neo Geo emulation. No promises as to when or if these cores will become
playable, I'm just giving you all a heads up since you'll see the skeletons for
these systems in the source code now.

Changelog:

  - Nintendo 64: improved Expansion Pak detection
  - Nintendo 64: fixed swapped L and R buttons [simer]
  - Nintendo 64: emulated the RST bit for gamepads
  - ruby: added library detection support for the Linux and BSD targets
  - lucia: gained support for game paks (custom file dialog only)
  - Super Famicom: added support for Super Game Boy, Sufami Turbo, and BS
    Memory packs
  - hiro: made SourceEdit optional for gtk2 and gtk3 targets (disabled
    for ares)
  - Nintendo 64: emulated 2048-byte EEPROM identifier and transfer protocol
  - Super Famicom: corrected ppu-performance widths table indexing to consider
    overscan
  - Mega CD: fixed a bug in register $ff8003; allows Popful Mail to boot
    [TascoDLX]
  - Mega Drive: fixed a bug with 256-width video modes
  - Mega Drive: improved VDP DMA emulation which should fix many games
  - Mega Drive: added SVP emulation
  - Mega Drive: added 32X emulation
  - Mega CD: fixed a bit-masking bug in register $ff8004; fixes Radical Rex
    [TascoDLX]
  - Nintendo 64: fixed C implementation of RSP VMACU instruction
  - Nintendo 64: use correct NTSC and PAL PIF ROM images based on the region
  - Mega Drive: fixed reset logic, Z80 interrupt timing + prefix timing +
    bus control [TascoDLX]
  - Mega CD: fixed word RAM access and CDC DMA word RAM transfers [TascoDLX]
  - Nintendo 64: improved RSP VMOV emulation [Rasky]
  - Nintendo 64: fixed RSP DMEM DMA alignment (&~7, not &~3) [Rasky]
  - Nintendo 64: upgraded to the latest version of ParaLLEl-RDP
  - nall: greatly expanded recompiler/amd64's supported intrinsics
  - mia: substantial refactoring around a new virtual filesystem implementation
    from nall
2021-03-31 04:38:00 +00:00
Near d0258c76e6 Update to ares v118r16 release.
My latest ares WIP hooked up 128KB VRAM mode to my fast SNES PPU.
2021-03-27 20:22:00 +00:00
Near fd4eb76bf5 Update to ares v118r15 release.
[This release was posted to the ares Discord after r16. That version introduced
128KB VRAM mode for the Super Famicom core, and somebody requested the previous
version so they could see the changes involved in implementing that feature.
-Ed.]
2021-03-25 05:31:00 +00:00
Near 8c1d9840c0 Update to ares v118r13 release.
Latest version with VMOV and RSP DMEM mask fix
2021-03-24 00:21:00 +00:00
Near fae7a763fa Update to ares v118r12 release.
With TascoDLX's Mega CD fix ❤️❤️
2021-03-22 09:36:00 +00:00
Near d6dfd20dd6 Update to ares v118r11 release.
That's as far as I can go with 32X support for now. I fully emulated the Sh2
cache but I still hang at Mars test 123. The Hblank (2) test fails because it
looks like I'm running a bit too fast. The DMA test fails because it expects
DREQ to become inactive when the DREQ length hits zero. If I do that, the test
hangs. If I don't do that, the test fails.

Virtua Fighter shows no graphics in-game, Virtua Racing shows no graphics
period.
2021-03-22 09:03:00 +00:00
Near 493a446168 Update to ares v118r09 release.
Knuckles Chaotix is now fully playable at glorious 20fps, heh.

Still a whole ton of issues but I really went to town with this WIP. I
implemented read/write functionality for all the SH7804 internal
registers/functional units, and added basic simulation of the free-range timer,
DMA controller (very basic) and interrupt controller.

On the 32X side, it should be functionally complete save for bugs now. VDP and
PWM are fully implemented.
2021-03-18 07:07:00 +00:00
Near 1ca28694f9 Update to ares 20210317 release.
I am getting my ass kicked by SH-2 delay slots >_>

The basic idea of them is simple, but the PR register and when to do the +4 or
+2 or not is not intuitive.
2021-03-17 09:23:00 +00:00
Near 382634e311 Update to ares v118r08 release.
Still too many bugs to run anything. Hopefully next time ...

Chaotix 68K writes to FIFO, then SH2s never read it or query FIFO status.
2021-03-15 06:33:00 +00:00
Near e6f5e75854 Update to ares v118r07 release.
SH-2 core finished, started connecting the 32X to it. It executes some
instructions and does some I/O register stuff before hanging. Still gotta
implement the 32X interrupts, PWM, and VDP stuff.
2021-03-14 03:57:00 +00:00
Near a17f29d4c4 Update to ares v118r05 release.
Here's the current build with working SVP support. Build with profile=accuracy
if you try it because my fast scanline renderer breaks soooo many games
including Virtua Racing ._.
2021-03-10 07:31:00 +00:00
Near a38a31e47a Update to ares v118r04 release.
This WIP has the new mia system. It's a pretty massive change ... I hope it will
go okay for you. Feel free to ping me and I'll walk you through it.

Essentially, we want to edit mia/system/neo-geo-(aes|mvs).cpp to load in the
necessary files from MAME's neogeo.zip that is given to it (I have a helper
Pak::read(zipfile, pattern) function to grab files out of the archive for you
into a vector<u8>), do endian conversion, add to the pak, then the Neo Geo core
can see it.

The Neo Geo cartridge support should be enough for Magician Lord and super early
games with no mappers or crypto, so we'll start there and work our way up.
2021-03-07 19:05:00 +00:00
Near 007b27704d Update to ares 20210303 release.
My tracer was crashing in v118 for the Mega CD due to the trace address not
being masked and the value underflowing, so here's a pre-v118.4 WIP with that
fixed.
2021-03-03 04:44:00 +00:00
Near c5759c503f Update to ares v118r02 release.
So, spoiler since you'll all see it: Luke and I are gonna be working on a
Neo*Geo core. Please keep that a secret for now until we can get some
screenshots to share with people.

Would appreciate feedack on the vfs redesign, still a work in progress. Right
now, the potential is there to have ares cores that don't use manifests at all.
So far, only the ColecoVision core actually does it. However, all cores are
ported to use the new Platform::pak() function instead of Platform::open() [now
removed.]

Lots of stuff is broken right now: N64/PS1 memory cards, PC Engine CD / Mega CD
internal save memory, Mega CD can't play any games, FDS and NGP don't save, etc.
2021-03-01 19:28:00 +00:00
Near c72292ef4b Update to ares v118r01 release.
[No official changelog available for this version. -Ed.]
2021-02-26 19:33:00 +00:00
Near 44bdc531bb Update to ares v118 release.
I'm excited to launch ares v118 today, the first release featuring playable,
full-speed Nintendo 64 emulation!

The new Nintendo 64 emulation is made possible thanks to [Themaister] very
graciously porting his Vulkan-based ParaLLEl-RDP graphics renderer to ares. With
its default settings, it is nearly pixel-perfect to real hardware, and it
optionally supports upscaling to 2x or 4x the original Nintendo 64 resolution,
plus optional supersampling back down to the original resolution (for enhanced
anti-aliasing) if desired. The Vulkan support requires an appropriate graphics
card, and either Windows or Linux. At this time, Vulkan is not available for
macOS nor the BSDs.

Also new for the Nintendo 64 core in this release is Rumble Pak, Cartridge Pak,
SRAM, EEPROM, and Flash save support. Note that for right now, the Rumble Pak
will only be enabled for games which use internal saves (SRAM, EEPROM, and
Flash.) That does not cover all Rumble Pak-capable games. The option to choose
between Rumble Paks and Cartridge Paks will be added to a future release.

For the PlayStation core, [Luke Usher] provided two rendering fixes that allow
Final Fantasy VII and Tony Hawk's Pro Skater to be fully playable!

Right now, approximately 33% of the Nintendo 64 library is fully playable, and
about 67% of the PlayStation library is fully playable. Each core has only been
under active development for about one month each, so they both have a long way
to go. Please treat these early releases as tech samples, rather than finished
emulation cores.

Further, note that the Nintendo 64 and PlayStation cores employ cached
interpreters. This is a middle-ground between the accuracy of interpreters and
the performance of dynamic recompilers. As such, ares' system requirements will
be a bit higher than traditional emulators for these systems. Presuming no
background task interference or CPU throttling, generally speaking, a Ryzen 5
2600 or better CPU should get you to around ~120fps in the average case, and
~60fps in the worst case.

The source code has also been released under the terms of the Creative Commons
BY-NC-ND 4.0 license.

[Themaister]: http://github.com/Themaister/
[Luke Usher]: https://twitter.com/LukeUsher1
2021-02-20 23:51:00 +00:00
Near 43af5c298b Update to ares v117r03 release.
[No official changelog available for this version. -Ed.]
2021-02-18 16:27:00 +00:00
Near 1e577f56e7 Update to ares v117r01 release.
[No official changelog available for this version. -Ed.]
2021-02-15 23:04:00 +00:00
Near 7656765f30 Update to ares v117 release.
[No official changelog available for this version. -Ed.]
2021-02-08 09:11:00 +00:00
Near fabde308e9 Update to ares v116r08 release.
[No official changelog available for this version. -Ed.]
2021-01-18 21:03:00 +00:00
Near 4af59c63f1 Update to ares v116r07 release.
[No official changelog available for this version. -Ed.]
2021-01-14 21:00:00 +00:00
Near 70cdb5b199 Update to ares v115a release.
[No official changelog available for this version. -Ed.]
2020-07-26 17:29:00 +00:00
2336 changed files with 107753 additions and 62974 deletions

No files matched your search

+13 -1
View File
@@ -7,13 +7,17 @@ else ifneq ($(filter $(platform),linux bsd),)
options += -Wl,-export-dynamic
options += -lX11 -lXext
else
$(error "unsupported platform")
$(error "ares is a library and cannot be built directly.")
endif
ares.objects := ares
$(object.path)/ares.o: $(ares.path)/ares/ares.cpp
ifeq ($(vulkan),true)
flags += -DVULKAN
endif
ifeq ($(profile),accuracy)
flags += -DPROFILE_ACCURACY
endif
@@ -46,6 +50,10 @@ ifneq ($(filter $(cores),md),)
include $(ares.path)/md/GNUmakefile
endif
ifneq ($(filter $(cores),saturn),)
include $(ares.path)/saturn/GNUmakefile
endif
ifneq ($(filter $(cores),ps1),)
include $(ares.path)/ps1/GNUmakefile
endif
@@ -74,6 +82,10 @@ ifneq ($(filter $(cores),ws),)
include $(ares.path)/ws/GNUmakefile
endif
ifneq ($(filter $(cores),ng),)
include $(ares.path)/ng/GNUmakefile
endif
ifneq ($(filter $(cores),ngp),)
include $(ares.path)/ngp/GNUmakefile
endif
+81
View File
@@ -0,0 +1,81 @@
#version 150
//anti-aliased nearest-neighbor
precision highp float;
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec4 vpow(vec4 n, float e) {
return vec4(pow(n.x, e), pow(n.y, e), pow(n.z, e), pow(n.w, e));
}
vec4 toLQV(vec3 c) {
return vec4(c.r, c.g, c.b, c.r * 0.2989 + c.g * 0.5870 + c.b * 0.1140);
}
vec3 fromLQV(vec4 c) {
float f = c.w / (c.r * 0.2989 + c.g * 0.5870 + c.b * 0.1140);
return vec3(c.rgb) * f;
}
vec3 percent(float ssize, float tsize, float coord) {
float minfull = (coord * tsize - 0.5) / tsize * ssize;
float maxfull = (coord * tsize + 0.5) / tsize * ssize;
float realfull = floor(maxfull);
if(minfull > realfull) {
return vec3(
1,
(realfull + 0.5) / ssize,
(realfull + 0.5) / ssize
);
}
return vec3(
(maxfull - realfull) / (maxfull - minfull),
(realfull - 0.5) / ssize,
(realfull + 0.5) / ssize
);
}
void main() {
float srgb = 2.1;
float gamma = 3.0;
vec3 x = percent(sourceSize[0].x, targetSize[0].x, texCoord.x);
vec3 y = percent(sourceSize[0].y, targetSize[0].y, texCoord.y);
//get points to interpolate across in linear RGB
vec4 a = toLQV(vpow(texture(source[0], vec2(x[1], y[1])), srgb).rgb);
vec4 b = toLQV(vpow(texture(source[0], vec2(x[2], y[1])), srgb).rgb);
vec4 c = toLQV(vpow(texture(source[0], vec2(x[1], y[2])), srgb).rgb);
vec4 d = toLQV(vpow(texture(source[0], vec2(x[2], y[2])), srgb).rgb);
//use perceptual gamma for luminance component
a.w = pow(a.w, 1 / gamma);
b.w = pow(b.w, 1 / gamma);
c.w = pow(c.w, 1 / gamma);
d.w = pow(d.w, 1 / gamma);
//interpolate
vec4 gammaLQV =
(1.0 - x[0]) * (1.0 - y[0]) * a +
(0.0 + x[0]) * (1.0 - y[0]) * b +
(1.0 - x[0]) * (0.0 + y[0]) * c +
(0.0 + x[0]) * (0.0 + y[0]) * d;
//convert luminance gamma back to linear
gammaLQV.w = pow(gammaLQV.w, gamma);
//convert color back to sRGB
fragColor = vpow(vec4(fromLQV(gammaLQV), 1), 1 / srgb);
}
+8
View File
@@ -0,0 +1,8 @@
input
filter: nearest
program
fragment: AANN.fs
output
filter: nearest
@@ -0,0 +1,21 @@
#version 150
#define distortion 0.2
uniform sampler2D source[];
uniform vec4 sourceSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec2 radialDistortion(vec2 coord) {
vec2 cc = coord - vec2(0.5);
float dist = dot(cc, cc) * distortion;
return coord + cc * (1.0 - dist) * dist;
}
void main() {
fragColor = texture(source[0], radialDistortion(texCoord));
}
@@ -0,0 +1,4 @@
program
filter: linear
wrap: border
fragment: curvature.fs
@@ -0,0 +1,25 @@
#version 150
uniform sampler2D source[];
uniform vec4 sourceSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec3 grayscale(vec3 color) {
return vec3(dot(color, vec3(0.3, 0.59, 0.11)));
}
void main() {
vec2 offset = fract(texCoord * sourceSize[0].xy) - 0.5;
offset /= sourceSize[0].xy;
vec3 cx = texture(source[0], texCoord - offset).xyz;
vec3 cy = texture(source[0], texCoord).xyz;
vec3 cz = vec3(5.0 * grayscale(abs(cx - cy)));
fragColor = vec4(clamp(cz, 0.0, 1.0), 1.0);
}
@@ -0,0 +1,4 @@
program
filter: linear
wrap: edge
fragment: edge-detection.fs
@@ -0,0 +1,4 @@
program
filter: linear
wrap: border
fragment: scanline.fs
+20
View File
@@ -0,0 +1,20 @@
#version 150
uniform sampler2D source[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
void main() {
vec4 rgba = texture(source[0], texCoord);
vec4 intensity;
if(fract(gl_FragCoord.y * (0.5 * 4.0 / 3.0)) > 0.5) {
intensity = vec4(0);
} else {
intensity = smoothstep(0.2, 0.8, rgba) + normalize(rgba);
}
fragColor = intensity * -0.25 + rgba * 1.1;
}
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
+2 -4
View File
@@ -1,5 +1,5 @@
database
revision: 2020-06-07
revision: 2020-11-09
//Boards (Production)
@@ -587,7 +587,7 @@ board: SHVC-YJ0N-01
//Boards (Generic)
database
revision: 2020-06-07
revision: 2020-11-09
board: ARM-LOROM-RAM
memory type=ROM content=Program
@@ -706,7 +706,6 @@ board: EXHIROM-RAM
map address=c0-ff:0000-ffff mask=0xc00000
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
map address=70-7d:0000-7fff
board: EXHIROM-RAM-SHARPRTC
memory type=ROM content=Program
@@ -716,7 +715,6 @@ board: EXHIROM-RAM-SHARPRTC
map address=c0-ff:0000-ffff mask=0xc00000
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
map address=70-7d:0000-7fff
rtc manufacturer=Sharp
map address=00-3f,80-bf:2800-2801
memory type=RTC content=Time manufacturer=Sharp
+26 -16
View File
@@ -13,12 +13,15 @@
#include <nall/endian.hpp>
#include <nall/image.hpp>
#include <nall/literals.hpp>
#include <nall/priority-queue.hpp>
#include <nall/queue.hpp>
#include <nall/random.hpp>
#include <nall/serializer.hpp>
#include <nall/set.hpp>
#include <nall/shared-pointer.hpp>
#include <nall/string.hpp>
#include <nall/terminal.hpp>
#include <nall/thread.hpp>
#include <nall/traits.hpp>
#include <nall/unique-pointer.hpp>
#include <nall/variant.hpp>
@@ -33,37 +36,44 @@
using namespace nall;
namespace ares {
static const string Name = "ares";
static const string Version = "121";
static const string Copyright = "Near";
static const string License = "ISC";
static const string LicenseURI = "https://opensource.org/licenses/ISC";
static const string Website = "ares.dev";
static const string WebsiteURI = "https://ares.dev";
//incremented only when serialization format changes
static const u32 SerializerSignature = 0x31545342; //"BST1" (little-endian)
static const string SerializerVersion = "121";
namespace VFS {
using Pak = shared_pointer<vfs::directory>;
using File = shared_pointer<vfs::file>;
}
namespace Video {
static constexpr bool Threaded = true;
}
namespace Constants {
namespace Colorburst {
static constexpr double NTSC = 315.0 / 88.0 * 1'000'000.0;
static constexpr double PAL = 283.75 * 15'625.0 + 25.0;
static constexpr f64 NTSC = 315.0 / 88.0 * 1'000'000.0;
static constexpr f64 PAL = 283.75 * 15'625.0 + 25.0;
}
}
//nall/vfs shorthand constants
namespace File {
static const auto Read = vfs::file::mode::read;
static const auto Write = vfs::file::mode::write;
static const auto Optional = false;
static const auto Required = true;
}
namespace Shared {
using File = shared_pointer<vfs::file>;
}
extern bool _runAhead;
inline auto runAhead() -> bool { return _runAhead; }
inline auto setRunAhead(bool runAhead) -> void { _runAhead = runAhead; }
}
#include <ares/information.hpp>
#include <ares/types.hpp>
#include <ares/random.hpp>
#include <ares/debug/debug.hpp>
#include <ares/node/node.hpp>
#include <ares/platform.hpp>
#include <ares/interface.hpp>
#include <ares/memory/readable.hpp>
#include <ares/memory/writable.hpp>
#include <ares/resource/resource.hpp>
+29 -1
View File
@@ -3,15 +3,43 @@ namespace ares {
Debug _debug;
auto Debug::reset() -> void {
_totalNotices = 0;
_unhandledNotices.reset();
_unimplementedNotices.reset();
_unusualNotices.reset();
_unverifiedNotices.reset();
}
auto Debug::_unhandled(const string& text) -> void {
if(_unhandledNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unhandledNotices.append(text);
print(terminal::color::yellow("[unhandled] "), text, "\n");
}
auto Debug::_unimplemented(const string& text) -> void {
//only warn about missing unimplemented functionality once per type
if(_unimplementedNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unimplementedNotices.append(text);
print(terminal::color::magenta("[unimplemented] "), text, "\n");
}
auto Debug::_unusual(const string& text) -> void {
if(_unusualNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unusualNotices.append(text);
print(terminal::color::cyan("[unusual] "), text, "\n");
}
auto Debug::_unverified(const string& text) -> void {
if(_unverifiedNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unverifiedNotices.append(text);
print(terminal::color::gray("[unverified] "), text, "\n");
}
}
+22 -5
View File
@@ -1,22 +1,39 @@
namespace ares {
struct Debug {
static constexpr bool enabled = true;
auto reset() -> void;
template<typename... P> auto unhandled(P&&... p) -> void {
return _unhandled({forward<P>(p)...});
}
template<typename... P> auto unimplemented(P&&... p) -> void {
return _unimplemented({forward<P>(p)...});
}
private:
auto _unimplemented(const string&) -> void;
template<typename... P> auto unusual(P&&... p) -> void {
return _unusual({forward<P>(p)...});
}
template<typename... P> auto unverified(P&&... p) -> void {
return _unverified({forward<P>(p)...});
}
private:
auto _unhandled(const string&) -> void;
auto _unimplemented(const string&) -> void;
auto _unusual(const string&) -> void;
auto _unverified(const string&) -> void;
u64 _totalNotices = 0;
vector<string> _unhandledNotices;
vector<string> _unimplementedNotices;
vector<string> _unusualNotices;
vector<string> _unverifiedNotices;
};
extern Debug _debug;
}
#define debug(function, ...) if constexpr(ares::_debug.enabled) ares::_debug.function(__VA_ARGS__)
#define debug(function, ...) if constexpr(1) ares::_debug.function(__VA_ARGS__)
-14
View File
@@ -1,14 +0,0 @@
#pragma once
namespace ares {
static const string Name = "ares";
static const string Version = "115";
static const string Copyright = "ares team";
static const string License = "ISC";
static const string LicenseURI = "https://opensource.org/licenses/ISC";
static const string Website = "ares.dev";
static const string WebsiteURI = "https://ares.dev";
//incremented only when serialization format changes
static const string SerializerVersion = "115";
}
-28
View File
@@ -1,28 +0,0 @@
#pragma once
namespace ares {
struct Interface {
virtual ~Interface() = default;
//information
virtual auto name() -> string { return {}; }
virtual auto game() -> string { return {}; }
//system interface
virtual auto root() -> Node::Object { return {}; }
virtual auto load(Node::Object&) -> void {}
virtual auto power() -> void {}
virtual auto run() -> void {}
virtual auto save() -> void {}
virtual auto unload() -> void {}
//state functions
virtual auto serialize(bool synchronize = true) -> serializer { return {}; }
virtual auto unserialize(serializer&) -> bool { return false; }
//debugging functions
virtual auto exportMemory() -> bool { return false; }
};
}
+5 -5
View File
@@ -2,10 +2,10 @@
namespace ares::Memory {
inline auto mirror(uint address, uint size) -> uint {
inline auto mirror(u32 address, u32 size) -> u32 {
if(size == 0) return 0;
uint base = 0;
uint mask = 1 << 31;
u32 base = 0;
u32 mask = 1 << 31;
while(address >= size) {
while(!(address & mask)) mask >>= 1;
address -= mask;
@@ -18,9 +18,9 @@ inline auto mirror(uint address, uint size) -> uint {
return base + address;
}
inline auto reduce(uint address, uint mask) -> uint {
inline auto reduce(u32 address, u32 mask) -> u32 {
while(mask) {
uint bits = (mask & -mask) - 1;
u32 bits = (mask & -mask) - 1;
address = address >> 1 & ~bits | address & bits;
mask = (mask & mask - 1) >> 1;
}
+18 -23
View File
@@ -15,7 +15,7 @@ struct Readable {
self.mask = 0;
}
auto allocate(uint size, T fill = ~0ull) -> void {
auto allocate(u32 size, T fill = (T)~0ull) -> void {
if(!size) return reset();
delete[] self.data;
self.size = size;
@@ -25,33 +25,32 @@ struct Readable {
}
auto fill(T fill = ~0ull) -> void {
for(uint address : range(self.size)) {
for(u32 address : range(self.size)) {
self.data[address] = fill;
}
}
auto load(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->read(self.data, min(fp->size(), self.size * sizeof(T)));
for(uint address = self.size; address <= self.mask; address++) {
auto load(VFS::File fp) -> void {
if(!self.size) allocate(fp->size());
fp->read({self.data, min(fp->size(), self.size * sizeof(T))});
for(u32 address = self.size; address <= self.mask; address++) {
self.data[address] = self.data[mirror(address, self.size)];
}
}
auto save(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->write(self.data, self.size * sizeof(T));
auto save(VFS::File fp) -> void {
fp->write({self.data, min(fp->size(), self.size * sizeof(T))});
}
explicit operator bool() const { return (bool)self.data; }
auto data() const -> const T* { return self.data; }
auto size() const -> uint { return self.size; }
auto mask() const -> uint { return self.mask; }
auto size() const -> u32 { return self.size; }
auto mask() const -> u32 { return self.mask; }
auto operator[](uint address) const -> T { return self.data[address & self.mask]; }
auto read(uint address) const -> T { return self.data[address & self.mask]; }
auto write(uint address, T data) const -> void {}
auto program(uint address, T data) const -> void { self.data[address & self.mask] = data; }
auto operator[](u32 address) const -> T { return self.data[address & self.mask]; }
auto read(u32 address) const -> T { return self.data[address & self.mask]; }
auto write(u32 address, T data) const -> void {}
auto program(u32 address, T data) const -> void { self.data[address & self.mask] = data; }
auto begin() -> T* { return &self.data[0]; }
auto end() -> T* { return &self.data[self.size]; }
@@ -60,18 +59,14 @@ struct Readable {
auto end() const -> const T* { return &self.data[self.size]; }
auto serialize(serializer& s) -> void {
const uint size = self.size;
s.integer(self.size);
s.integer(self.mask);
if(self.size != size) allocate(self.size);
s.array(self.data, self.size);
s(array_span<T>{self.data, self.size});
}
private:
//private:
struct {
T* data = nullptr;
uint size = 0;
uint mask = 0;
u32 size = 0;
u32 mask = 0;
} self;
};
+18 -23
View File
@@ -15,7 +15,7 @@ struct Writable {
self.mask = 0;
}
auto allocate(uint size, T fill = ~0ull) -> void {
auto allocate(u32 size, T fill = (T)~0ull) -> void {
if(!size) return reset();
delete[] self.data;
self.size = size;
@@ -25,35 +25,34 @@ struct Writable {
}
auto fill(T fill = ~0ull) -> void {
for(uint address : range(self.size)) {
for(u32 address : range(self.size)) {
self.data[address] = fill;
}
}
auto load(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->read(self.data, min(fp->size(), self.size * sizeof(T)));
for(uint address = self.size; address <= self.mask; address++) {
auto load(VFS::File fp) -> void {
if(!self.size) allocate(fp->size());
fp->read({self.data, min(fp->size(), self.size * sizeof(T))});
for(u32 address = self.size; address <= self.mask; address++) {
self.data[address] = self.data[mirror(address, self.size)];
}
}
auto save(shared_pointer<vfs::file> fp) -> void {
if(!self.size) return;
fp->write(self.data, self.size * sizeof(T));
auto save(VFS::File fp) -> void {
fp->write({self.data, min(fp->size(), self.size * sizeof(T))});
}
explicit operator bool() const { return (bool)self.data; }
auto data() -> T* { return self.data; }
auto data() const -> const T* { return self.data; }
auto size() const -> uint { return self.size; }
auto mask() const -> uint { return self.mask; }
auto size() const -> u32 { return self.size; }
auto mask() const -> u32 { return self.mask; }
auto operator[](uint address) -> T& { return self.data[address & self.mask]; }
auto operator[](uint address) const -> T { return self.data[address & self.mask]; }
auto read(uint address) const -> T { return self.data[address & self.mask]; }
auto write(uint address, T data) -> void { self.data[address & self.mask] = data; }
auto program(uint address, T data) -> void { self.data[address & self.mask] = data; }
auto operator[](u32 address) -> T& { return self.data[address & self.mask]; }
auto operator[](u32 address) const -> T { return self.data[address & self.mask]; }
auto read(u32 address) const -> T { return self.data[address & self.mask]; }
auto write(u32 address, T data) -> void { self.data[address & self.mask] = data; }
auto program(u32 address, T data) -> void { self.data[address & self.mask] = data; }
auto begin() -> T* { return &self.data[0]; }
auto end() -> T* { return &self.data[self.size]; }
@@ -62,18 +61,14 @@ struct Writable {
auto end() const -> const T* { return &self.data[self.size]; }
auto serialize(serializer& s) -> void {
const uint size = self.size;
s.integer(self.size);
s.integer(self.mask);
if(self.size != size) allocate(self.size);
s.array(self.data, self.size);
s(array_span<T>{self.data, self.size});
}
private:
struct {
T* data = nullptr;
uint size = 0;
uint mask = 0;
u32 size = 0;
u32 mask = 0;
} self;
};
+4
View File
@@ -0,0 +1,4 @@
struct Audio : Object {
DeclareClass(Audio, "audio")
using Object::Object;
};
+24 -22
View File
@@ -1,14 +1,14 @@
auto Stream::setChannels(uint channels) -> void {
auto Stream::setChannels(u32 channels) -> void {
_channels.reset();
_channels.resize(channels);
}
auto Stream::setFrequency(double frequency) -> void {
auto Stream::setFrequency(f64 frequency) -> void {
_frequency = frequency;
setResamplerFrequency(_resamplerFrequency);
}
auto Stream::setResamplerFrequency(double resamplerFrequency) -> void {
auto Stream::setResamplerFrequency(f64 resamplerFrequency) -> void {
_resamplerFrequency = resamplerFrequency;
for(auto& channel : _channels) {
@@ -18,12 +18,12 @@ auto Stream::setResamplerFrequency(double resamplerFrequency) -> void {
if(_frequency >= _resamplerFrequency * 2) {
//add a low-pass filter to prevent aliasing during resampling
double cutoffFrequency = min(25000.0, _resamplerFrequency / 2.0 - 2000.0);
f64 cutoffFrequency = min(25000.0, _resamplerFrequency / 2.0 - 2000.0);
for(auto& channel : _channels) {
uint passes = 3;
for(uint pass : range(passes)) {
u32 passes = 3;
for(u32 pass : range(passes)) {
DSP::IIR::Biquad filter;
double q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.reset(DSP::IIR::Biquad::Type::LowPass, cutoffFrequency, _frequency, q);
channel.nyquist.append(filter);
}
@@ -41,9 +41,9 @@ auto Stream::resetFilters() -> void {
}
}
auto Stream::addLowPassFilter(double cutoffFrequency, uint order, uint passes) -> void {
auto Stream::addLowPassFilter(f64 cutoffFrequency, u32 order, u32 passes) -> void {
for(auto& channel : _channels) {
for(uint pass : range(passes)) {
for(u32 pass : range(passes)) {
if(order == 1) {
Filter filter{Filter::Mode::OnePole, Filter::Type::LowPass, Filter::Order::First};
filter.onePole.reset(DSP::IIR::OnePole::Type::LowPass, cutoffFrequency, _frequency);
@@ -51,7 +51,7 @@ auto Stream::addLowPassFilter(double cutoffFrequency, uint order, uint passes) -
}
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::LowPass, Filter::Order::Second};
double q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.biquad.reset(DSP::IIR::Biquad::Type::LowPass, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
@@ -59,9 +59,9 @@ auto Stream::addLowPassFilter(double cutoffFrequency, uint order, uint passes) -
}
}
auto Stream::addHighPassFilter(double cutoffFrequency, uint order, uint passes) -> void {
auto Stream::addHighPassFilter(f64 cutoffFrequency, u32 order, u32 passes) -> void {
for(auto& channel : _channels) {
for(uint pass : range(passes)) {
for(u32 pass : range(passes)) {
if(order == 1) {
Filter filter{Filter::Mode::OnePole, Filter::Type::HighPass, Filter::Order::First};
filter.onePole.reset(DSP::IIR::OnePole::Type::HighPass, cutoffFrequency, _frequency);
@@ -69,7 +69,7 @@ auto Stream::addHighPassFilter(double cutoffFrequency, uint order, uint passes)
}
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::HighPass, Filter::Order::Second};
double q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.biquad.reset(DSP::IIR::Biquad::Type::HighPass, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
@@ -77,22 +77,22 @@ auto Stream::addHighPassFilter(double cutoffFrequency, uint order, uint passes)
}
}
auto Stream::addLowShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void {
auto Stream::addLowShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void {
for(auto& channel : _channels) {
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::LowShelf, Filter::Order::Second};
double q = DSP::IIR::Biquad::shelf(gain, slope);
f64 q = DSP::IIR::Biquad::shelf(gain, slope);
filter.biquad.reset(DSP::IIR::Biquad::Type::LowShelf, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
}
}
auto Stream::addHighShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void {
auto Stream::addHighShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void {
for(auto& channel : _channels) {
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::HighShelf, Filter::Order::Second};
double q = DSP::IIR::Biquad::shelf(gain, slope);
f64 q = DSP::IIR::Biquad::shelf(gain, slope);
filter.biquad.reset(DSP::IIR::Biquad::Type::HighShelf, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
@@ -103,14 +103,16 @@ auto Stream::pending() const -> bool {
return _channels && _channels[0].resampler.pending();
}
auto Stream::read(double samples[]) -> uint {
for(uint c : range(_channels.size())) samples[c] = _channels[c].resampler.read() * !muted();
auto Stream::read(f64 samples[]) -> u32 {
for(u32 c : range(_channels.size())) {
samples[c] = _channels[c].resampler.read() * !muted();
}
return _channels.size();
}
auto Stream::write(const double samples[]) -> void {
for(uint c : range(_channels.size())) {
double sample = samples[c] + 1e-25; //constant offset used to suppress denormals
auto Stream::write(const f64 samples[]) -> void {
for(u32 c : range(_channels.size())) {
f64 sample = samples[c] + 1e-25; //constant offset used to suppress denormals
for(auto& filter : _channels[c].filters) {
switch(filter.mode) {
case Filter::Mode::OnePole: sample = filter.onePole.process(sample); break;
+22 -22
View File
@@ -1,39 +1,39 @@
struct Stream : Object {
DeclareClass(Stream, "Stream")
using Object::Object;
struct Stream : Audio {
DeclareClass(Stream, "audio.stream")
using Audio::Audio;
auto channels() const -> uint { return _channels.size(); }
auto frequency() const -> double { return _frequency; }
auto resamplerFrequency() const -> double { return _resamplerFrequency; }
auto channels() const -> u32 { return _channels.size(); }
auto frequency() const -> f64 { return _frequency; }
auto resamplerFrequency() const -> f64 { return _resamplerFrequency; }
auto muted() const -> bool { return _muted; }
auto setChannels(uint channels) -> void;
auto setFrequency(double frequency) -> void;
auto setResamplerFrequency(double resamplerFrequency) -> void;
auto setChannels(u32 channels) -> void;
auto setFrequency(f64 frequency) -> void;
auto setResamplerFrequency(f64 resamplerFrequency) -> void;
auto setMuted(bool muted) -> void;
auto resetFilters() -> void;
auto addLowPassFilter(double cutoffFrequency, uint order, uint passes = 1) -> void;
auto addHighPassFilter(double cutoffFrequency, uint order, uint passes = 1) -> void;
auto addLowShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void;
auto addHighShelfFilter(double cutoffFrequency, uint order, double gain, double slope) -> void;
auto addLowPassFilter(f64 cutoffFrequency, u32 order, u32 passes = 1) -> void;
auto addHighPassFilter(f64 cutoffFrequency, u32 order, u32 passes = 1) -> void;
auto addLowShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void;
auto addHighShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void;
auto pending() const -> bool;
auto read(double samples[]) -> uint;
auto write(const double samples[]) -> void;
auto read(f64 samples[]) -> u32;
auto write(const f64 samples[]) -> void;
template<typename... P>
auto sample(P&&... p) -> void {
auto frame(P&&... p) -> void {
if(runAhead()) return;
double samples[sizeof...(p)] = {forward<P>(p)...};
f64 samples[sizeof...(p)] = {forward<P>(p)...};
write(samples);
}
protected:
struct Filter {
enum class Mode : uint { OnePole, Biquad } mode;
enum class Type : uint { None, LowPass, HighPass, LowShelf, HighShelf } type;
enum class Order : uint { None, First, Second } order;
enum class Mode : u32 { OnePole, Biquad } mode;
enum class Type : u32 { None, LowPass, HighPass, LowShelf, HighShelf } type;
enum class Order : u32 { None, First, Second } order;
DSP::IIR::OnePole onePole;
DSP::IIR::Biquad biquad;
};
@@ -43,7 +43,7 @@ protected:
DSP::Resampler::Cubic resampler;
};
vector<Channel> _channels;
double _frequency = 48000.0;
double _resamplerFrequency = 48000.0;
f64 _frequency = 48000.0;
f64 _resamplerFrequency = 48000.0;
bool _muted = false;
};
@@ -1,4 +1,4 @@
struct Component : Object {
DeclareClass(Component, "Component")
DeclareClass(Component, "component");
using Object::Object;
};
@@ -0,0 +1,30 @@
struct RealTimeClock : Component {
DeclareClass(RealTimeClock, "component.real-time-clock")
using Component::Component;
auto update() -> void { if(_update) return _update(); }
auto timestamp() const -> u64 { return _timestamp; }
auto setUpdate(function<void ()> update) -> void { _update = update; }
auto setTimestamp(u64 timestamp) -> void { _timestamp = timestamp; }
auto synchronize(u64 timestamp = 0) -> void {
if(!timestamp) timestamp = chrono::timestamp();
_timestamp = timestamp;
update();
}
auto serialize(string& output, string depth) -> void override {
Component::serialize(output, depth);
output.append(depth, " timestamp: ", _timestamp, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Component::unserialize(node);
_timestamp = node["timestamp"].natural();
}
protected:
function<void ()> _update;
u64 _timestamp;
};
-26
View File
@@ -1,26 +0,0 @@
struct Graphics : Object {
DeclareClass(Graphics, "Graphics")
Graphics(string name = {}) : Object(name) {
}
auto width() const -> uint { return _width; }
auto height() const -> uint { return _height; }
auto capture() const -> vector<uint32_t> { if(_capture) return _capture(); return {}; }
auto setSize(uint width, uint height) -> void { _width = width, _height = height; }
auto setCapture(function<vector<uint32_t> ()> capture) -> void { _capture = capture; }
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
}
protected:
uint _width = 0;
uint _height = 0;
function<vector<uint32_t> ()> _capture;
};
-83
View File
@@ -1,83 +0,0 @@
struct Instruction : Tracer {
DeclareClass(Instruction, "Instruction")
Instruction(string name = {}, string component = {}) : Tracer(name, component) {
setDepth(_depth);
}
auto depth() const -> uint { return _depth; }
auto addressBits() const -> uint { return _addressBits; }
auto setDepth(uint depth) -> void {
_depth = depth;
_history.reset();
_history.resize(depth);
for(auto& history : _history) history = ~0ull;
}
auto setAddressBits(uint addressBits) -> void {
_addressBits = addressBits;
}
auto address(uint64 address) -> bool {
_address = address;
if(!_depth) return false;
for(auto history : _history) {
if(address == history) {
_omitted++;
return false;
}
}
for(auto index : range(_depth - 1)) {
_history[index] = _history[index + 1];
}
_history.last() = _address;
return true;
}
auto notify(string_view instruction, string_view context, string_view extra = {}) -> void {
if(!enabled()) return;
if(_omitted) {
PlatformLog({
//_component, " ",
"[Omitted: ", _omitted, "]\n"}
);
_omitted = 0;
}
string output{
//_component, " ",
hex(_address, _addressBits + 3 >> 2), " ",
instruction, " ",
context, " ",
extra
};
PlatformLog({output.strip(), "\n"});
}
auto serialize(string& output, string depth) -> void override {
Tracer::serialize(output, depth);
output.append(depth, " depth: ", _depth, "\n");
output.append(depth, " addressBits: ", _addressBits, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Tracer::unserialize(node);
_depth = node["depth"].natural();
_addressBits = node["addressBits"].natural();
setDepth(_depth);
}
protected:
uint _depth = 4;
uint _addressBits = 0;
uint64 _address = 0;
uint64 _omitted = 0;
vector<uint64> _history;
};
-27
View File
@@ -1,27 +0,0 @@
struct Memory : Object {
DeclareClass(Memory, "Memory")
Memory(string name = {}) : Object(name) {
}
auto size() const -> uint { return _size; }
auto read(uint32 address) const -> uint8 { if(_read) return _read(address); return 0; }
auto write(uint32 address, uint8 data) const -> void { if(_write) return _write(address, data); }
auto setSize(uint size) -> void { _size = size; }
auto setRead(function<uint8 (uint32)> read) -> void { _read = read; }
auto setWrite(function<void (uint32, uint8)> write) -> void { _write = write; }
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
}
protected:
uint _size = 0;
function<uint8 (uint32)> _read;
function<void (uint32, uint8)> _write;
};
-18
View File
@@ -1,18 +0,0 @@
struct Notification : Tracer {
DeclareClass(Notification, "Notification")
Notification(string name = {}, string component = {}) : Tracer(name, component) {
}
auto notify(string_view message = {}) -> void {
if(!enabled()) return;
if(message) {
PlatformLog({_component, " [", _name, ": ", message, "]\n"});
} else {
PlatformLog({_component, " [", _name, "]\n"});
}
}
protected:
};
+4
View File
@@ -0,0 +1,4 @@
struct Debugger : Object {
DeclareClass(Debugger, "debugger")
using Object::Object;
};
+26
View File
@@ -0,0 +1,26 @@
struct Graphics : Debugger {
DeclareClass(Graphics, "debugger.graphics")
Graphics(string name = {}) : Debugger(name) {
}
auto width() const -> u32 { return _width; }
auto height() const -> u32 { return _height; }
auto capture() const -> vector<u32> { if(_capture) return _capture(); return {}; }
auto setSize(u32 width, u32 height) -> void { _width = width, _height = height; }
auto setCapture(function<vector<u32> ()> capture) -> void { _capture = capture; }
auto serialize(string& output, string depth) -> void override {
Debugger::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Debugger::unserialize(node);
}
protected:
u32 _width = 0;
u32 _height = 0;
function<vector<u32> ()> _capture;
};
+27
View File
@@ -0,0 +1,27 @@
struct Memory : Debugger {
DeclareClass(Memory, "debugger.memory")
Memory(string name = {}) : Debugger(name) {
}
auto size() const -> u32 { return _size; }
auto read(u32 address) const -> n8 { if(_read) return _read(address); return 0; }
auto write(u32 address, u8 data) const -> void { if(_write) return _write(address, data); }
auto setSize(u32 size) -> void { _size = size; }
auto setRead(function<u8 (u32)> read) -> void { _read = read; }
auto setWrite(function<void (u32, u8)> write) -> void { _write = write; }
auto serialize(string& output, string depth) -> void override {
Debugger::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Debugger::unserialize(node);
}
protected:
u32 _size = 0;
function<u8 (u32)> _read;
function<void (u32, u8)> _write;
};
@@ -1,7 +1,7 @@
struct Properties : Object {
DeclareClass(Properties, "Properties")
struct Properties : Debugger {
DeclareClass(Properties, "debugger.properties")
Properties(string name = {}) : Object(name) {
Properties(string name = {}) : Debugger(name) {
}
auto query() const -> string { if(_query) return _query(); return {}; }
@@ -9,11 +9,11 @@ struct Properties : Object {
auto setQuery(function<string ()> query) -> void { _query = query; }
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
Debugger::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
Debugger::unserialize(node);
}
protected:
@@ -0,0 +1,125 @@
struct Instruction : Tracer {
DeclareClass(Instruction, "debugger.tracer.instruction")
Instruction(string name = {}, string component = {}) : Tracer(name, component) {
setMask(_mask);
setDepth(_depth);
}
auto addressBits() const -> u32 { return _addressBits; }
auto addressMask() const -> u32 { return _addressMask; }
auto mask() const -> bool { return _mask; }
auto depth() const -> u32 { return _depth; }
auto setAddressBits(u32 addressBits, u32 addressMask = 0) -> void {
_addressBits = addressBits;
_addressMask = addressMask;
}
auto setMask(bool mask) -> void {
_mask = mask;
}
auto setDepth(u32 depth) -> void {
_depth = depth;
_history.reset();
_history.resize(depth);
for(auto& history : _history) history = ~0;
}
auto address(u32 address) -> bool {
address &= (1u << _addressBits) - 1; //mask upper bits of address
_address = address;
address >>= _addressMask; //clip unneeded alignment bits (to reduce _masks size)
if(_mask && updateMasks()) {
if(_masks[address >> 3] & 1 << (address & 7)) return false; //do not trace twice
_masks[address >> 3] |= 1 << (address & 7);
}
if(_depth) {
for(auto history : _history) {
if(_address == history) {
_omitted++;
return false; //do not trace again if recently traced
}
}
for(auto index : range(_depth - 1)) {
_history[index] = _history[index + 1];
}
_history.last() = _address;
}
return true;
}
//mark an already-executed address as not executed yet for trace masking.
//call when writing to executable RAM to support self-modifying code.
auto invalidate(u32 address) -> void {
if(unlikely(_mask && updateMasks())) {
address &= (1u << _addressBits) - 1;
address >>= _addressMask;
_masks[address >> 3] &= ~(1 << (address & 7));
}
}
auto notify(const string& instruction, const string& context, const string& extra = {}) -> void {
if(!enabled()) return;
if(_omitted) {
PlatformLog({
"[Omitted: ", _omitted, "]\n"}
);
_omitted = 0;
}
string output{
_component, " ",
hex(_address, _addressBits + 3 >> 2), " ",
instruction, " ",
context, " ",
extra
};
PlatformLog({output.strip(), "\n"});
}
auto serialize(string& output, string depth) -> void override {
Tracer::serialize(output, depth);
output.append(depth, " addressBits: ", _addressBits, "\n");
output.append(depth, " addressMask: ", _addressMask, "\n");
output.append(depth, " mask: ", _mask, "\n");
output.append(depth, " depth: ", _depth, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Tracer::unserialize(node);
_addressBits = node["addressBits"].natural();
_addressMask = node["addressMask"].natural();
_mask = node["mask"].boolean();
_depth = node["depth"].natural();
setMask(_mask);
setDepth(_depth);
}
protected:
auto updateMasks() -> bool {
auto size = 1ull << _addressBits >> _addressMask >> 3;
if(!_mask || !size) return _masks.reset(), false;
if(_masks.size() == size) return true;
_masks.reset();
_masks.resize(size);
return true;
}
u32 _addressBits = 32;
u32 _addressMask = 0;
bool _mask = false;
u32 _depth = 4;
//unserialized:
n64 _address = 0;
n64 _omitted = 0;
vector<u32> _history;
vector<u08> _masks;
};
@@ -0,0 +1,18 @@
struct Notification : Tracer {
DeclareClass(Notification, "debugger.tracer.notification")
Notification(string name = {}, string component = {}) : Tracer(name, component) {
}
auto notify(const string& message = {}) -> void {
if(!enabled()) return;
if(message) {
PlatformLog({_component, " ", _name, ": ", message, "\n"});
} else {
PlatformLog({_component, " ", _name, "\n"});
}
}
protected:
};
@@ -1,7 +1,7 @@
struct Tracer : Object {
DeclareClass(Tracer, "Tracer")
struct Tracer : Debugger {
DeclareClass(Tracer, "debugger.tracer")
Tracer(string name = {}, string component = {}) : Object(name) {
Tracer(string name = {}, string component = {}) : Debugger(name) {
_component = component;
}
@@ -12,13 +12,13 @@ struct Tracer : Object {
auto setEnabled(bool enabled) -> void { _enabled = enabled; }
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
Debugger::serialize(output, depth);
output.append(depth, " component: ", _component, "\n");
output.append(depth, " enabled: ", _enabled, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
Debugger::unserialize(node);
_component = node["component"].string();
_enabled = node["enabled"].boolean();
}
-52
View File
@@ -1,52 +0,0 @@
struct Input : Object {
DeclareClass(Input, "Input")
using Object::Object;
};
struct Button : Input {
DeclareClass(Button, "Button")
using Input::Input;
auto value() const -> boolean { return _value; }
auto setValue(boolean value) -> void { _value = value; }
protected:
boolean _value;
};
struct Axis : Input {
DeclareClass(Axis, "Axis")
using Input::Input;
auto value() const -> integer { return _value; }
auto setValue(integer value) -> void { _value = value; }
protected:
integer _value;
integer _minimum = -32768;
integer _maximum = +32767;
};
struct Trigger : Input {
DeclareClass(Trigger, "Trigger")
using Input::Input;
auto value() const -> integer { return _value; }
auto setValue(integer value) -> void { _value = value; }
protected:
integer _value;
integer _minimum = 0;
integer _maximum = +32767;
};
struct Rumble : Input {
DeclareClass(Rumble, "Rumble")
using Input::Input;
auto enable() const -> boolean { return _enable; }
auto setEnable(boolean enable) -> void { _enable = enable; }
protected:
boolean _enable;
};
+12
View File
@@ -0,0 +1,12 @@
struct Axis : Input {
DeclareClass(Axis, "input.axis")
using Input::Input;
auto value() const -> s64 { return _value; }
auto setValue(s64 value) -> void { _value = value; }
protected:
s64 _value = 0;
s64 _minimum = -32768;
s64 _maximum = +32767;
};
+10
View File
@@ -0,0 +1,10 @@
struct Button : Input {
DeclareClass(Button, "input.button")
using Input::Input;
auto value() const -> bool { return _value; }
auto setValue(bool value) -> void { _value = value; }
protected:
bool _value = 0;
};
+4
View File
@@ -0,0 +1,4 @@
struct Input : Object {
DeclareClass(Input, "input")
using Object::Object;
};
+10
View File
@@ -0,0 +1,10 @@
struct Rumble : Input {
DeclareClass(Rumble, "input.rumble")
using Input::Input;
auto enable() const -> bool { return _enable; }
auto setEnable(bool enable) -> void { _enable = enable; }
protected:
bool _enable = 0;
};
+12
View File
@@ -0,0 +1,12 @@
struct Trigger : Input {
DeclareClass(Trigger, "input.trigger")
using Input::Input;
auto value() const -> s64 { return _value; }
auto setValue(s64 value) -> void { _value = value; }
protected:
s64 _value = 0;
s64 _minimum = 0;
s64 _maximum = +32767;
};
+7 -3
View File
@@ -1,5 +1,9 @@
namespace ares::Core {
#include <ares/node/video/sprite.cpp>
#include <ares/node/video/screen.cpp>
#include <ares/node/audio/stream.cpp>
namespace Video {
#include <ares/node/video/sprite.cpp>
#include <ares/node/video/screen.cpp>
}
namespace Audio {
#include <ares/node/audio/stream.cpp>
}
}
+121 -69
View File
@@ -1,71 +1,97 @@
namespace ares::Core {
struct Object;
struct System;
struct System;
struct Peripheral;
struct Port;
namespace Component {
struct Component;
struct RealTimeClock;
struct Peripheral;
struct Port;
}
namespace Video {
struct Video;
struct Sprite;
struct Screen;
}
namespace Audio {
struct Audio;
struct Stream;
}
namespace Input {
struct Input;
struct Button;
struct Axis;
struct Trigger;
struct Rumble;
struct Settings;
struct Button;
struct Axis;
struct Trigger;
struct Rumble;
}
namespace Setting {
struct Setting;
struct Boolean;
struct Natural;
struct Integer;
struct Real;
struct String;
//struct Video;
struct Sprite;
struct Screen;
//struct Audio;
struct Stream;
//struct Debug;
struct Memory;
struct Graphics;
struct Properties;
struct Boolean;
struct Natural;
struct Integer;
struct Real;
struct String;
}
namespace Debugger {
struct Debugger;
struct Memory;
struct Graphics;
struct Properties;
namespace Tracer {
struct Tracer;
struct Notification;
struct Instruction;
struct Notification;
struct Instruction;
}
}
}
namespace ares::Node {
using Object = shared_pointer<Core::Object>;
using System = shared_pointer<Core::System>;
using Component = shared_pointer<Core::Component>;
using RealTimeClock = shared_pointer<Core::RealTimeClock>;
using Peripheral = shared_pointer<Core::Peripheral>;
using Port = shared_pointer<Core::Port>;
using Input = shared_pointer<Core::Input>;
using Button = shared_pointer<Core::Button>;
using Axis = shared_pointer<Core::Axis>;
using Trigger = shared_pointer<Core::Trigger>;
using Rumble = shared_pointer<Core::Rumble>;
using Settings = shared_pointer<Core::Settings>;
using Setting = shared_pointer<Core::Setting>;
using Boolean = shared_pointer<Core::Boolean>;
using Natural = shared_pointer<Core::Natural>;
using Integer = shared_pointer<Core::Integer>;
using Real = shared_pointer<Core::Real>;
using String = shared_pointer<Core::String>;
//using Video;
using Sprite = shared_pointer<Core::Sprite>;
using Screen = shared_pointer<Core::Screen>;
//using Audio;
using Stream = shared_pointer<Core::Stream>;
//using Debug;
using Memory = shared_pointer<Core::Memory>;
using Graphics = shared_pointer<Core::Graphics>;
using Properties = shared_pointer<Core::Properties>;
using Tracer = shared_pointer<Core::Tracer>;
using Notification = shared_pointer<Core::Notification>;
using Instruction = shared_pointer<Core::Instruction>;
using Object = shared_pointer<Core::Object>;
using System = shared_pointer<Core::System>;
using Peripheral = shared_pointer<Core::Peripheral>;
using Port = shared_pointer<Core::Port>;
namespace Component {
using Component = shared_pointer<Core::Component::Component>;
using RealTimeClock = shared_pointer<Core::Component::RealTimeClock>;
}
namespace Video {
using Video = shared_pointer<Core::Video::Video>;
using Sprite = shared_pointer<Core::Video::Sprite>;
using Screen = shared_pointer<Core::Video::Screen>;
}
namespace Audio {
using Audio = shared_pointer<Core::Audio::Audio>;
using Stream = shared_pointer<Core::Audio::Stream>;
}
namespace Input {
using Input = shared_pointer<Core::Input::Input>;
using Button = shared_pointer<Core::Input::Button>;
using Axis = shared_pointer<Core::Input::Axis>;
using Trigger = shared_pointer<Core::Input::Trigger>;
using Rumble = shared_pointer<Core::Input::Rumble>;
}
namespace Setting {
using Setting = shared_pointer<Core::Setting::Setting>;
using Boolean = shared_pointer<Core::Setting::Boolean>;
using Natural = shared_pointer<Core::Setting::Natural>;
using Integer = shared_pointer<Core::Setting::Integer>;
using Real = shared_pointer<Core::Setting::Real>;
using String = shared_pointer<Core::Setting::String>;
}
namespace Debugger {
using Debugger = shared_pointer<Core::Debugger::Debugger>;
using Memory = shared_pointer<Core::Debugger::Memory>;
using Graphics = shared_pointer<Core::Debugger::Graphics>;
using Properties = shared_pointer<Core::Debugger::Properties>;
namespace Tracer {
using Tracer = shared_pointer<Core::Debugger::Tracer::Tracer>;
using Notification = shared_pointer<Core::Debugger::Tracer::Notification>;
using Instruction = shared_pointer<Core::Debugger::Tracer::Instruction>;
}
}
}
namespace ares::Core {
// <emulator/platform.hpp> forward declarations (dependent on <emulator/node.hpp>)
// <ares/platform.hpp> forward declarations
static auto PlatformAttach(Node::Object) -> void;
static auto PlatformDetach(Node::Object) -> void;
static auto PlatformLog(string_view) -> void;
@@ -74,21 +100,47 @@ namespace ares::Core {
#include <ares/node/class.hpp>
#include <ares/node/object.hpp>
#include <ares/node/system.hpp>
#include <ares/node/component.hpp>
#include <ares/node/real-time-clock.hpp>
#include <ares/node/peripheral.hpp>
#include <ares/node/port.hpp>
#include <ares/node/input.hpp>
#include <ares/node/setting.hpp>
#include <ares/node/video/sprite.hpp>
#include <ares/node/video/screen.hpp>
#include <ares/node/audio/stream.hpp>
#include <ares/node/debug/memory.hpp>
#include <ares/node/debug/graphics.hpp>
#include <ares/node/debug/properties.hpp>
#include <ares/node/debug/tracer.hpp>
#include <ares/node/debug/notification.hpp>
#include <ares/node/debug/instruction.hpp>
namespace Component {
#include <ares/node/component/component.hpp>
#include <ares/node/component/real-time-clock.hpp>
}
namespace Video {
#include <ares/node/video/video.hpp>
#include <ares/node/video/sprite.hpp>
#include <ares/node/video/screen.hpp>
}
namespace Audio {
#include <ares/node/audio/audio.hpp>
#include <ares/node/audio/stream.hpp>
}
namespace Input {
#include <ares/node/input/input.hpp>
#include <ares/node/input/button.hpp>
#include <ares/node/input/axis.hpp>
#include <ares/node/input/trigger.hpp>
#include <ares/node/input/rumble.hpp>
}
namespace Setting {
#include <ares/node/setting/setting.hpp>
#include <ares/node/setting/boolean.hpp>
#include <ares/node/setting/natural.hpp>
#include <ares/node/setting/integer.hpp>
#include <ares/node/setting/real.hpp>
#include <ares/node/setting/string.hpp>
}
namespace Debugger {
#include <ares/node/debugger/debugger.hpp>
#include <ares/node/debugger/memory.hpp>
#include <ares/node/debugger/graphics.hpp>
#include <ares/node/debugger/properties.hpp>
namespace Tracer {
#include <ares/node/debugger/tracer/tracer.hpp>
#include <ares/node/debugger/tracer/notification.hpp>
#include <ares/node/debugger/tracer/instruction.hpp>
}
}
}
namespace ares::Node {
@@ -106,7 +158,7 @@ namespace ares::Node {
static inline auto unserialize(string markup) -> Object {
auto document = BML::unserialize(markup);
if(!document) return {};
auto node = Core::Class::create(document["node"].text());
auto node = Core::Class::create(document["node"].string());
node->unserialize(document["node"]);
return node;
}
+28 -6
View File
@@ -3,12 +3,16 @@
#define DeclareClass(Type, Name) \
static inline const string identifier = Name; \
virtual auto identity() const -> string { return Name; } \
static auto create() -> Node::Object { return new Type; } \
auto identity() const -> string override { return Name; } \
private: static inline Class::Register<Type> register; public: \
struct Object : shared_pointer_this<Object> {
DeclareClass(Object, "Object")
static inline const string identifier = "Object";
static auto create() -> Node::Object { return new Object; }
virtual auto identity() const -> string { return "Object"; }
private: static inline Class::Register<Object> register; public:
//DeclareClass(Object, "object")
Object(string name = {}) : _name(name) {}
virtual ~Object() = default;
@@ -86,7 +90,7 @@ struct Object : shared_pointer_this<Object> {
}
template<typename T>
auto find(uint index) -> shared_pointer<typename T::type> {
auto find(u32 index) -> shared_pointer<typename T::type> {
auto result = find<T>();
if(index < result.size()) return result[index];
return {};
@@ -130,6 +134,15 @@ struct Object : shared_pointer_this<Object> {
for(auto& node : _nodes) node->enumerate<T>(objects);
}
auto pak() -> VFS::Pak {
return _pak;
}
auto setPak(VFS::Pak pak) -> bool {
_pak = pak;
return (bool)_pak;
}
template<typename T = string>
auto attribute(const string& name) const -> T {
if(auto attribute = _attributes.find(name)) {
@@ -138,6 +151,14 @@ struct Object : shared_pointer_this<Object> {
return {};
}
template<typename T = string>
auto hasAttribute(const string& name) const -> bool {
if(auto attribute = _attributes.find(name)) {
if(attribute->value.is<T>()) return true;
}
return false;
}
template<typename T = string, typename U = string>
auto setAttribute(const string& name, const U& value = {}) -> void {
if constexpr(is_same_v<T, string> && !is_same_v<U, string>) return setAttribute(name, string{value});
@@ -178,13 +199,13 @@ struct Object : shared_pointer_this<Object> {
virtual auto unserialize(Markup::Node markup) -> void {
if(!markup) return;
_name = markup["name"].text();
_name = markup["name"].string();
_attributes.reset();
for(auto& attribute : markup.find("attribute")) {
_attributes.insert({attribute["name"].text(), attribute["value"].text()});
_attributes.insert({attribute["name"].string(), attribute["value"].string()});
}
for(auto& leaf : markup.find("node")) {
auto node = Class::create(leaf.text());
auto node = Class::create(leaf.string());
append(node);
node->unserialize(leaf);
}
@@ -207,6 +228,7 @@ struct Object : shared_pointer_this<Object> {
protected:
string _name;
VFS::Pak _pak;
set<Attribute> _attributes;
shared_pointer_weak<Object> _parent;
vector<Node::Object> _nodes;
+1 -8
View File
@@ -1,11 +1,4 @@
struct Peripheral : Object {
DeclareClass(Peripheral, "Peripheral")
DeclareClass(Peripheral, "peripheral")
using Object::Object;
auto manifest() -> string { if(_manifest) return _manifest(); return {}; }
auto setManifest(function<string()> manifest) -> void { _manifest = manifest; }
protected:
function<string ()> _manifest;
};
+1 -1
View File
@@ -1,5 +1,5 @@
struct Port : Object {
DeclareClass(Port, "Port")
DeclareClass(Port, "port")
using Object::Object;
auto type() const -> string { return _type; }
-30
View File
@@ -1,30 +0,0 @@
struct RealTimeClock : Object {
DeclareClass(RealTimeClock, "Real Time Clock")
using Object::Object;
auto update() -> void { if(_update) return _update(); }
auto timestamp() const -> uint64 { return _timestamp; }
auto setUpdate(function<void ()> update) { _update = update; }
auto setTimestamp(uint64 timestamp) -> void { _timestamp = timestamp; }
auto synchronize(uint64 timestamp = 0) -> void {
if(!timestamp) timestamp = chrono::timestamp();
_timestamp = timestamp;
update();
}
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
output.append(depth, " timestamp: ", _timestamp, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
_timestamp = node["timestamp"].natural();
}
protected:
function<void ()> _update;
uint64 _timestamp;
};
-192
View File
@@ -1,192 +0,0 @@
struct Settings : Object {
DeclareClass(Settings, "Settings")
using Object::Object;
};
struct Setting : Object {
DeclareClass(Setting, "Setting")
using Object::Object;
auto dynamic() const -> bool { return _dynamic; }
auto setDynamic(bool dynamic) -> void {
_dynamic = dynamic;
}
virtual auto setLatch() -> void {}
virtual auto readValue() const -> string { return {}; }
virtual auto readLatch() const -> string { return {}; }
virtual auto readAllowedValues() const -> vector<string> { return {}; }
virtual auto writeValue(string value) -> void {}
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
output.append(depth, " dynamic: ", _dynamic, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
_dynamic = node["dynamic"].boolean();
}
protected:
bool _dynamic = false;
};
template<typename Cast, typename Type> struct Abstract : Setting {
using Setting::Setting;
Abstract(string name = {}, Type value = {}, function<void (Type)> modify = {}) : Setting(name), _defaultValue(value) {
_currentValue = value;
_latchedValue = value;
if constexpr(is_same_v<Type, boolean>) _allowedValues = {false, true};
_modify = modify;
}
auto modify(Type value) const -> void { if(_modify) return _modify(value); }
auto value() const -> Type { return _currentValue; }
auto latch() const -> Type { return _latchedValue; }
auto setModify(function<void (Type)> modify) {
_modify = modify;
}
auto setValue(Type value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) _latchedValue = _currentValue;
modify(value);
}
auto setLatch() -> void override {
_latchedValue = _currentValue;
}
auto setAllowedValues(vector<Type> allowedValues) -> void {
_allowedValues = allowedValues;
//if the current setting isn't an allowed value, change it to the first allowed value
if(_allowedValues && !_allowedValues.find(_currentValue)) {
_currentValue = _allowedValues.first();
_latchedValue = _currentValue;
}
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override {
vector<string> values;
for(auto& value : _allowedValues) values.append(value);
return values;
}
auto writeValue(string value) -> void override {
if(_allowedValues && !readAllowedValues().find(value)) return;
if constexpr(is_same_v<Type, boolean>) _currentValue = value.boolean();
if constexpr(is_same_v<Type, natural>) _currentValue = value.natural();
if constexpr(is_same_v<Type, integer>) _currentValue = value.integer();
if constexpr(is_same_v<Type, real >) _currentValue = value.real();
if constexpr(is_same_v<Type, string >) _currentValue = value;
if(_dynamic) _latchedValue = _currentValue;
modify(_currentValue);
}
auto load(Node::Object source) -> bool override {
if(!Setting::load(source)) return false;
if(auto setting = source->cast<shared_pointer<Cast>>()) {
if(!_allowedValues || _allowedValues.find(setting->_currentValue)) {
_currentValue = setting->_currentValue;
_latchedValue = _currentValue;
modify(_currentValue);
}
}
return true;
}
auto serialize(string& output, string depth) -> void override {
Setting::serialize(output, depth);
output.append(depth, " value: ", _currentValue, "\n");
if(_latchedValue) output.append(depth, " latch: ", _latchedValue, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Setting::unserialize(node);
if constexpr(is_same_v<Type, boolean>) _currentValue = node["value"].boolean(), _latchedValue = node["latch"].boolean();
if constexpr(is_same_v<Type, natural>) _currentValue = node["value"].natural(), _latchedValue = node["latch"].natural();
if constexpr(is_same_v<Type, integer>) _currentValue = node["value"].integer(), _latchedValue = node["latch"].integer();
if constexpr(is_same_v<Type, real>) _currentValue = node["value"].real(), _latchedValue = node["latch"].real();
if constexpr(is_same_v<Type, string>) _currentValue = node["value"].text(), _latchedValue = node["latch"].text();
}
protected:
function<void (Type)> _modify;
const Type _defaultValue;
Type _currentValue;
Type _latchedValue;
vector<Type> _allowedValues;
};
struct Boolean : Abstract<Boolean, boolean> {
DeclareClass(Boolean, "Boolean")
using Abstract::Abstract;
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::Boolean>()) {
Object::copy(source);
setValue(source->value());
setLatch();
}
}
};
struct Natural : Abstract<Natural, natural> {
DeclareClass(Natural, "Natural")
using Abstract::Abstract;
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::Natural>()) {
Object::copy(source);
setValue(source->value());
setLatch();
}
}
};
struct Integer : Abstract<Integer, integer> {
DeclareClass(Integer, "Integer")
using Abstract::Abstract;
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::Integer>()) {
Object::copy(source);
setValue(source->value());
setLatch();
}
}
};
struct Real : Abstract<Real, real> {
DeclareClass(Real, "Real")
using Abstract::Abstract;
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::Real>()) {
Object::copy(source);
setValue(source->value());
setLatch();
}
}
};
struct String : Abstract<String, string> {
DeclareClass(String, "String")
using Abstract::Abstract;
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::String>()) {
Object::copy(source);
setValue(source->value());
setLatch();
}
}
};
+36
View File
@@ -0,0 +1,36 @@
struct Boolean : Setting {
DeclareClass(Boolean, "setting.boolean")
Boolean(string name = {}, bool value = {}, function<void (bool)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(bool value) const -> void { if(_modify) return _modify(value); }
auto value() const -> bool { return _currentValue; }
auto latch() const -> bool { return _latchedValue; }
auto setModify(function<void (bool)> modify) { _modify = modify; }
auto setValue(bool value) -> void {
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override { return {"false", "true"}; }
auto writeValue(string value) -> void override { setValue(value.boolean()); }
protected:
function<void (bool)> _modify;
bool _currentValue = {};
bool _latchedValue = {};
};
+47
View File
@@ -0,0 +1,47 @@
struct Integer : Setting {
DeclareClass(Integer, "setting.integer")
Integer(string name = {}, s64 value = {}, function<void (s64)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(s64 value) const -> void { if(_modify) return _modify(value); }
auto value() const -> s64 { return _currentValue; }
auto latch() const -> s64 { return _latchedValue; }
auto setModify(function<void (s64)> modify) { _modify = modify; }
auto setValue(s64 value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<s64> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override {
vector<string> values;
for(auto value : _allowedValues) values.append(value);
return values;
}
auto writeValue(string value) -> void override { setValue(value.integer()); }
protected:
function<void (s64)> _modify;
s64 _currentValue = {};
s64 _latchedValue = {};
vector<s64> _allowedValues;
};
+47
View File
@@ -0,0 +1,47 @@
struct Natural : Setting {
DeclareClass(Natural, "setting.natural")
Natural(string name = {}, u64 value = {}, function<void (u64)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(u64 value) const -> void { if(_modify) return _modify(value); }
auto value() const -> u64 { return _currentValue; }
auto latch() const -> u64 { return _latchedValue; }
auto setModify(function<void (u64)> modify) { _modify = modify; }
auto setValue(u64 value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<u64> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override {
vector<string> values;
for(auto value : _allowedValues) values.append(value);
return values;
}
auto writeValue(string value) -> void override { setValue(value.natural()); }
protected:
function<void (u64)> _modify;
u64 _currentValue = {};
u64 _latchedValue = {};
vector<u64> _allowedValues;
};
+47
View File
@@ -0,0 +1,47 @@
struct Real : Setting {
DeclareClass(Real, "setting.real")
Real(string name = {}, f64 value = {}, function<void (f64)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(f64 value) const -> void { if(_modify) return _modify(value); }
auto value() const -> f64 { return _currentValue; }
auto latch() const -> f64 { return _latchedValue; }
auto setModify(function<void (f64)> modify) { _modify = modify; }
auto setValue(f64 value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<f64> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override {
vector<string> values;
for(auto value : _allowedValues) values.append(value);
return values;
}
auto writeValue(string value) -> void override { setValue(value.real()); }
protected:
function<void (f64)> _modify;
f64 _currentValue = {};
f64 _latchedValue = {};
vector<f64> _allowedValues;
};
+46
View File
@@ -0,0 +1,46 @@
struct Setting : Object {
DeclareClass(Setting, "setting")
using Object::Object;
auto dynamic() const -> bool { return _dynamic; }
auto setDynamic(bool dynamic) -> void {
_dynamic = dynamic;
}
virtual auto setLatch() -> void {}
virtual auto readValue() const -> string { return {}; }
virtual auto readLatch() const -> string { return {}; }
virtual auto readAllowedValues() const -> vector<string> { return {}; }
virtual auto writeValue(string value) -> void {}
auto load(Node::Object source) -> bool override {
if(!Object::load(source)) return false;
if(auto setting = source->cast<shared_pointer<Setting>>()) writeValue(setting->readValue());
return true;
}
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::Setting::Setting>()) {
Object::copy(source);
writeValue(source->readValue());
setLatch();
}
}
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
output.append(depth, " dynamic: ", _dynamic, "\n");
output.append(depth, " value: ", readValue(), "\n");
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
_dynamic = node["dynamic"].boolean();
writeValue(node["value"].string());
}
protected:
bool _dynamic = false;
};
+43
View File
@@ -0,0 +1,43 @@
struct String : Setting {
DeclareClass(String, "setting.string")
String(string name = {}, string value = {}, function<void (string)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(string value) const -> void { if(_modify) return _modify(value); }
auto value() const -> string { return _currentValue; }
auto latch() const -> string { return _latchedValue; }
auto setModify(function<void (string)> modify) { _modify = modify; }
auto setValue(string value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<string> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override { return _allowedValues; }
auto writeValue(string value) -> void override { setValue(value); }
protected:
function<void (string)> _modify;
string _currentValue = {};
string _latchedValue = {};
vector<string> _allowedValues;
};
+26 -1
View File
@@ -1,4 +1,29 @@
struct System : Object {
DeclareClass(System, "System")
DeclareClass(System, "system")
using Object::Object;
auto game() -> string { if(_game) return _game(); return {}; }
auto run() -> void { if(_run) return _run(); }
auto power(bool reset = false) -> void { if(_power) return _power(reset); }
auto save() -> void { if(_save) return _save(); }
auto unload() -> void { if(_unload) return _unload(); }
auto serialize(bool synchronize = true) -> serializer { if(_serialize) return _serialize(synchronize); return {}; }
auto unserialize(serializer& s) -> bool { if(_unserialize) return _unserialize(s); return false; }
auto setGame(function<string ()> game) -> void { _game = game; }
auto setRun(function<void ()> run) -> void { _run = run; }
auto setPower(function<void (bool)> power) -> void { _power = power; }
auto setSave(function<void ()> save) -> void { _save = save; }
auto setUnload(function<void ()> unload) -> void { _unload = unload; }
auto setSerialize(function<serializer (bool)> serialize) -> void { _serialize = serialize; }
auto setUnserialize(function<bool (serializer&)> unserialize) -> void { _unserialize = unserialize; }
protected:
function<string ()> _game;
function<void ()> _run;
function<void (bool)> _power;
function<void ()> _save;
function<void ()> _unload;
function<serializer (bool)> _serialize;
function<bool (serializer&)> _unserialize;
};
+257 -79
View File
@@ -1,106 +1,237 @@
Screen::Screen(string name, u32 width, u32 height) : Video(name) {
_canvasWidth = width;
_canvasHeight = height;
if(width && height) {
_inputA = new u32[width * height]();
_inputB = new u32[width * height]();
_output = new u32[width * height]();
_rotate = new u32[width * height]();
if constexpr(ares::Video::Threaded) {
_thread = nall::thread::create({&Screen::main, this});
}
}
}
Screen::~Screen() {
if constexpr(ares::Video::Threaded) {
if(_canvasWidth && _canvasHeight) {
_kill = true;
_thread.join();
}
}
}
auto Screen::main(uintptr_t) -> void {
while(!_kill) {
usleep(1);
if(_frame) {
refresh();
_frame = false;
}
}
}
auto Screen::quit() -> void {
_kill = true;
_thread.join();
}
auto Screen::power() -> void {
lock_guard<recursive_mutex> lock(_mutex);
memory::fill<u32>(_inputA.data(), _canvasWidth * _canvasHeight, _fillColor);
memory::fill<u32>(_inputB.data(), _canvasWidth * _canvasHeight, _fillColor);
memory::fill<u32>(_output.data(), _canvasWidth * _canvasHeight, _fillColor);
memory::fill<u32>(_rotate.data(), _canvasWidth * _canvasHeight, _fillColor);
}
auto Screen::pixels(bool frame) -> array_span<u32> {
if(frame == 0) return {_inputA.data(), _canvasWidth * _canvasHeight};
if(frame == 1) return {_inputB.data(), _canvasWidth * _canvasHeight};
return {};
}
auto Screen::resetPalette() -> void {
lock_guard<recursive_mutex> lock(_mutex);
_palette.reset();
}
auto Screen::resetSprites() -> void {
lock_guard<recursive_mutex> lock(_mutex);
_sprites.reset();
}
auto Screen::attach(Node::Sprite sprite) -> void {
auto Screen::setRefresh(function<void ()> refresh) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_refresh = refresh;
}
auto Screen::setViewport(u32 x, u32 y, u32 width, u32 height) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_viewportX = x;
_viewportY = y;
_viewportWidth = width;
_viewportHeight = height;
}
auto Screen::setSize(u32 width, u32 height) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_width = width;
_height = height;
}
auto Screen::setScale(f64 scaleX, f64 scaleY) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_scaleX = scaleX;
_scaleY = scaleY;
}
auto Screen::setAspect(f64 aspectX, f64 aspectY) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_aspectX = aspectX;
_aspectY = aspectY;
}
auto Screen::setSaturation(f64 saturation) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_saturation = saturation;
_palette.reset();
}
auto Screen::setGamma(f64 gamma) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_gamma = gamma;
_palette.reset();
}
auto Screen::setLuminance(f64 luminance) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_luminance = luminance;
_palette.reset();
}
auto Screen::setFillColor(u32 fillColor) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_fillColor = fillColor;
}
auto Screen::setColorBleed(bool colorBleed) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colorBleed = colorBleed;
}
auto Screen::setInterframeBlending(bool interframeBlending) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_interframeBlending = interframeBlending;
}
auto Screen::setRotation(u32 rotation) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_rotation = rotation;
}
auto Screen::setProgressive(bool progressiveDouble) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_interlace = false;
_progressive = true;
_progressiveDouble = progressiveDouble;
}
auto Screen::setInterlace(bool interlaceField) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_progressive = false;
_interlace = true;
_interlaceField = interlaceField;
}
auto Screen::attach(Node::Video::Sprite sprite) -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(_sprites.find(sprite)) return;
_sprites.append(sprite);
}
auto Screen::detach(Node::Sprite sprite) -> void {
auto Screen::detach(Node::Video::Sprite sprite) -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(!_sprites.find(sprite)) return;
_sprites.removeByValue(sprite);
}
auto Screen::colors(uint colors, function<uint64 (uint32)> color) -> void {
auto Screen::colors(u32 colors, function<n64 (n32)> color) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colors = colors;
_color = color;
_palette.reset();
}
auto Screen::refresh(uint32* input, uint pitch, uint width, uint height) -> void {
auto Screen::frame() -> void {
if(runAhead()) return;
while(_frame) spinloop();
lock_guard<recursive_mutex> lock(_mutex);
_inputA.swap(_inputB);
_frame = true;
if constexpr(!ares::Video::Threaded) {
refresh();
_frame = false;
}
}
auto Screen::refresh() -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(runAhead()) return;
//allocate the screen buffers (only when growing)
if(_renderWidth != width || _renderHeight != height) {
if(_renderWidth * _renderHeight < width * height) {
_buffer = new uint32[width * height];
_rotate = new uint32[width * height];
}
}
refreshPalette();
if(_refresh) _refresh();
//generate the color lookup palettes to convert native colors to ARGB8888
if(!_palette) {
_palette = new uint32[_colors];
for(uint index : range(_colors)) {
uint64 color = _color(index);
uint16 b = color.bit( 0,15);
uint16 g = color.bit(16,31);
uint16 r = color.bit(32,47);
uint16 a = 65535;
auto viewX = _viewportX;
auto viewY = _viewportY;
auto viewWidth = _viewportWidth;
auto viewHeight = _viewportHeight;
if(_saturation != 1.0) {
uint16 grayscale = uclamp<16>((r + g + b) / 3);
double inverse = max(0.0, 1.0 - _saturation);
r = uclamp<16>(r * _saturation + grayscale * inverse);
g = uclamp<16>(g * _saturation + grayscale * inverse);
b = uclamp<16>(b * _saturation + grayscale * inverse);
}
auto pitch = _canvasWidth;
auto width = _canvasWidth;
auto height = _canvasHeight;
auto input = _inputB.data();
auto output = _output.data();
if(_gamma != 1.0) {
double reciprocal = 1.0 / 32767.0;
r = r > 32767 ? r : uint16(32767 * pow(r * reciprocal, _gamma));
g = g > 32767 ? g : uint16(32767 * pow(g * reciprocal, _gamma));
b = b > 32767 ? b : uint16(32767 * pow(b * reciprocal, _gamma));
}
if(_luminance != 1.0) {
r = uclamp<16>(r * _luminance);
g = uclamp<16>(g * _luminance);
b = uclamp<16>(b * _luminance);
}
a >>= 8;
r >>= 8;
g >>= 8;
b >>= 8;
_palette[index] = a << 24 | r << 16 | g << 8 | b << 0;
}
}
auto output = _buffer.data();
pitch >>= 2; //bytes to words
for(uint y : range(height)) {
auto source = input + y * pitch;
for(u32 y : range(height)) {
auto source = input + y * pitch;
auto target = output + y * width;
//if not blending, or if previous frame resolution was different, render normally
if(!_interframeBlending || width != _renderWidth || height != _renderHeight) {
for(uint x : range(width)) {
if(_interlace) {
if((_interlaceField & 1) == (y & 1)) {
for(u32 x : range(width)) {
auto color = _palette[*source++];
*target++ = color;
}
}
} else if(_progressive && _progressiveDouble) {
source = input + (y & ~1) * pitch;
for(u32 x : range(width)) {
auto color = _palette[*source++];
*target++ = color;
}
} else {
uint32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 0;
for(uint x : range(width)) {
} else if(_interframeBlending) {
n32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 0;
for(u32 x : range(width)) {
auto a = *target;
auto b = _palette[*source++];
*target++ = (a + b - ((a ^ b) & mask)) >> 1;
}
} else {
for(u32 x : range(width)) {
auto color = _palette[*source++];
*target++ = color;
}
}
}
if(_colorBleed) {
uint32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 9;
for(uint y : range(height)) {
n32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 0;
for(u32 y : range(height)) {
auto target = output + y * width;
for(uint x : range(width)) {
for(u32 x : range(width)) {
auto a = target[x];
auto b = target[x + (x != width - 1)];
target[x] = (a + b - ((a ^ b) & mask)) >> 1;
@@ -111,15 +242,15 @@ auto Screen::refresh(uint32* input, uint pitch, uint width, uint height) -> void
for(auto& sprite : _sprites) {
if(!sprite->visible()) continue;
uint32 alpha = 255u << 24;
n32 alpha = 255u << 24;
for(int y : range(sprite->height())) {
int pixelY = sprite->y() + y;
s32 pixelY = sprite->y() + y;
if(pixelY < 0 || pixelY >= height) continue;
auto source = sprite->image() + y * sprite->width();
auto source = sprite->image().data() + y * sprite->width();
auto target = &output[pixelY * width];
for(int x : range(sprite->width())) {
int pixelX = sprite->x() + x;
for(s32 x : range(sprite->width())) {
s32 pixelX = sprite->x() + x;
if(pixelX < 0 || pixelX >= width) continue;
auto pixel = source[x];
@@ -130,22 +261,23 @@ auto Screen::refresh(uint32* input, uint pitch, uint width, uint height) -> void
if(_rotation == 90) {
//rotate left
for(uint y : range(height)) {
for(u32 y : range(height)) {
auto source = output + y * width;
for(uint x : range(width)) {
for(u32 x : range(width)) {
auto target = _rotate.data() + (width - 1 - x) * height + y;
*target = *source++;
}
}
output = _rotate.data();
swap(width, height);
swap(viewWidth, viewHeight);
}
if(_rotation == 180) {
//rotate upside down
for(uint y : range(height)) {
for(u32 y : range(height)) {
auto source = output + y * width;
for(uint x : range(width)) {
for(u32 x : range(width)) {
auto target = _rotate.data() + (height - 1 - y) * width + (width - 1 - x);
*target = *source++;
}
@@ -155,25 +287,67 @@ auto Screen::refresh(uint32* input, uint pitch, uint width, uint height) -> void
if(_rotation == 270) {
//rotate right
for(uint y : range(height)) {
for(u32 y : range(height)) {
auto source = output + y * width;
for(uint x : range(width)) {
for(u32 x : range(width)) {
auto target = _rotate.data() + x * height + (height - 1 - y);
*target = *source++;
}
}
output = _rotate.data();
swap(width, height);
swap(viewWidth, viewHeight);
}
platform->video(shared(), (const uint32_t*)output, width * sizeof(uint32), width, height);
platform->video(shared(), output + viewX + viewY * width, width * sizeof(u32), viewWidth, viewHeight);
memory::fill<u32>(_inputB.data(), width * height, _fillColor);
}
_renderWidth = width;
_renderHeight = height;
auto Screen::refreshPalette() -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(_palette) return;
//generate the color lookup palettes to convert native colors to ARGB8888
_palette = new u32[_colors];
for(u32 index : range(_colors)) {
n64 color = _color(index);
n16 b = color.bit( 0,15);
n16 g = color.bit(16,31);
n16 r = color.bit(32,47);
n16 a = 65535;
if(_saturation != 1.0) {
n16 grayscale = uclamp<16>((r + g + b) / 3);
f64 inverse = max(0.0, 1.0 - _saturation);
r = uclamp<16>(r * _saturation + grayscale * inverse);
g = uclamp<16>(g * _saturation + grayscale * inverse);
b = uclamp<16>(b * _saturation + grayscale * inverse);
}
if(_gamma != 1.0) {
f64 reciprocal = 1.0 / 32767.0;
r = r > 32767 ? r : n16(32767 * pow(r * reciprocal, _gamma));
g = g > 32767 ? g : n16(32767 * pow(g * reciprocal, _gamma));
b = b > 32767 ? b : n16(32767 * pow(b * reciprocal, _gamma));
}
if(_luminance != 1.0) {
r = uclamp<16>(r * _luminance);
g = uclamp<16>(g * _luminance);
b = uclamp<16>(b * _luminance);
}
a >>= 8;
r >>= 8;
g >>= 8;
b >>= 8;
_palette[index] = a << 24 | r << 16 | g << 8 | b << 0;
}
}
auto Screen::serialize(string& output, string depth) -> void {
Object::serialize(output, depth);
Video::serialize(output, depth);
output.append(depth, " width: ", _width, "\n");
output.append(depth, " height: ", _height, "\n");
output.append(depth, " scaleX: ", _scaleX, "\n");
@@ -184,13 +358,15 @@ auto Screen::serialize(string& output, string depth) -> void {
output.append(depth, " saturation: ", _saturation, "\n");
output.append(depth, " gamma: ", _gamma, "\n");
output.append(depth, " luminance: ", _luminance, "\n");
output.append(depth, " fillColor: ", _fillColor, "\n");
output.append(depth, " colorBleed: ", _colorBleed, "\n");
output.append(depth, " interlace: ", _interlace, "\n");
output.append(depth, " interframeBlending: ", _interframeBlending, "\n");
output.append(depth, " rotation: ", _rotation, "\n");
}
auto Screen::unserialize(Markup::Node node) -> void {
Object::unserialize(node);
Video::unserialize(node);
_width = node["width"].natural();
_height = node["height"].natural();
_scaleX = node["scaleX"].real();
@@ -201,7 +377,9 @@ auto Screen::unserialize(Markup::Node node) -> void {
_saturation = node["saturation"].real();
_gamma = node["gamma"].real();
_luminance = node["luminance"].real();
_fillColor = node["fillColor"].natural();
_colorBleed = node["colorBleed"].boolean();
_interlace = node["interlace"].natural();
_interframeBlending = node["interframeBlending"].boolean();
_rotation = node["rotation"].natural();
resetPalette();
+80 -42
View File
@@ -1,68 +1,106 @@
struct Screen : Object {
DeclareClass(Screen, "Screen")
using Object::Object;
struct Screen : Video {
DeclareClass(Screen, "video.screen")
using Video::Video;
auto width() const -> uint { return _width; }
auto height() const -> uint { return _height; }
auto scaleX() const -> double { return _scaleX; }
auto scaleY() const -> double { return _scaleY; }
auto aspectX() const -> double { return _aspectX; }
auto aspectY() const -> double { return _aspectY; }
auto colors() const -> uint { return _colors; }
Screen(string name = {}, u32 width = 0, u32 height = 0);
~Screen();
auto main(uintptr_t) -> void;
auto quit() -> void;
auto power() -> void;
auto canvasWidth() const -> u32 { return _canvasWidth; }
auto canvasHeight() const -> u32 { return _canvasHeight; }
auto width() const -> u32 { return _width; }
auto height() const -> u32 { return _height; }
auto scaleX() const -> f64 { return _scaleX; }
auto scaleY() const -> f64 { return _scaleY; }
auto aspectX() const -> f64 { return _aspectX; }
auto aspectY() const -> f64 { return _aspectY; }
auto colors() const -> u32 { return _colors; }
auto pixels(bool frame = 0) -> array_span<u32>;
auto saturation() const -> double { return _saturation; }
auto gamma() const -> double { return _gamma; }
auto luminance() const -> double { return _luminance; }
auto fillColor() const -> u32 { return _fillColor; }
auto colorBleed() const -> bool { return _colorBleed; }
auto interframeBlending() const -> bool { return _interframeBlending; }
auto rotation() const -> uint { return _rotation; }
auto rotation() const -> u32 { return _rotation; }
auto resetPalette() -> void;
auto resetSprites() -> void;
auto setSize(uint width, uint height) -> void { _width = width, _height = height; }
auto setScale(double scaleX, double scaleY) -> void { _scaleX = scaleX, _scaleY = scaleY; }
auto setAspect(double aspectX, double aspectY) -> void { _aspectX = aspectX, _aspectY = aspectY; }
auto setRefresh(function<void ()> refresh) -> void;
auto setViewport(u32 x, u32 y, u32 width, u32 height) -> void;
auto setSaturation(double saturation) -> void { _saturation = saturation; _palette.reset(); }
auto setGamma(double gamma) -> void { _gamma = gamma; _palette.reset(); }
auto setLuminance(double luminance) -> void { _luminance = luminance; _palette.reset(); }
auto setSize(u32 width, u32 height) -> void;
auto setScale(f64 scaleX, f64 scaleY) -> void;
auto setAspect(f64 aspectX, f64 aspectY) -> void;
auto setColorBleed(bool colorBleed) -> void { _colorBleed = colorBleed; }
auto setInterframeBlending(bool interframeBlending) -> void { _interframeBlending = interframeBlending; }
auto setRotation(uint rotation) -> void { _rotation = rotation; }
auto setSaturation(f64 saturation) -> void;
auto setGamma(f64 gamma) -> void;
auto setLuminance(f64 luminance) -> void;
auto attach(Node::Sprite) -> void;
auto detach(Node::Sprite) -> void;
auto setFillColor(u32 fillColor) -> void;
auto setColorBleed(bool colorBleed) -> void;
auto setInterframeBlending(bool interframeBlending) -> void;
auto setRotation(u32 rotation) -> void;
auto colors(uint colors, function<uint64 (uint32)> color) -> void;
auto refresh(uint32* input, uint pitch, uint width, uint height) -> void;
auto setProgressive(bool progressiveDouble = false) -> void;
auto setInterlace(bool interlaceField) -> void;
auto attach(Node::Video::Sprite) -> void;
auto detach(Node::Video::Sprite) -> void;
auto colors(u32 colors, function<n64 (n32)> color) -> void;
auto frame() -> void;
auto refresh() -> void;
auto serialize(string& output, string depth) -> void override;
auto unserialize(Markup::Node node) -> void override;
private:
auto refreshPalette() -> void;
protected:
uint _width = 0;
uint _height = 0;
double _scaleX = 1.0;
double _scaleY = 1.0;
double _aspectX = 1.0;
double _aspectY = 1.0;
uint _colors = 0;
double _saturation = 1.0;
double _gamma = 1.0;
double _luminance = 1.0;
u32 _canvasWidth = 0;
u32 _canvasHeight = 0;
u32 _width = 0;
u32 _height = 0;
f64 _scaleX = 1.0;
f64 _scaleY = 1.0;
f64 _aspectX = 1.0;
f64 _aspectY = 1.0;
u32 _colors = 0;
f64 _saturation = 1.0;
f64 _gamma = 1.0;
f64 _luminance = 1.0;
u32 _fillColor = 0;
bool _colorBleed = false;
bool _interframeBlending = false;
uint _rotation = 0; //counter-clockwise (90 = left, 270 = right)
u32 _rotation = 0; //counter-clockwise (90 = left, 270 = right)
function<uint64 (uint32)> _color;
unique_pointer<uint32[]> _buffer;
unique_pointer<uint32[]> _rotate;
unique_pointer<uint32[]> _palette;
vector<Node::Sprite> _sprites;
function<n64 (n32)> _color;
unique_pointer<u32> _inputA;
unique_pointer<u32> _inputB;
unique_pointer<u32> _output;
unique_pointer<u32> _rotate;
unique_pointer<u32[]> _palette;
vector<Node::Video::Sprite> _sprites;
uint _renderWidth = 0;
uint _renderHeight = 0;
//unserialized:
nall::thread _thread;
recursive_mutex _mutex;
atomic<bool> _kill = false;
atomic<bool> _frame = false;
function<void ()> _refresh;
bool _progressive = false;
bool _progressiveDouble = false;
bool _interlace = false;
bool _interlaceField = false;
u32 _viewportX = 0;
u32 _viewportY = 0;
u32 _viewportWidth = 0;
u32 _viewportHeight = 0;
};
+5 -5
View File
@@ -2,7 +2,7 @@ auto Sprite::setVisible(bool visible) -> void {
_visible = visible;
}
auto Sprite::setPosition(uint x, uint y) -> void {
auto Sprite::setPosition(u32 x, u32 y) -> void {
_x = x;
_y = y;
}
@@ -10,14 +10,14 @@ auto Sprite::setPosition(uint x, uint y) -> void {
auto Sprite::setImage(nall::image image, bool invert) -> void {
_width = image.width();
_height = image.height();
_pixels = new uint32[_width * _height];
_pixels = new u32[_width * _height];
image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
memory::copy(_pixels.data(), _width * _height * sizeof(uint32), image.data(), image.size());
memory::copy(_pixels.data(), _width * _height * sizeof(u32), image.data(), image.size());
if(!invert) return;
for(uint y : range(_height)) {
for(u32 y : range(_height)) {
auto data = _pixels.data() + y * _width;
for(uint x : range(_width)) {
for(u32 x : range(_width)) {
auto pixel = data[x];
pixel ^= 0xffffff;
data[x] = pixel;
+14 -14
View File
@@ -1,23 +1,23 @@
struct Sprite : Object {
DeclareClass(Sprite, "Sprite")
using Object::Object;
struct Sprite : Video {
DeclareClass(Sprite, "video.sprite")
using Video::Video;
auto visible() const -> bool { return _visible; }
auto x() const -> uint { return _x; }
auto y() const -> uint { return _y; }
auto width() const -> uint { return _width; }
auto height() const -> uint { return _height; }
auto image() const -> const uint32* { return _pixels.data(); }
auto x() const -> u32 { return _x; }
auto y() const -> u32 { return _y; }
auto width() const -> u32 { return _width; }
auto height() const -> u32 { return _height; }
auto image() const -> array_view<u32> { return {_pixels.data(), _width * _height}; }
auto setVisible(bool visible) -> void;
auto setPosition(uint x, uint y) -> void;
auto setPosition(u32 x, u32 y) -> void;
auto setImage(nall::image, bool invert = false) -> void;
protected:
bool _visible = false;
uint _x = 0;
uint _y = 0;
uint _width = 0;
uint _height = 0;
unique_pointer<uint32[]> _pixels;
u32 _x = 0;
u32 _y = 0;
u32 _width = 0;
u32 _height = 0;
unique_pointer<u32[]> _pixels;
};
+4
View File
@@ -0,0 +1,4 @@
struct Video : Object {
DeclareClass(Video, "video");
using Object::Object;
};
+6 -5
View File
@@ -2,7 +2,7 @@
namespace ares {
enum class Event : uint {
enum class Event : u32 {
None,
Step,
Frame,
@@ -13,12 +13,12 @@ enum class Event : uint {
struct Platform {
virtual auto attach(Node::Object) -> void {}
virtual auto detach(Node::Object) -> void {}
virtual auto open(Node::Object, string name, vfs::file::mode mode, bool required = false) -> shared_pointer<vfs::file> { return {}; }
virtual auto pak(Node::Object) -> shared_pointer<vfs::directory> { return {}; }
virtual auto event(Event) -> void {}
virtual auto log(string_view message) -> void {}
virtual auto video(Node::Screen, const uint32_t* data, uint pitch, uint width, uint height) -> void {}
virtual auto audio(Node::Stream) -> void {}
virtual auto input(Node::Input) -> void {}
virtual auto video(Node::Video::Screen, const u32* data, u32 pitch, u32 width, u32 height) -> void {}
virtual auto audio(Node::Audio::Stream) -> void {}
virtual auto input(Node::Input::Input) -> void {}
};
extern Platform* platform;
@@ -26,6 +26,7 @@ extern Platform* platform;
}
namespace ares::Core {
// <ares/node/node.hpp> forward declarations
auto PlatformAttach(Node::Object node) -> void { if(platform && node->name()) platform->attach(node); }
auto PlatformDetach(Node::Object node) -> void { if(platform && node->name()) platform->detach(node); }
auto PlatformLog(string_view text) -> void { if(platform) platform->log(text); }
+30 -30
View File
@@ -3,9 +3,9 @@
namespace ares {
struct Random {
enum class Entropy : uint { None, Low, High };
enum class Entropy : u32 { None, Low, High };
auto operator()() -> uint64 {
auto operator()() -> n64 {
return random();
}
@@ -14,8 +14,8 @@ struct Random {
seed();
}
auto seed(maybe<uint32> seed = nothing, maybe<uint32> sequence = nothing) -> void {
if(!seed) seed = (uint32)clock();
auto seed(maybe<n32> seed = nothing, maybe<n32> sequence = nothing) -> void {
if(!seed) seed = (n32)clock();
if(!sequence) sequence = 0;
_state = 0;
@@ -25,72 +25,72 @@ struct Random {
step();
}
auto random() -> uint64 {
auto random() -> n64 {
if(_entropy == Entropy::None) return 0;
return (uint64)step() << 32 | (uint64)step() << 0;
return (n64)step() << 32 | (n64)step() << 0;
}
auto bias(uint64 bias) -> uint64 {
auto bias(n64 bias) -> n64 {
if(_entropy == Entropy::None) return bias;
return random();
}
auto bound(uint64 bound) -> uint64 {
uint64 threshold = -bound % bound;
auto bound(n64 bound) -> n64 {
n64 threshold = -bound % bound;
while(true) {
uint64 result = random();
n64 result = random();
if(result >= threshold) return result % bound;
}
}
auto array(uint8* data, uint32 size) -> void {
auto array(array_span<n8> buffer) -> void {
if(_entropy == Entropy::None) {
memory::fill(data, size);
memory::fill(buffer.data(), buffer.size());
return;
}
if(_entropy == Entropy::High) {
for(uint32 address : range(size)) {
data[address] = random();
for(n32 address : range(buffer.size())) {
buffer[address] = random();
}
return;
}
//Entropy::Low
uint lobit = random() & 3;
uint hibit = (lobit + 8 + (random() & 3)) & 15;
uint lovalue = random() & 255;
uint hivalue = random() & 255;
u32 lobit = random() & 3;
u32 hibit = (lobit + 8 + (random() & 3)) & 15;
u32 lovalue = random() & 255;
u32 hivalue = random() & 255;
if((random() & 3) == 0) lovalue = 0;
if((random() & 1) == 0) hivalue = ~lovalue;
for(uint32 address : range(size)) {
uint8 value = address.bit(lobit) ? lovalue : hivalue;
for(n32 address : range(buffer.size())) {
n8 value = address.bit(lobit) ? lovalue : hivalue;
if(address.bit(hibit)) value = ~value;
if((random() & 511) == 0) value.bit(random() & 7) ^= 1;
if((random() & 2047) == 0) value.bit(random() & 7) ^= 1;
data[address] = value;
buffer[address] = value;
}
}
auto serialize(serializer& s) -> void {
s.integer((uint&)_entropy);
s.integer(_state);
s.integer(_increment);
s((u32&)_entropy);
s(_state);
s(_increment);
}
private:
auto step() -> uint32 {
uint64 state = _state;
auto step() -> n32 {
n64 state = _state;
_state = state * 6364136223846793005ull + _increment;
uint32 xorshift = (state >> 18 ^ state) >> 27;
uint32 rotate = state >> 59;
n32 xorshift = (state >> 18 ^ state) >> 27;
n32 rotate = state >> 59;
return xorshift >> rotate | xorshift << (-rotate & 31);
}
Entropy _entropy = Entropy::High;
uint64 _state;
uint64 _increment;
n64 _state;
n64 _increment;
};
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+361 -429
View File
@@ -210,436 +210,368 @@ const unsigned char Icon[6562] = {
45,50,53,84,48,51,58,48,48,58,50,49,43,48,57,58,48,48,84,98,58,187,0,0,0,0,73,69,78,68,174,66,
96,130,
};
const unsigned char Logo[13719] = {
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,61,0,0,0,85,8,6,0,0,0,59,75,51,
30,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
const unsigned char Logo[11533] = {
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,94,0,0,0,85,8,6,0,0,0,1,155,140,
109,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0,
9,112,72,89,115,0,0,0,96,0,0,0,96,0,240,107,66,207,0,0,0,7,116,73,77,69,7,228,3,26,14,47,
13,95,54,87,197,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,52,134,73,68,65,84,120,
218,237,93,7,84,20,87,23,158,237,203,86,150,222,123,7,165,55,81,236,13,17,27,162,32,40,168,136,191,177,247,150,
216,123,143,93,163,49,137,105,198,222,162,198,104,76,76,52,61,198,30,11,177,198,2,130,130,96,129,125,255,187,51,179,
184,16,17,216,153,69,48,115,207,121,7,17,216,41,239,190,239,125,183,62,130,224,132,19,78,56,225,132,19,78,56,225,
132,19,78,56,225,132,19,78,56,225,132,19,78,56,97,87,120,120,240,233,33,196,195,22,15,123,60,44,240,144,210,63,
231,132,19,78,56,121,227,128,15,196,4,143,53,60,30,241,167,198,84,114,194,213,89,185,223,84,45,94,135,191,31,137,
255,191,61,30,110,52,16,114,194,9,39,156,188,49,226,142,199,84,27,107,217,197,183,250,251,63,253,104,77,115,237,162,
153,81,168,127,154,79,81,147,104,155,108,59,27,217,30,129,128,55,22,255,78,4,30,114,238,117,113,194,9,39,111,130,
128,169,27,164,84,136,54,165,38,121,222,63,245,93,226,211,71,215,51,80,246,169,100,244,245,206,120,52,111,106,164,54,
161,157,115,142,147,131,226,32,159,207,251,31,254,93,87,250,111,56,225,132,19,78,234,181,0,147,203,12,12,48,63,191,
253,195,214,197,24,248,180,5,55,50,16,140,127,46,164,162,163,123,58,162,9,195,131,74,66,3,45,46,74,37,130,89,
248,119,253,56,240,227,132,19,78,234,187,128,191,47,6,155,181,223,188,59,183,81,225,131,171,125,74,31,94,75,71,48,
0,252,30,94,203,64,103,79,116,71,11,167,71,105,163,194,172,178,197,98,193,52,252,251,206,220,107,227,132,19,78,234,
187,120,154,170,197,59,102,191,29,81,144,123,133,2,190,252,191,169,1,166,111,1,30,231,127,76,66,211,39,132,149,250,
122,107,254,192,191,159,134,135,140,123,109,156,112,194,73,125,22,71,165,82,180,101,206,59,17,5,121,217,125,74,117,160,
167,15,126,192,252,126,56,216,9,245,238,225,249,24,131,228,135,248,111,188,185,215,198,9,39,156,212,103,113,54,211,72,
246,172,93,210,228,49,6,56,109,69,224,131,1,172,239,206,197,52,180,114,65,12,242,245,50,253,19,255,77,2,30,2,
238,213,113,194,9,39,245,85,252,156,29,21,39,246,111,105,95,12,0,247,50,224,3,243,23,152,223,209,221,241,168,77,
115,135,251,2,1,111,4,65,229,1,114,194,9,39,156,212,47,161,51,153,219,68,135,91,95,57,127,50,233,217,163,74,
128,143,100,125,55,40,95,95,239,158,94,69,82,169,96,1,254,59,21,247,6,57,225,132,147,250,138,125,99,6,245,243,
203,131,192,70,101,160,167,243,245,221,56,211,11,13,27,24,240,76,33,23,173,194,127,167,225,94,31,39,156,112,82,31,
197,204,92,35,217,181,117,83,235,98,96,116,175,4,190,107,84,110,223,232,193,13,75,228,20,240,169,185,215,199,9,39,
156,212,71,105,217,170,169,253,245,235,167,83,158,235,167,177,188,220,207,71,1,223,208,172,128,231,82,137,96,62,193,249,
248,56,225,132,147,122,40,34,137,68,176,122,237,146,38,69,85,177,61,29,227,187,126,186,23,74,235,225,89,196,231,241,
134,19,92,5,7,39,156,112,82,15,37,186,121,19,187,236,27,103,122,149,84,197,246,116,62,190,243,39,147,80,235,230,
14,247,240,223,198,243,249,92,247,42,78,56,225,164,126,137,88,46,23,109,250,108,67,203,226,234,176,61,93,84,247,200,
174,120,200,227,251,29,255,189,23,247,10,57,225,132,147,250,38,93,122,247,240,188,15,181,185,213,1,61,29,227,91,62,
63,6,169,85,226,247,9,206,191,199,9,39,156,212,51,177,241,116,87,159,56,245,93,226,43,243,246,42,38,48,223,185,
144,134,82,147,60,31,227,191,239,37,22,113,238,61,78,56,225,164,254,8,79,36,226,47,217,184,188,105,181,77,92,93,
201,218,241,47,19,144,183,167,233,47,248,51,28,185,215,200,9,39,156,212,39,233,62,48,195,55,23,51,56,109,117,65,
79,199,248,166,142,15,213,10,5,188,183,185,87,200,9,39,156,212,39,241,139,109,100,123,233,230,217,234,69,113,245,125,
123,208,147,47,60,196,242,50,193,117,101,225,132,19,78,234,145,152,58,59,42,143,252,126,172,91,73,117,253,122,250,192,
55,111,106,36,18,9,249,83,241,215,186,254,156,208,49,6,2,47,112,106,156,15,30,129,120,52,199,163,27,30,233,120,
100,226,49,16,15,104,165,159,69,127,223,23,143,222,244,239,180,194,35,20,143,0,130,138,92,195,9,116,50,226,205,233,
68,99,138,71,56,188,11,30,143,55,134,47,20,205,195,99,33,143,207,159,68,191,143,102,120,216,25,249,121,193,65,44,
165,231,200,23,143,16,60,218,225,209,131,158,7,152,143,62,120,164,224,209,21,143,166,244,60,250,210,127,99,66,212,253,
28,82,120,127,10,130,106,218,235,71,191,243,14,120,244,194,163,63,173,127,131,240,120,139,214,71,208,195,12,60,82,241,
232,132,71,12,173,131,158,120,152,227,33,34,184,211,15,107,44,66,181,74,252,225,222,207,218,61,169,137,95,79,7,122,
167,191,79,68,65,13,204,207,18,117,171,243,50,40,190,134,94,16,201,120,225,190,35,146,202,63,85,88,57,28,49,115,
245,63,103,19,16,253,143,75,163,14,15,60,91,39,23,250,197,247,123,218,160,219,224,210,192,30,35,80,112,242,104,20,
156,50,134,252,10,223,55,236,62,84,219,160,235,91,37,240,59,94,109,122,61,118,111,214,45,223,49,162,109,174,181,111,
196,45,51,87,191,51,74,27,231,163,98,153,242,11,30,95,48,3,95,167,31,65,29,188,100,206,162,18,54,193,99,24,
30,67,24,142,161,52,80,72,42,124,62,220,167,39,126,63,19,21,86,142,63,56,69,180,125,208,48,113,104,105,163,65,
243,81,179,49,107,81,243,113,235,81,227,161,75,224,157,104,221,154,118,45,208,56,251,158,19,74,76,214,211,139,84,205,
18,0,216,210,224,53,68,32,150,174,151,91,216,29,134,57,178,11,108,114,215,181,73,167,124,239,182,105,69,254,9,3,
158,227,121,40,197,243,4,243,81,26,208,121,96,137,111,135,190,79,61,91,37,23,186,196,116,204,179,109,16,115,199,204,
45,224,60,204,175,80,34,251,0,64,155,6,75,23,26,20,94,167,200,232,77,54,17,244,16,235,203,22,165,173,203,183,
22,30,129,151,237,131,155,221,199,239,53,223,167,125,159,226,128,206,255,43,9,76,26,174,5,253,11,77,155,128,66,210,
198,147,186,24,4,122,152,56,84,27,208,229,127,37,190,113,25,79,60,90,36,61,114,140,104,147,107,229,19,126,195,212,
209,235,23,169,202,124,15,95,32,132,74,169,100,26,8,69,28,164,85,33,230,102,82,2,43,201,172,245,203,98,11,11,
107,8,122,58,223,222,216,161,129,37,176,35,9,4,188,215,13,116,14,120,116,199,139,103,141,202,214,245,39,135,176,150,
57,254,157,178,158,199,188,181,16,181,155,185,21,117,89,249,45,74,249,248,28,234,179,253,58,202,216,125,7,245,219,159,
139,50,15,62,68,3,190,42,192,163,176,146,81,64,254,78,255,253,15,80,223,189,247,81,198,174,127,80,239,109,215,80,
242,71,103,81,183,213,223,163,184,57,59,81,147,225,239,2,72,150,58,71,181,207,195,215,253,153,47,16,205,195,247,17,
141,135,152,201,243,136,76,20,159,250,196,165,163,136,190,83,81,120,198,59,6,13,248,91,248,12,12,86,223,208,12,67,
39,106,60,239,195,53,46,126,151,240,34,211,194,187,201,216,117,27,13,56,132,223,197,225,199,40,139,30,240,111,120,15,
240,236,61,63,248,147,4,66,188,80,31,155,104,172,190,198,159,209,147,168,121,7,30,152,39,8,126,37,11,165,178,141,
26,103,159,51,174,77,58,23,132,246,158,168,109,245,246,71,168,243,242,111,80,202,102,60,71,59,110,162,190,123,238,161,
254,95,62,168,48,71,248,235,161,71,40,243,64,62,57,127,125,247,220,197,243,121,3,207,235,121,114,126,219,76,251,12,
69,246,159,129,48,32,22,89,120,6,93,17,203,84,159,211,76,201,169,22,89,32,108,46,193,248,253,142,53,49,181,60,
136,55,217,91,190,241,253,158,53,122,107,1,106,63,123,7,234,182,246,4,74,253,236,18,74,223,121,11,191,87,120,198,
60,242,153,42,215,193,66,114,94,250,195,51,239,203,161,116,112,107,54,234,177,241,55,212,113,225,151,40,118,228,10,4,
27,131,149,79,216,117,172,51,155,241,181,227,9,238,212,195,202,133,71,225,212,200,69,51,163,158,23,222,236,91,99,208,
3,118,248,213,142,14,200,222,86,190,143,120,61,173,230,129,45,4,129,57,134,23,208,121,188,107,62,109,62,254,61,148,
184,238,71,82,169,200,5,163,91,192,180,242,100,194,162,57,248,136,252,89,205,199,35,242,239,73,112,128,207,211,125,54,
254,30,128,52,113,237,73,4,76,201,46,168,105,14,44,106,184,55,3,153,159,133,218,222,253,183,30,155,254,64,89,95,
23,189,122,65,188,98,12,60,242,4,181,156,244,1,18,138,165,43,219,207,218,174,251,108,55,96,28,24,12,159,117,127,
239,231,178,5,71,189,151,202,159,29,158,17,158,21,128,166,195,252,189,200,182,97,227,39,248,179,102,86,19,76,0,8,
162,5,34,241,18,141,139,239,5,223,248,190,207,224,190,122,110,58,69,46,124,184,190,97,115,84,126,62,116,159,1,128,
152,242,201,5,212,118,250,22,4,27,31,232,6,102,68,112,22,140,187,17,117,17,128,166,3,126,183,159,227,119,115,55,
172,207,100,109,199,197,7,81,239,47,178,73,144,30,80,182,137,208,192,125,136,161,14,194,231,28,166,158,57,243,96,62,
6,210,191,80,171,201,31,32,215,198,9,133,98,133,122,59,189,241,114,166,111,37,146,57,117,92,40,212,225,106,13,97,
122,183,207,165,162,14,109,156,238,209,62,175,218,20,119,0,59,188,195,221,140,202,154,141,122,188,255,59,185,107,102,209,
138,101,184,82,61,52,88,25,117,140,164,247,214,191,81,147,97,203,16,54,187,178,105,211,183,166,172,47,192,62,164,249,
221,62,59,110,48,122,14,184,31,48,151,72,31,17,181,195,249,97,150,118,12,222,23,128,23,9,118,6,124,38,44,100,
135,144,22,121,36,171,224,189,114,93,129,185,213,4,51,144,143,176,57,151,19,51,120,17,2,32,239,127,32,175,108,179,
48,214,124,232,88,43,0,78,18,102,69,161,189,39,105,177,73,120,30,223,207,128,10,172,151,177,139,8,124,158,18,133,
233,14,0,28,96,172,105,248,253,232,116,161,182,244,144,220,188,240,243,2,19,108,129,55,126,75,175,224,155,180,95,80,
194,65,220,191,165,247,248,225,65,15,11,174,215,28,244,116,108,111,214,228,112,88,88,35,69,181,147,172,12,14,235,222,
106,123,143,179,216,132,211,130,57,164,111,138,214,133,161,99,79,221,214,252,128,156,162,218,23,242,120,252,137,53,84,190,
174,190,29,250,62,135,29,156,201,125,0,227,113,111,218,237,49,237,55,115,147,153,89,127,7,230,16,0,1,147,197,24,
158,49,5,225,13,103,9,189,224,43,19,111,1,102,152,118,65,177,57,205,198,174,35,55,130,215,53,79,186,77,176,235,
234,227,200,163,69,143,39,152,133,111,162,77,94,166,98,141,25,228,108,204,236,238,183,196,44,11,0,7,216,87,237,111,
184,122,131,214,189,238,235,127,70,206,209,113,143,177,238,77,96,232,106,121,35,165,207,132,17,65,143,12,97,122,58,208,
59,180,45,14,217,88,201,118,212,194,174,226,32,148,152,172,117,109,210,249,49,248,127,116,166,77,93,1,187,127,47,182,
66,210,223,228,18,19,255,152,142,200,85,105,110,96,37,133,47,147,163,255,55,143,90,64,12,128,23,124,71,86,62,225,
144,86,20,45,81,106,246,2,211,98,2,120,240,60,157,150,30,70,42,91,87,168,191,118,125,133,243,62,3,179,170,11,
192,40,211,182,92,169,85,198,83,213,253,167,239,188,141,194,251,78,69,38,166,150,95,211,145,95,67,37,80,170,50,63,
20,152,52,188,180,215,167,23,235,204,51,86,212,61,103,188,233,210,81,96,78,244,100,224,140,137,225,79,10,13,4,61,
48,113,175,252,158,140,26,69,90,95,54,114,20,215,71,170,54,255,10,204,20,112,94,27,98,154,189,46,229,3,223,153,
133,71,208,53,58,13,163,74,103,191,88,174,254,180,253,172,109,148,121,198,224,186,224,220,199,236,238,39,204,202,54,135,
164,142,215,146,193,27,67,23,38,254,187,244,29,183,144,91,108,23,178,4,81,32,122,41,121,112,192,236,110,45,254,157,
162,174,43,191,163,24,111,29,2,2,221,102,0,230,53,4,160,76,52,214,199,106,234,231,195,204,14,190,52,197,192,255,
103,179,49,107,200,32,87,93,221,120,65,7,18,215,157,68,230,30,129,127,227,123,14,227,160,14,38,144,106,17,53,118,
233,236,70,79,13,9,100,232,198,131,171,125,80,122,138,55,236,40,173,140,5,120,50,51,155,227,224,39,131,136,94,93,
91,72,213,81,190,198,67,151,34,129,88,178,154,168,58,215,141,12,98,128,31,138,137,41,8,62,179,150,147,54,33,188,
72,115,61,90,246,40,134,136,40,147,247,6,11,27,158,1,155,134,31,18,47,111,54,17,98,98,106,245,13,56,240,235,
252,166,68,71,128,129,77,139,229,170,173,68,53,143,67,224,81,254,203,38,166,142,158,23,219,205,248,130,6,187,71,117,
94,247,154,142,90,133,68,82,249,199,4,149,7,249,223,150,6,254,102,132,80,200,95,176,105,85,51,131,82,86,244,77,
220,57,239,68,128,95,111,8,143,253,120,145,173,84,101,118,0,22,92,153,194,214,35,192,211,1,70,175,79,46,32,75,
239,80,216,113,171,106,203,21,96,31,210,236,14,0,7,211,32,6,228,122,153,185,250,147,65,30,38,0,10,127,155,184,
254,71,248,44,96,243,13,95,114,207,45,49,80,159,5,7,58,176,168,122,177,41,225,123,132,200,177,127,66,38,164,92,
77,160,92,15,85,42,175,143,194,218,233,87,72,141,97,207,55,73,71,114,25,101,21,188,250,57,65,151,28,35,218,64,
224,169,57,71,245,8,66,108,110,38,253,252,240,142,14,207,10,24,128,30,0,230,103,27,90,34,133,66,180,114,254,52,
86,171,51,196,124,161,120,89,72,175,177,84,206,86,61,4,60,253,1,201,206,4,85,93,80,69,16,35,227,25,211,32,
6,12,200,171,35,205,100,70,11,244,17,153,167,231,19,151,241,12,54,53,153,198,186,236,70,53,78,100,5,98,7,12,
134,87,33,103,177,62,48,159,138,96,14,249,135,120,51,186,81,13,243,79,37,146,41,183,52,30,178,152,177,30,234,34,
187,160,211,25,187,255,33,131,60,105,95,92,37,211,172,72,115,153,229,128,15,248,134,129,237,209,150,198,127,190,53,146,
165,151,187,250,251,51,63,116,127,14,109,225,13,102,122,215,51,208,177,189,29,145,131,157,124,55,91,145,34,30,159,156,
155,174,78,145,237,30,146,41,0,172,250,77,202,231,57,193,87,93,126,24,252,255,139,255,99,111,1,195,103,182,24,191,
1,9,68,226,85,13,19,135,86,17,196,152,203,40,136,193,182,121,4,102,50,4,66,8,170,92,141,158,31,210,74,111,
13,105,57,241,11,247,179,187,72,191,42,120,145,215,118,168,128,78,199,40,124,145,142,196,242,243,129,219,4,3,194,218,
202,92,15,2,17,25,159,203,242,110,155,250,20,82,125,152,248,69,225,107,247,13,191,144,249,156,222,237,210,158,56,132,
180,200,181,246,143,186,97,237,27,241,183,93,96,236,61,207,86,201,197,240,179,238,239,253,194,154,101,3,239,176,231,135,
167,33,133,234,2,193,117,70,34,66,219,182,116,188,118,247,98,90,169,161,128,167,95,146,230,231,173,57,73,176,119,92,
164,173,194,202,225,100,252,130,125,172,249,135,116,169,36,160,184,160,120,109,103,108,65,16,209,12,237,61,137,172,170,104,
152,56,164,36,168,231,168,210,200,204,153,168,45,54,97,200,168,28,75,192,7,215,237,252,238,17,36,55,183,61,240,10,
223,10,43,65,12,54,205,242,228,205,103,145,181,127,228,63,4,85,22,167,47,97,106,7,143,115,113,115,119,177,55,63,
36,251,201,195,230,248,31,168,245,219,31,161,136,126,211,200,121,129,8,105,120,250,59,168,197,196,247,201,156,59,202,132,
46,96,77,39,32,202,109,227,31,125,155,32,75,23,95,106,226,58,97,243,253,84,215,85,223,25,254,172,135,40,198,12,
76,81,227,228,115,145,39,16,204,38,168,114,185,96,130,106,218,225,65,187,14,218,192,207,76,157,188,47,68,15,156,163,
133,164,119,54,128,15,88,165,119,219,52,72,40,239,244,95,7,189,126,99,134,4,230,63,50,48,71,79,63,130,123,249,
183,158,40,42,204,234,34,65,213,83,50,179,105,229,100,117,211,40,168,139,5,5,103,139,61,0,99,4,154,239,218,56,
161,0,130,5,34,19,197,135,152,81,78,193,215,130,3,143,116,133,221,253,177,226,143,135,146,30,43,223,240,91,144,229,
14,37,64,172,0,8,222,109,77,29,189,206,224,107,216,24,51,136,193,214,0,0,194,160,163,197,20,116,90,5,179,200,
9,155,185,223,2,8,177,2,62,116,96,161,211,178,175,145,95,199,204,103,120,193,159,21,74,101,239,225,235,64,29,45,
52,26,72,135,60,80,129,88,186,10,191,191,179,129,221,135,149,36,127,116,134,181,119,4,159,3,101,123,248,26,19,105,
221,211,99,121,164,225,50,164,97,247,161,165,153,12,244,0,244,56,106,192,44,8,156,236,162,83,101,94,229,64,36,235,
162,241,59,248,60,188,239,20,109,205,214,64,197,170,33,170,114,104,224,209,39,168,201,240,229,8,91,19,115,196,138,170,
75,167,223,212,82,14,161,92,38,220,184,117,83,235,39,76,252,121,58,208,187,126,58,5,181,108,106,127,141,165,164,79,
23,80,124,8,183,179,161,216,160,0,9,75,191,66,142,97,173,242,132,98,233,6,112,188,19,84,115,128,87,37,215,194,
207,162,148,54,206,167,18,150,124,197,156,205,96,69,4,191,13,54,99,174,191,34,181,39,192,62,152,121,16,163,250,73,
172,5,229,234,59,245,253,113,240,127,113,115,118,1,51,61,94,97,35,51,193,224,179,14,64,130,173,205,0,158,23,18,
205,149,214,78,191,81,155,14,217,53,229,101,166,38,85,99,205,227,189,109,23,220,52,23,130,43,172,232,7,228,31,46,
59,130,100,230,182,71,8,168,214,40,31,141,83,201,204,109,142,48,209,1,50,125,104,197,55,72,105,227,2,141,119,93,
106,176,14,156,85,118,110,191,67,157,55,53,71,122,115,70,155,251,186,210,187,76,93,109,238,238,127,200,220,72,168,124,
233,186,234,56,138,95,176,31,65,149,8,164,232,96,243,28,241,69,226,157,68,53,26,19,240,223,80,224,115,15,106,96,
126,250,210,47,61,159,215,164,151,94,101,160,119,235,92,42,138,107,237,116,189,134,147,250,111,164,145,144,217,16,195,130,
147,71,107,201,93,74,231,212,53,48,186,5,127,11,38,178,153,139,223,21,130,106,19,85,237,78,20,116,78,214,91,193,
41,99,181,140,205,92,136,162,109,187,14,117,185,55,95,241,142,88,11,98,188,178,60,11,191,19,72,210,77,194,38,62,
152,220,157,151,31,197,139,228,20,89,63,172,171,97,5,86,236,24,222,58,31,223,83,71,218,191,74,136,76,200,58,246,
12,200,195,35,211,82,88,112,232,131,105,233,213,166,215,83,200,239,171,65,158,39,0,98,38,48,118,104,32,145,201,214,
220,4,54,185,3,73,13,21,174,21,233,24,222,230,1,89,203,109,104,82,55,214,227,168,1,51,129,73,78,22,201,148,
213,94,11,10,75,7,112,244,206,129,212,26,152,155,94,159,92,36,125,125,48,95,208,188,0,234,204,225,103,33,169,227,
180,254,9,3,158,186,55,75,44,180,15,105,145,107,229,19,150,173,113,241,253,69,110,105,255,173,88,174,222,133,215,212,
74,30,95,0,22,205,104,60,226,254,147,160,71,231,231,245,31,54,176,65,126,77,187,38,87,54,254,57,159,138,58,182,
115,190,193,20,244,192,196,195,147,116,50,168,231,40,4,254,162,46,43,142,145,41,23,176,123,149,117,71,161,235,12,245,
59,129,148,21,114,151,99,43,5,164,15,200,218,47,2,124,82,113,124,145,65,49,150,230,158,45,123,22,235,58,126,48,
77,29,176,15,105,126,139,120,73,53,67,109,4,49,224,125,64,167,25,240,21,97,64,123,160,118,240,248,89,170,182,248,
10,186,166,104,156,125,78,57,71,199,61,140,204,156,169,133,242,57,108,86,65,208,101,69,133,5,226,101,234,232,121,182,
203,202,99,140,153,47,128,47,0,171,71,139,164,98,12,170,208,158,171,166,13,43,36,216,252,251,8,210,100,216,241,41,
230,35,223,248,126,207,241,231,118,214,49,61,158,128,36,155,131,32,123,128,89,202,79,33,10,233,53,14,64,111,40,61,
207,53,145,238,106,123,143,60,219,192,38,119,45,60,131,46,168,29,60,79,194,124,137,100,138,207,4,98,201,2,30,143,
7,61,15,7,227,209,133,160,154,12,4,211,9,215,166,244,59,21,27,130,95,66,58,25,243,77,2,62,149,149,133,201,
222,67,219,59,48,54,109,217,102,122,88,172,176,210,13,199,59,255,60,152,88,153,153,205,17,141,147,207,207,176,123,57,
132,181,124,224,217,170,231,227,6,221,6,63,135,69,25,59,98,5,106,59,253,115,178,52,170,251,250,159,200,192,3,236,
200,253,246,221,39,149,141,76,181,104,223,231,41,237,179,51,116,254,154,67,114,47,27,160,7,133,250,54,254,209,149,109,
12,100,16,163,157,17,131,24,208,117,196,218,47,242,31,204,96,23,130,233,78,47,12,41,61,44,241,104,140,25,193,84,
108,102,254,33,85,155,255,74,80,61,218,202,216,21,95,40,90,10,173,155,216,48,189,97,243,130,32,5,190,151,197,132,
225,39,235,37,120,181,78,41,214,181,9,99,154,214,1,101,115,248,51,39,209,12,159,194,61,145,100,45,116,132,201,98,
88,29,3,243,106,98,106,121,172,26,254,188,138,162,166,211,105,26,16,84,251,52,5,253,190,132,198,4,8,240,103,172,
34,140,219,150,166,182,165,83,98,39,183,59,247,46,245,46,101,131,229,25,193,167,87,113,195,81,211,239,63,152,142,34,
66,167,217,81,88,57,167,11,165,242,247,49,91,57,168,182,119,255,1,239,132,23,237,130,98,161,57,99,129,127,167,129,
207,124,226,50,144,68,101,182,143,96,214,244,50,57,160,203,160,231,108,152,149,80,11,137,205,108,8,246,216,213,118,16,
3,74,166,176,185,3,62,165,102,85,228,106,241,104,157,247,170,176,56,163,109,27,196,220,133,22,70,76,131,23,36,8,
204,252,2,97,198,2,62,52,107,38,190,95,75,239,208,236,212,207,47,51,54,181,203,82,138,196,210,101,120,30,116,159,
47,194,247,184,143,13,159,46,0,115,227,161,75,180,152,81,255,133,55,143,197,52,51,131,6,163,42,99,3,152,33,226,
128,41,228,159,152,241,78,121,67,216,158,218,76,35,217,177,115,115,155,98,54,88,94,89,244,246,87,50,122,123,129,141,
232,109,13,69,64,51,21,5,157,131,212,144,102,49,208,82,28,58,7,7,213,52,69,144,102,61,237,160,255,155,202,206,
237,18,25,165,100,106,206,145,206,236,99,0,60,135,42,49,229,140,18,196,0,0,133,146,41,133,149,195,175,196,203,171,
41,170,181,249,64,215,100,232,208,194,70,64,39,125,199,77,228,220,168,195,35,2,186,48,51,43,225,49,83,218,56,255,
68,246,5,100,184,81,0,211,107,63,107,59,146,40,76,55,233,173,115,169,202,214,245,107,48,247,153,111,68,212,156,194,
166,6,81,84,159,184,244,167,54,1,209,55,85,182,46,39,197,50,229,39,120,3,7,19,31,154,82,180,161,153,157,27,
30,74,226,53,117,72,177,208,152,74,78,218,217,200,46,210,76,163,222,10,125,78,109,159,212,36,207,251,247,47,245,46,
97,3,240,140,152,167,87,171,175,134,118,162,119,226,11,73,160,251,213,189,89,183,199,177,35,150,163,164,13,191,34,54,
204,39,96,18,16,69,195,76,226,61,132,208,203,238,161,139,111,135,140,231,108,6,49,96,161,130,63,20,179,161,155,52,
195,51,84,66,109,26,52,186,195,6,163,2,112,129,50,46,186,209,37,211,3,227,77,228,22,118,7,160,227,14,27,155,
18,116,34,198,102,253,118,61,160,97,17,244,202,39,94,67,58,16,84,98,64,195,91,0,219,38,195,151,145,1,9,159,
246,125,158,56,70,180,205,183,242,9,191,138,245,240,71,12,194,59,49,51,156,75,80,189,241,98,105,215,136,212,216,4,
76,234,234,172,252,242,173,254,254,79,85,74,241,251,68,253,110,197,236,225,230,162,250,241,248,151,9,79,106,122,16,80,
85,21,25,223,176,92,145,97,68,225,209,76,11,108,152,182,208,235,14,43,214,118,56,183,192,171,77,234,19,240,19,130,
34,130,63,144,138,30,23,176,150,120,27,150,254,54,89,159,92,145,221,208,209,81,214,131,24,253,49,88,99,211,28,74,
223,198,86,2,180,85,231,76,68,181,135,40,203,76,200,49,99,227,93,128,111,148,246,179,118,231,49,47,212,150,202,205,
109,247,65,4,154,13,208,3,223,176,137,169,229,62,61,48,22,193,247,9,75,14,25,167,129,66,133,14,200,186,228,108,
72,158,135,192,29,48,88,200,60,104,58,106,37,212,81,151,186,197,118,41,180,244,10,190,140,239,233,0,143,98,134,237,
105,203,138,253,210,50,83,181,100,221,71,107,155,35,204,144,160,67,112,127,111,15,117,125,4,60,19,137,88,176,106,238,
148,200,130,135,215,50,180,108,1,94,89,237,237,123,45,145,66,46,90,49,125,66,88,93,3,56,19,218,207,216,24,143,
1,2,145,100,25,94,40,71,173,124,195,255,134,146,31,168,190,128,40,49,248,219,200,14,46,135,141,211,232,18,0,200,
179,101,207,34,130,202,194,55,122,16,131,100,46,139,190,68,114,11,50,207,206,146,193,59,180,81,219,187,255,14,27,1,
99,19,146,102,158,166,142,94,217,180,111,214,141,222,124,12,29,13,229,150,246,39,217,96,98,212,251,58,128,153,158,5,
228,177,149,245,133,196,44,107,57,212,48,103,213,118,133,140,94,78,158,174,252,14,242,240,122,125,250,23,74,88,124,8,
193,153,27,30,45,122,20,153,58,121,159,1,157,38,168,70,177,38,172,172,26,58,189,99,212,226,89,209,232,143,111,187,
61,13,12,48,63,135,191,111,84,207,0,15,30,34,43,169,179,219,189,91,231,82,75,152,230,229,213,114,151,149,154,50,
56,103,122,65,13,196,202,176,84,102,102,125,24,239,142,151,92,155,116,42,8,78,30,93,10,10,12,190,181,180,207,175,
188,40,238,102,185,206,182,210,196,100,191,200,27,149,4,196,88,15,98,244,219,159,163,99,84,125,244,162,145,6,69,72,
61,91,245,44,134,207,99,3,136,59,204,219,131,172,124,194,138,240,248,27,155,112,217,76,6,54,219,175,57,70,180,121,
2,29,108,216,8,174,196,205,221,13,53,198,31,211,126,98,93,26,81,138,95,66,230,243,204,3,249,175,189,66,70,191,
148,18,116,22,230,4,54,17,48,141,29,195,91,231,137,229,170,207,8,234,152,72,86,142,234,108,159,217,219,167,8,76,
194,47,54,181,46,182,181,145,29,37,168,90,185,58,47,244,41,101,237,35,66,172,46,3,104,179,105,214,150,239,167,231,
101,204,126,122,47,19,17,77,237,97,146,179,4,98,201,187,144,222,98,233,21,114,217,45,182,115,97,112,202,88,18,224,
192,244,129,84,22,210,92,165,15,183,169,237,46,183,112,189,174,171,191,71,10,43,199,111,137,151,159,32,198,106,16,67,
23,52,81,90,59,157,100,200,242,128,233,44,131,210,61,182,24,40,228,90,166,109,185,138,82,241,166,195,198,0,191,24,
27,165,138,160,23,173,223,217,140,68,50,229,74,12,32,229,44,124,56,204,168,174,148,6,150,7,64,124,223,100,131,140,
66,148,186,237,6,138,24,185,30,169,252,26,223,225,9,68,195,217,96,125,110,77,27,217,102,255,125,42,5,129,105,184,
116,78,163,2,181,74,188,141,206,155,169,235,210,200,203,93,253,219,161,237,113,197,5,70,0,60,178,115,242,111,61,81,
163,8,163,119,78,38,104,38,23,132,183,224,65,16,241,194,202,120,214,37,166,227,35,138,193,189,71,30,33,8,244,31,
204,0,125,128,123,221,253,221,116,65,12,161,196,100,67,37,207,197,106,16,3,158,55,36,117,60,48,239,177,21,107,73,
107,40,26,149,173,235,143,112,202,27,171,11,254,208,35,118,7,75,115,20,59,114,37,226,241,5,11,164,42,243,178,23,
224,27,15,231,58,241,166,64,114,241,107,5,56,189,1,223,167,127,249,16,245,220,147,143,226,183,229,161,216,79,31,160,
160,15,114,145,231,198,60,100,63,251,119,36,111,156,86,204,19,155,44,36,106,126,68,103,121,135,169,189,173,124,239,145,
93,241,164,41,135,153,77,233,140,73,225,143,148,10,209,103,68,221,110,213,210,200,197,73,249,227,182,15,91,23,49,109,
42,240,42,211,246,32,121,70,134,201,118,194,56,103,100,0,85,181,195,202,216,79,98,110,191,223,170,97,236,189,32,12,
114,237,102,108,65,201,31,254,137,250,193,17,130,117,8,224,94,123,16,3,76,233,45,87,144,141,127,20,84,126,4,48,
124,247,161,152,245,228,66,201,90,125,239,101,88,157,57,130,132,119,252,204,35,94,146,70,227,132,89,250,207,29,230,237,
174,149,150,95,21,1,174,239,129,135,40,117,95,62,234,182,43,31,181,249,226,1,138,254,56,23,5,188,159,131,220,215,
231,32,167,53,247,145,3,61,28,97,172,205,69,14,75,179,145,178,213,255,158,241,68,146,57,6,175,73,19,169,16,222,
195,184,249,211,34,201,69,14,236,38,231,74,159,210,217,111,71,60,210,152,74,116,93,19,234,154,15,175,157,167,155,250,
55,99,2,94,133,211,208,70,176,124,26,26,60,131,11,166,234,19,69,14,254,167,84,109,134,60,179,29,179,23,121,175,
184,130,162,63,201,67,173,183,62,66,157,119,62,68,201,123,243,201,93,175,255,1,90,81,14,149,87,24,70,190,19,150,
218,23,213,102,16,3,22,37,36,254,138,21,234,173,76,34,233,180,63,43,131,236,46,242,134,3,158,110,128,239,14,124,
152,149,108,76,113,214,126,145,119,224,176,110,54,129,79,95,103,251,131,249,143,117,185,215,94,0,184,60,212,110,107,30,
106,252,9,197,226,188,223,203,65,46,107,41,96,115,88,173,7,114,47,27,24,248,236,151,92,65,178,136,110,5,248,190,
147,121,66,145,193,139,48,178,83,156,75,238,157,11,105,36,232,193,0,198,183,106,97,227,66,71,123,197,247,4,213,185,
163,46,116,37,5,91,62,51,34,196,242,18,152,180,198,4,60,189,242,51,136,106,135,176,248,12,74,172,105,3,68,14,
1,103,76,187,188,83,106,59,227,39,106,50,215,61,192,147,157,83,54,225,206,88,9,60,240,110,231,143,119,189,240,143,
114,81,211,207,30,160,56,76,247,19,241,142,216,11,239,140,25,250,96,120,176,106,48,212,49,70,48,51,193,15,8,17,
221,122,23,196,192,215,107,216,125,152,22,116,192,128,58,207,50,81,217,185,65,195,133,185,96,242,101,213,129,222,126,198,
30,125,247,220,131,35,19,243,95,17,164,132,151,153,110,19,208,232,62,153,194,66,54,55,45,168,25,115,211,3,55,96,
111,105,251,243,81,210,238,124,212,113,123,30,106,241,249,3,20,181,57,23,53,220,148,131,188,244,1,174,34,147,171,238,
192,107,197,102,242,81,36,178,245,250,153,120,121,5,80,181,68,225,228,160,56,116,116,79,71,164,95,201,0,5,251,123,
63,107,87,28,25,106,117,25,111,16,163,94,115,114,174,171,68,44,88,145,152,224,118,23,130,22,198,240,225,85,100,121,
95,237,232,128,236,108,229,251,136,154,23,140,87,234,63,229,203,53,31,43,154,245,123,98,59,237,4,222,181,114,200,157,
235,85,19,236,160,183,251,1,221,119,89,119,159,84,156,6,58,48,252,244,1,106,143,119,205,174,59,243,80,242,158,124,
212,27,43,27,40,93,166,126,36,108,95,14,217,58,28,124,111,254,157,7,62,51,119,107,240,164,241,176,165,172,228,127,
213,90,16,3,234,123,183,254,141,108,27,198,64,131,133,6,76,19,182,37,74,205,110,104,77,84,87,186,56,27,51,34,
10,17,96,11,175,224,191,72,128,168,60,5,1,128,175,139,218,222,227,92,228,128,153,72,23,53,46,107,251,84,193,202,
232,119,128,242,189,165,96,230,6,27,49,248,223,72,112,195,230,105,224,166,92,228,179,33,7,185,97,93,117,90,91,94,
135,107,12,112,175,24,170,184,145,144,167,153,197,51,36,130,47,18,146,187,230,160,137,35,131,75,31,86,104,173,14,224,
114,246,68,247,103,89,233,190,15,204,76,37,112,254,107,115,162,6,45,140,88,97,70,4,145,234,226,164,60,129,77,238,
2,72,75,121,100,100,192,211,49,189,49,67,2,225,165,102,210,81,98,134,214,44,209,80,104,225,124,220,44,117,49,114,
88,113,171,74,176,171,18,8,43,152,2,46,235,114,144,199,134,7,200,119,83,30,10,124,255,62,10,95,125,17,53,154,
117,0,53,26,190,66,235,221,174,247,35,51,23,191,51,244,65,208,125,69,50,229,215,144,41,15,145,49,38,102,243,139,
32,134,212,232,65,12,88,124,80,39,42,51,179,62,200,194,38,164,130,142,30,208,126,170,174,69,45,141,225,207,131,126,
119,208,55,143,160,202,25,171,18,111,200,141,179,242,9,187,17,154,54,161,52,97,233,97,148,180,229,26,234,134,55,213,
248,157,143,80,171,47,30,162,24,108,150,134,124,152,139,252,55,230,32,79,188,1,187,174,187,255,194,255,102,4,112,171,
140,237,89,143,59,128,4,26,187,189,76,162,185,110,97,65,150,23,49,192,161,138,160,2,223,131,159,111,203,198,86,197,
205,155,216,93,147,72,4,43,241,239,71,24,185,66,1,192,174,131,198,84,178,45,185,155,199,253,111,247,37,60,1,230,
201,118,30,94,101,165,103,127,30,79,68,65,13,204,207,178,20,181,245,17,90,186,252,96,145,245,62,197,238,214,228,176,
51,241,240,89,120,242,225,171,253,82,108,102,78,58,130,52,105,75,145,60,54,189,72,228,22,113,145,175,178,218,138,119,
65,96,232,80,226,99,67,239,230,42,19,7,223,31,130,23,253,140,154,111,201,39,125,43,157,118,228,161,238,216,20,129,
93,27,152,34,152,206,176,147,87,116,60,235,131,35,140,172,23,65,140,161,198,14,98,192,103,196,188,181,16,225,235,204,
192,44,141,177,213,96,233,29,122,5,74,207,88,241,233,233,88,117,29,28,3,143,60,65,45,39,190,15,37,130,43,253,
187,12,172,238,251,1,234,228,207,227,241,7,203,45,29,182,169,253,99,179,77,91,13,124,98,209,111,45,178,126,251,24,
178,91,124,25,131,219,61,74,247,72,253,203,101,79,167,107,160,251,224,219,147,250,54,131,238,71,158,134,115,126,49,127,
246,162,153,209,168,50,211,17,76,190,107,127,166,60,95,185,160,241,227,38,209,54,87,229,50,33,236,240,29,233,124,41,
54,82,119,225,101,67,63,182,12,11,115,233,238,174,29,93,239,236,248,168,77,49,116,76,169,13,118,167,15,122,115,167,
68,34,161,144,63,117,88,22,211,32,33,97,33,80,89,237,50,207,88,69,3,30,27,19,158,75,42,27,76,186,213,168,
221,72,221,113,108,137,212,191,197,45,161,185,227,65,158,64,52,149,14,42,56,86,194,200,189,164,126,205,175,219,45,185,
74,250,16,225,243,192,4,129,221,218,115,125,14,105,150,128,233,28,138,119,114,48,85,32,101,160,213,150,7,40,142,6,
71,48,101,32,157,32,117,223,67,212,123,111,46,242,120,117,16,227,19,56,19,99,32,68,159,15,50,11,194,80,231,32,
164,194,57,8,241,44,232,89,160,93,80,108,78,250,174,219,140,79,56,3,19,16,58,249,66,116,52,172,207,228,215,55,
240,230,19,14,35,227,29,109,100,255,233,90,232,29,72,125,157,161,117,141,237,82,202,23,138,178,106,210,228,83,79,36,
116,117,73,103,158,72,58,15,91,43,135,37,222,77,178,21,77,251,22,105,146,231,107,173,70,108,71,182,51,126,198,155,
110,54,114,172,8,132,107,141,13,132,247,144,34,54,157,113,14,173,127,116,184,117,246,133,31,147,80,101,32,3,76,139,
6,191,146,143,215,181,40,78,73,244,184,231,238,162,250,94,36,226,207,39,202,183,148,169,78,230,52,44,74,115,130,234,
22,210,71,102,34,92,223,208,207,236,207,33,3,2,242,14,108,141,123,114,239,175,222,165,108,117,75,169,9,224,157,253,
161,59,10,15,182,188,68,80,135,154,48,202,127,197,32,52,69,213,97,116,169,227,170,187,236,236,134,88,153,236,230,158,
70,154,228,121,90,12,116,183,5,42,203,173,152,253,64,27,114,191,106,154,125,157,148,45,7,62,173,210,116,174,96,62,
59,209,224,8,62,69,72,39,240,222,144,139,188,222,253,11,41,125,98,46,17,47,111,185,101,166,112,240,254,169,213,170,
95,81,226,158,71,168,7,102,146,16,141,134,244,4,96,147,224,15,2,70,9,254,71,96,149,253,95,146,210,80,198,40,
33,96,130,89,25,148,215,17,236,180,65,11,117,138,106,159,15,117,160,53,73,3,122,233,189,129,137,63,249,67,56,120,
252,27,130,234,124,51,132,100,190,181,59,160,209,230,255,240,24,128,71,63,124,47,253,48,179,235,135,129,14,18,241,250,
97,198,150,142,255,207,142,97,245,138,126,101,144,27,185,209,241,5,99,248,114,205,7,34,59,159,31,176,46,222,84,52,
235,87,100,154,52,75,107,57,228,115,100,51,245,7,114,83,46,15,132,44,131,32,94,11,170,184,81,224,130,234,193,132,
115,241,48,120,77,159,57,41,28,61,172,226,216,68,29,248,229,98,179,247,247,99,221,158,173,91,26,91,212,63,205,39,
167,81,164,245,95,142,246,138,195,74,165,104,35,143,58,116,5,38,5,14,166,129,62,113,244,225,52,196,40,161,128,55,
23,155,174,159,186,187,170,190,107,221,204,33,123,228,160,134,249,159,99,243,249,226,79,61,160,197,187,182,182,193,78,255,
185,166,140,11,213,10,4,188,183,89,88,92,145,82,223,166,183,237,230,159,99,228,195,211,223,217,44,254,247,17,146,120,
68,93,227,9,197,51,9,242,132,171,234,231,42,185,124,134,173,67,145,100,129,121,223,53,148,18,50,84,56,235,201,223,
32,129,185,211,129,74,124,42,30,192,40,29,151,94,33,253,141,110,235,169,104,52,4,97,128,77,250,109,204,33,163,121,
193,31,228,162,48,204,42,35,55,231,146,57,90,144,198,0,193,153,230,159,83,12,179,237,23,152,101,110,127,136,98,23,
126,131,228,150,142,95,17,236,52,197,8,115,142,73,120,152,186,235,30,9,190,250,163,207,254,138,131,2,233,180,125,212,
0,208,134,232,57,164,94,128,59,32,101,127,1,138,30,181,14,9,165,178,217,230,30,65,196,127,80,192,143,1,5,251,
94,36,16,242,248,195,248,38,202,117,66,107,247,99,82,159,216,191,1,8,53,189,22,34,235,241,7,41,16,100,147,1,
174,203,197,86,206,56,45,133,45,204,12,77,23,63,111,205,169,19,135,58,163,234,70,72,129,29,21,82,32,165,189,113,
186,215,243,95,142,118,125,190,235,227,182,79,86,47,106,82,56,127,106,228,179,201,163,67,30,143,30,220,48,127,204,144,
192,135,83,199,133,62,89,52,35,234,233,134,229,77,11,15,110,139,123,246,231,241,196,231,119,46,164,129,249,170,165,242,
4,95,15,216,233,130,54,223,237,79,64,222,30,166,191,176,144,152,45,194,147,255,158,121,255,245,204,1,134,30,102,216,
68,22,104,236,161,76,48,204,64,119,130,181,200,222,239,23,48,71,24,131,240,186,60,100,145,181,9,241,196,38,75,228,
81,73,47,187,86,27,108,122,60,38,119,250,202,152,100,69,86,185,250,229,142,112,167,245,121,8,220,3,24,232,103,137,
108,60,217,88,168,1,202,224,184,187,222,107,110,34,95,12,190,229,198,134,242,195,135,30,222,244,0,208,134,225,169,27,
27,243,144,77,230,26,36,16,155,76,149,90,56,16,156,148,49,66,5,205,202,219,99,70,56,65,160,177,219,35,245,109,
118,83,147,52,171,212,126,209,95,236,0,31,214,97,101,219,33,112,80,123,87,102,137,112,38,36,5,78,79,79,241,42,
186,123,145,202,219,171,41,83,2,16,4,0,43,188,217,151,28,248,223,90,0,53,26,216,180,228,255,223,160,126,167,54,
125,117,85,221,247,63,23,210,80,175,238,158,224,35,72,97,33,25,57,88,234,223,242,182,253,226,203,204,39,24,239,104,
86,99,246,35,161,149,219,73,122,71,173,185,22,10,201,152,83,42,54,109,159,56,174,190,203,74,244,76,221,121,18,236,
178,253,254,149,6,65,229,208,13,195,166,14,59,128,143,223,159,170,221,48,72,174,77,98,105,81,122,224,5,152,13,126,
40,93,110,164,161,131,4,255,65,155,1,252,151,121,159,70,255,5,64,19,16,134,117,67,6,139,196,143,39,16,205,151,
55,74,41,96,101,93,172,186,131,228,81,61,94,149,127,88,35,145,155,170,37,155,49,83,171,51,160,84,27,190,188,229,
243,98,144,74,41,222,72,48,44,104,230,75,149,144,246,63,65,211,99,14,43,139,30,82,92,64,81,192,153,76,24,238,
151,177,22,90,186,124,11,102,6,43,64,180,234,31,36,143,238,249,144,160,218,90,253,11,99,249,50,245,122,240,237,176,
242,252,203,111,34,147,224,120,72,18,103,171,209,173,181,216,37,228,79,187,249,103,89,216,144,30,32,235,9,95,33,129,
153,195,94,106,97,51,50,179,248,196,235,105,175,14,215,149,210,190,120,43,130,106,56,18,74,167,167,193,41,123,3,9,
190,112,50,214,235,101,120,94,63,197,204,109,60,131,251,20,227,13,98,5,25,216,99,162,27,16,189,93,120,1,92,61,
127,17,44,150,203,250,250,251,104,78,31,219,91,62,97,249,77,28,240,124,95,239,140,71,62,94,166,191,51,10,127,235,
109,26,66,115,167,67,54,147,142,178,226,59,179,157,254,35,100,159,159,96,144,28,46,130,198,140,234,142,227,75,42,154,
155,134,43,220,197,87,41,156,74,104,237,241,173,237,180,147,204,205,104,124,45,187,57,167,144,216,41,240,20,193,176,171,
138,190,65,35,180,112,62,100,243,246,49,146,69,51,126,23,216,92,147,120,55,249,155,97,224,75,136,129,37,131,47,215,
124,142,129,101,53,102,230,211,233,160,72,79,60,90,211,41,98,222,116,234,145,154,222,152,5,213,250,92,42,88,232,74,
7,12,155,146,155,39,248,214,121,252,9,60,137,124,17,95,97,254,1,152,159,34,91,239,239,197,110,97,231,164,126,205,
175,201,66,59,221,87,196,246,41,82,181,31,94,98,154,56,93,107,214,231,93,210,159,108,158,185,30,225,185,253,145,96,
86,168,144,4,1,8,70,186,129,215,149,213,152,125,72,160,182,222,198,90,234,156,80,64,154,40,157,219,181,116,204,185,
248,83,143,55,150,241,193,115,157,59,153,132,90,53,179,7,38,17,207,99,167,105,158,183,212,191,197,13,200,157,99,131,
73,192,228,242,21,102,31,27,184,187,138,225,4,54,89,68,183,71,246,139,46,178,227,75,193,64,97,51,249,27,132,129,
253,96,229,65,140,102,215,41,199,53,11,207,63,118,63,86,110,171,173,108,38,197,227,197,190,28,22,49,152,167,108,108,
2,166,221,166,106,49,3,122,199,64,95,171,20,230,200,36,184,67,158,229,176,173,200,114,240,167,200,60,99,53,2,75,
1,34,255,80,193,35,11,239,250,64,26,208,234,134,196,61,242,130,200,222,247,164,192,204,126,31,95,105,254,17,79,170,
88,130,175,59,17,146,232,233,236,137,166,52,184,1,200,193,137,112,254,124,165,197,9,8,42,152,132,116,188,39,111,156,
86,168,108,59,228,185,105,215,41,90,179,180,165,8,114,71,173,70,236,36,231,19,124,189,192,126,161,168,223,97,229,109,
42,242,170,203,5,93,159,71,14,176,58,100,33,9,57,16,164,51,240,189,195,151,225,166,221,103,50,100,122,185,72,157,
48,161,20,127,214,32,252,252,236,218,239,2,62,111,116,70,47,239,226,155,103,123,161,71,215,50,222,56,192,131,147,206,
210,122,120,22,97,176,27,78,176,87,95,28,167,104,222,191,136,189,204,243,131,72,160,178,50,164,200,222,18,51,134,57,
242,168,164,2,187,185,127,178,20,65,46,31,196,80,52,78,171,44,136,81,196,10,171,196,215,50,75,95,129,120,2,209,
52,129,41,59,231,50,225,207,34,253,214,234,248,177,37,172,188,19,72,35,154,119,26,97,134,4,7,106,119,224,155,212,
40,31,206,150,12,6,197,164,60,134,84,36,18,92,200,20,143,60,106,144,247,119,143,116,39,56,44,187,134,236,22,156,
71,182,51,127,69,192,82,173,70,237,66,22,3,63,64,102,189,151,145,160,171,106,59,180,4,64,13,131,231,61,12,116,
112,122,31,128,97,67,12,150,247,72,48,35,129,236,110,121,32,91,167,187,94,174,94,100,53,231,149,250,168,233,181,8,
130,74,115,12,4,120,91,161,165,235,113,235,137,135,13,103,217,228,251,62,131,36,238,17,151,89,178,204,254,37,50,19,
169,96,209,136,65,13,159,223,33,3,27,111,6,240,193,115,192,33,222,67,179,2,158,73,36,130,185,180,79,131,133,21,
69,226,102,22,86,66,214,156,248,144,242,34,241,140,190,74,231,226,85,203,124,131,197,39,208,216,127,173,238,56,174,196,
126,241,37,246,0,175,170,32,6,191,206,7,49,202,114,82,165,254,45,111,217,47,185,202,90,36,17,124,123,98,183,240,
108,58,53,75,94,69,116,19,76,245,20,161,133,203,247,208,120,130,178,10,114,171,87,133,67,38,167,231,190,0,71,29,
80,146,63,203,65,22,111,125,2,81,254,31,104,182,231,40,241,138,185,194,74,224,160,76,31,207,34,169,111,83,104,239,
213,2,155,228,53,121,231,14,124,169,242,67,211,110,211,74,25,5,211,240,179,107,82,22,32,158,72,50,143,48,226,33,
66,166,74,133,104,237,184,97,65,37,0,124,245,157,241,193,253,255,115,33,21,141,30,220,176,68,46,19,173,36,24,54,
36,44,207,34,132,16,196,24,7,166,3,43,166,19,173,104,102,125,86,96,19,215,124,39,13,124,130,74,18,189,193,191,
150,36,80,89,110,151,133,119,123,104,53,114,215,139,157,157,205,164,208,250,29,196,40,139,38,98,246,188,205,106,228,78,
214,82,138,0,140,108,166,28,135,160,83,161,64,109,189,155,54,57,33,178,232,67,251,227,32,213,168,43,79,36,157,47,
178,243,249,89,217,98,192,19,50,176,180,230,30,75,110,135,7,100,41,162,216,37,248,178,94,68,83,41,180,241,100,199,
191,170,247,156,86,163,247,32,177,99,131,11,180,207,81,85,5,192,67,112,36,25,51,188,19,154,30,179,181,48,167,6,
63,47,248,184,103,254,130,159,49,228,47,250,189,26,85,204,0,248,70,12,106,240,252,230,153,94,245,214,199,71,153,180,
189,72,134,39,151,139,86,17,44,119,142,33,77,39,30,127,130,89,239,119,217,3,61,72,171,88,249,15,152,121,90,137,
123,228,85,190,220,116,19,190,6,68,208,32,11,127,40,228,175,225,5,188,5,179,140,139,144,146,98,57,124,59,114,120,
247,58,123,139,249,101,142,123,207,104,88,88,78,245,48,136,161,111,226,38,43,48,240,176,146,194,163,223,232,18,47,106,
171,81,123,144,186,211,196,82,121,100,82,190,73,131,54,183,240,184,41,11,235,156,171,108,51,248,25,36,135,67,112,138,
188,46,91,115,132,63,7,62,83,234,19,11,93,104,58,241,21,102,47,54,33,169,114,53,164,213,176,167,143,212,220,64,
123,39,121,76,106,161,208,194,249,40,157,44,15,190,142,14,4,117,146,25,228,206,13,230,75,21,171,68,246,126,191,42,
154,247,47,182,30,127,232,5,91,53,120,29,220,70,88,199,33,55,111,40,102,234,181,18,218,86,155,72,133,139,210,147,
189,138,47,252,148,84,239,162,186,112,191,231,79,38,161,222,61,60,139,164,82,193,124,54,25,94,5,243,118,144,105,247,
25,236,131,14,109,90,88,14,251,2,153,165,45,65,166,73,51,145,166,231,92,4,139,200,106,204,94,210,12,38,89,3,
121,93,35,213,61,146,108,230,123,200,25,60,82,137,9,87,231,131,24,122,98,241,194,191,196,242,92,233,234,79,87,221,
33,55,32,135,119,175,33,71,188,113,189,104,18,193,174,187,1,130,16,38,13,90,67,128,161,119,57,147,143,114,55,164,
168,218,14,125,110,12,93,0,16,2,255,162,89,198,74,8,44,104,149,173,6,61,87,182,204,122,170,106,55,172,4,130,
21,0,182,192,204,40,128,207,101,124,61,72,117,193,128,190,133,142,96,215,154,200,4,2,222,232,182,45,28,114,224,60,
88,96,78,181,209,249,132,105,226,49,220,39,180,196,135,40,45,190,127,86,14,23,169,156,205,67,32,35,179,216,88,221,
37,202,59,161,43,248,116,170,250,91,22,22,24,48,73,190,92,179,169,18,127,138,17,130,24,66,214,130,24,229,102,74,
68,186,113,83,21,177,125,138,201,118,95,181,221,41,132,45,192,155,118,66,7,120,125,43,9,198,57,97,115,240,156,221,
156,63,216,5,219,114,13,48,242,202,127,182,78,79,217,2,120,216,0,71,237,70,34,91,111,72,43,123,45,221,220,193,
167,212,217,207,91,115,122,245,162,198,8,42,55,10,234,168,185,11,247,5,126,200,21,243,99,144,175,151,41,152,73,241,
4,75,199,200,189,66,92,193,252,131,228,73,227,119,154,168,1,75,156,123,26,155,94,55,152,125,14,148,132,245,95,143,
8,129,112,22,207,164,2,81,166,82,7,234,67,16,67,95,148,152,57,124,97,158,185,193,56,238,0,163,2,30,21,60,
145,120,55,190,69,7,79,4,175,168,200,153,65,206,139,49,64,175,54,122,231,65,144,200,53,244,42,153,48,253,26,207,
98,5,241,209,168,37,155,251,36,123,21,157,56,216,185,140,81,213,21,223,29,220,207,241,47,59,161,180,36,207,199,106,
149,248,3,194,192,18,46,67,210,28,249,50,245,70,72,39,120,237,11,9,64,23,155,22,230,153,239,33,89,72,71,50,
181,130,17,16,67,202,66,202,2,168,183,26,249,146,252,168,250,18,196,168,40,193,98,231,192,139,84,178,114,61,0,62,
114,78,161,249,196,135,72,68,5,19,226,171,17,197,116,23,57,248,159,182,121,251,219,122,4,238,84,164,26,82,115,104,
192,235,64,212,17,145,99,224,237,3,44,106,198,196,240,210,243,63,38,145,236,234,117,129,31,89,247,75,39,28,79,29,
31,90,234,227,73,86,89,192,46,40,171,189,87,66,234,95,115,147,160,184,28,86,124,91,12,0,10,82,21,212,157,38,
150,240,229,102,39,197,78,129,247,236,22,156,99,14,122,61,231,80,141,67,255,13,122,245,34,136,241,175,26,44,138,177,
38,74,3,90,221,183,157,245,107,221,6,5,221,156,118,158,84,42,208,216,65,215,153,106,157,223,66,155,242,201,178,176,
206,143,160,154,166,206,51,62,240,23,174,184,141,204,250,44,71,34,27,207,223,240,189,55,35,234,160,56,75,196,130,233,
81,97,86,87,23,206,136,210,66,7,102,200,133,211,157,176,102,108,159,157,238,58,208,11,111,254,180,72,109,100,168,213,
85,177,152,63,181,146,8,99,109,136,8,146,78,201,124,61,8,46,212,166,191,136,86,104,235,177,95,2,83,202,195,247,
1,249,76,129,18,247,200,179,246,11,206,51,4,189,60,82,17,49,167,155,68,71,64,203,7,49,124,217,14,98,88,27,
43,136,241,50,151,77,166,73,195,182,185,228,249,37,117,13,248,96,78,49,187,179,26,189,23,65,229,6,164,189,208,37,
105,53,44,71,20,189,173,136,77,127,66,118,58,169,139,224,190,150,74,146,134,141,19,42,81,248,114,205,167,4,243,190,
150,70,21,112,162,250,74,36,130,89,33,129,22,23,39,140,8,42,129,224,1,116,47,41,184,193,46,0,234,128,14,6,
36,25,127,141,175,51,126,120,80,9,92,23,95,127,38,237,236,124,221,39,184,217,9,76,109,15,146,253,235,214,228,24,
159,241,209,29,149,193,119,167,238,60,185,84,104,229,6,245,186,29,233,242,53,51,108,194,253,1,236,137,41,232,129,249,
138,217,209,186,250,86,137,81,77,224,75,149,120,68,94,179,28,186,133,46,195,202,125,237,204,14,116,7,128,88,213,110,
248,115,161,185,211,49,218,204,51,116,35,144,241,132,226,169,178,136,196,2,50,109,198,24,205,61,13,214,93,170,178,5,
26,145,138,29,27,156,195,27,107,22,65,29,27,81,47,4,236,59,87,30,143,247,150,131,157,252,80,66,123,231,92,96,
95,0,128,127,159,74,70,121,217,20,96,21,210,173,165,32,89,88,119,244,228,67,61,80,211,13,248,185,174,103,31,252,
29,252,125,246,31,201,232,240,206,14,104,238,148,8,109,199,118,206,57,248,58,7,240,245,6,210,89,232,252,58,244,46,
124,5,102,14,71,33,181,132,76,91,96,59,157,68,47,5,130,236,168,156,178,16,225,69,251,55,86,236,41,248,218,246,
229,146,113,53,118,187,193,33,204,180,230,145,78,89,129,190,126,138,127,7,49,102,179,84,207,154,75,46,114,35,7,49,
42,211,221,24,129,198,254,48,4,81,72,83,189,44,5,37,167,118,252,88,116,181,133,195,138,155,8,210,105,84,113,35,
159,139,236,253,254,192,32,48,132,78,244,101,156,152,77,240,120,253,196,46,33,151,33,137,158,12,184,233,42,60,214,214,
178,69,2,186,178,250,46,178,157,126,18,153,118,159,161,149,184,71,92,229,137,36,179,8,170,211,11,143,168,167,2,11,
35,82,32,224,141,179,183,149,239,141,109,100,155,157,217,219,167,104,225,244,40,180,117,83,107,116,252,203,4,210,255,118,
21,131,24,212,247,66,165,4,68,91,129,189,193,247,87,127,79,70,231,78,36,145,205,61,191,216,212,10,76,87,212,47,
205,167,168,113,148,77,182,173,141,108,183,128,207,27,131,63,63,156,96,167,163,174,209,76,127,232,38,11,7,20,195,153,
2,101,224,87,99,37,203,209,75,5,200,163,18,133,23,95,38,27,18,192,57,25,18,183,240,75,112,142,1,190,94,64,
69,224,23,154,57,0,48,77,134,46,182,208,148,83,87,178,84,243,145,75,158,135,32,245,107,113,163,130,217,193,195,236,
239,61,178,136,31,234,68,151,223,52,124,224,197,14,38,178,73,80,135,251,4,187,103,14,215,40,135,15,191,175,97,0,
54,0,126,80,129,80,86,202,165,171,87,101,116,32,78,142,94,73,25,61,159,107,168,3,158,160,248,31,78,205,147,133,
117,201,195,204,238,107,12,80,192,120,28,140,0,238,254,60,137,124,153,196,43,230,186,105,215,41,165,176,33,146,174,9,
154,105,151,63,235,34,135,217,198,172,175,183,235,114,201,198,5,144,191,103,49,96,35,82,52,205,40,22,217,249,252,202,
19,8,39,209,85,22,124,226,13,18,240,166,66,127,253,246,60,30,49,82,173,18,175,115,114,80,124,217,192,207,236,151,
152,40,155,203,109,91,56,220,196,172,240,118,151,120,151,219,9,237,156,111,195,247,49,145,54,151,225,231,248,247,246,171,
148,226,181,248,239,70,16,212,65,52,174,4,91,245,178,181,247,236,9,2,149,213,78,188,152,115,128,249,193,17,118,144,
80,12,139,92,23,169,42,3,67,253,65,251,115,32,201,21,146,147,173,39,126,141,204,251,175,35,187,198,74,125,155,94,
23,168,173,119,210,11,195,189,10,133,105,36,118,9,190,171,108,51,248,169,178,205,144,39,134,143,193,79,69,118,190,208,
108,181,155,254,230,134,1,119,183,212,39,54,79,22,218,41,7,58,113,48,25,38,129,237,30,8,84,150,223,145,224,243,
122,5,216,114,6,126,199,59,224,93,67,146,175,121,191,53,8,170,11,192,85,64,214,204,66,210,241,171,230,175,226,97,
57,152,217,192,198,7,12,11,152,36,148,194,1,227,82,182,250,223,83,168,7,198,64,247,21,125,192,83,99,163,36,208,
87,200,52,32,160,180,145,47,24,129,217,237,126,240,201,194,125,64,43,41,184,47,56,140,30,238,147,220,168,87,223,173,
217,115,66,4,126,229,109,18,72,161,225,5,176,86,232,234,2,221,81,48,160,63,128,46,222,208,237,6,214,5,205,96,
121,196,127,64,120,52,24,152,211,59,153,43,189,112,61,232,175,174,244,255,155,215,51,128,123,149,64,82,116,36,52,98,
20,152,218,238,20,187,134,158,3,144,128,174,44,170,248,49,165,16,248,48,237,49,155,172,180,128,170,14,117,167,137,8,
22,154,162,113,90,129,73,96,251,59,216,36,57,131,205,229,125,180,35,59,137,102,91,210,26,92,187,37,173,100,29,25,
142,4,162,252,33,61,66,122,151,14,102,113,120,214,66,78,101,77,54,45,120,215,73,208,97,68,160,177,219,37,114,108,
240,27,6,169,155,178,200,196,7,138,230,153,69,170,246,35,74,212,157,39,33,211,196,233,72,163,155,195,164,89,248,251,
105,16,109,69,240,115,101,139,172,98,121,116,207,124,12,234,119,36,30,145,23,133,214,238,223,240,149,230,155,129,133,19,
84,159,59,223,215,104,181,152,208,239,188,11,180,201,226,43,45,54,139,108,60,191,131,251,4,221,147,55,74,126,168,36,
159,115,248,115,208,75,82,87,187,207,36,91,96,149,61,43,254,63,56,183,2,235,236,51,56,169,76,22,222,53,23,42,
116,68,142,1,191,10,204,236,119,243,196,38,139,9,42,137,58,146,94,215,255,9,160,227,68,223,183,66,16,182,244,2,
7,246,154,76,80,69,234,131,9,234,64,37,168,173,237,67,80,117,140,16,178,247,199,195,250,13,218,0,234,179,136,105,
22,234,65,47,96,168,55,237,142,71,58,1,157,134,95,204,225,91,120,100,209,255,15,63,143,3,159,33,13,110,118,180,
163,190,174,154,115,124,154,105,218,209,247,219,152,126,206,68,90,47,51,105,29,213,157,0,55,136,254,191,94,180,206,194,
209,140,161,180,117,103,65,212,224,16,43,78,56,225,132,19,78,56,225,132,19,78,56,225,132,19,78,56,225,164,76,254,
15,59,211,107,111,127,84,85,213,0,0,0,37,116,69,88,116,100,97,116,101,58,99,114,101,97,116,101,0,50,48,50,
48,45,48,51,45,50,54,84,48,53,58,52,55,58,49,51,43,48,57,58,48,48,231,7,151,25,0,0,0,37,116,69,
88,116,100,97,116,101,58,109,111,100,105,102,121,0,50,48,50,48,45,48,51,45,50,54,84,48,53,58,52,55,58,49,
51,43,48,57,58,48,48,150,90,47,165,0,0,0,0,73,69,78,68,174,66,96,130,
9,112,72,89,115,0,0,0,96,0,0,0,96,0,240,107,66,207,0,0,0,7,116,73,77,69,7,228,8,10,18,21,
15,166,100,212,10,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,43,252,73,68,65,84,120,
218,237,93,7,84,84,71,23,126,219,119,217,66,89,58,75,239,189,72,17,193,130,2,162,8,42,96,3,1,177,199,168,
81,163,177,229,55,246,168,137,137,189,151,104,140,37,246,216,176,165,153,24,75,236,198,196,222,59,29,236,194,252,115,223,
190,85,68,80,145,89,88,240,125,231,220,99,52,176,251,222,148,111,110,31,138,98,193,130,5,11,22,44,88,176,96,193,
130,5,11,22,44,88,176,96,193,130,5,11,22,44,180,7,14,22,46,35,2,44,150,88,172,176,40,177,136,216,225,97,
193,130,5,11,237,145,47,64,129,101,57,135,195,57,169,52,20,237,183,183,149,111,83,200,133,115,241,191,125,130,37,10,
139,45,75,198,44,88,176,96,65,158,128,221,176,124,105,109,37,189,52,168,143,247,211,21,243,35,208,148,49,33,40,35,
217,245,65,131,96,179,139,230,166,146,141,92,46,103,0,254,25,127,44,18,118,200,88,176,96,193,130,12,120,88,66,12,
244,133,171,123,164,185,101,255,123,176,253,211,252,171,93,208,197,99,157,208,206,245,45,209,248,145,65,37,45,34,173,239,
90,154,235,109,225,112,168,174,248,103,173,75,105,205,44,88,176,96,193,162,10,0,215,67,255,144,122,166,23,118,172,109,
241,184,240,90,70,73,225,245,12,4,114,243,76,103,180,107,67,75,52,168,143,207,51,31,79,163,211,2,1,247,115,252,
179,78,44,1,179,96,193,130,69,213,1,65,183,72,59,27,249,129,197,51,27,63,200,187,210,165,4,11,2,13,24,8,
24,254,251,196,190,68,90,11,246,247,49,62,199,231,115,135,226,159,183,96,135,141,5,11,22,44,170,14,111,19,165,120,
231,140,73,97,69,185,151,187,20,3,225,106,164,224,90,6,45,39,255,72,66,195,7,250,61,119,180,87,252,133,127,62,
129,98,3,113,44,88,176,96,81,101,56,25,25,138,182,205,250,42,172,72,163,249,150,37,96,248,243,231,205,173,80,82,
188,67,129,76,42,152,77,169,51,33,88,176,96,193,130,69,21,224,106,110,170,247,243,202,133,77,31,98,162,125,141,124,
65,192,5,113,227,159,20,52,121,116,72,137,131,157,226,0,254,157,8,138,245,253,178,96,193,130,69,149,16,228,230,108,
112,252,247,109,113,143,53,90,110,89,1,31,48,200,214,213,49,40,188,190,249,13,252,59,221,40,117,129,6,11,22,44,
88,176,168,44,56,106,221,53,49,42,66,117,227,210,241,78,207,242,175,150,79,190,26,237,247,216,111,137,40,161,149,125,
129,128,207,29,65,177,185,191,44,88,176,96,241,222,224,115,185,156,241,195,7,250,229,99,130,45,174,136,120,53,190,223,
11,71,59,162,140,20,215,71,34,17,111,2,254,93,41,59,124,44,88,176,96,241,126,176,180,180,144,254,188,115,125,203,
199,154,212,178,55,145,239,213,147,201,168,71,186,219,99,161,144,55,158,213,124,89,176,96,193,226,253,145,144,208,202,254,
206,157,179,169,207,193,167,251,46,228,155,222,201,229,33,143,199,129,124,95,62,59,124,44,88,176,96,81,121,232,41,228,
194,85,107,22,55,123,244,54,173,87,67,190,231,254,238,128,226,91,216,230,225,223,77,141,111,201,102,155,177,96,193,130,
197,251,32,166,77,75,187,91,119,177,214,251,54,226,165,3,110,152,124,15,255,220,22,133,4,154,94,193,191,27,198,230,
153,177,96,193,130,69,229,33,83,26,137,55,209,253,28,222,65,235,213,100,59,108,248,62,26,217,168,100,191,80,234,30,
192,44,88,176,96,193,162,146,232,218,191,151,87,94,254,213,46,37,239,66,188,26,25,51,60,176,68,44,226,77,161,88,
127,47,11,22,44,88,84,26,142,1,62,198,167,206,31,233,248,236,109,65,182,151,69,22,25,232,202,137,100,20,27,109,
147,133,127,191,57,151,203,58,29,88,176,96,193,162,50,224,203,164,130,239,54,126,31,253,206,238,6,141,203,1,170,219,
84,150,210,93,248,51,140,216,97,100,193,130,5,139,202,161,215,136,129,254,249,133,21,244,112,168,72,114,46,165,163,126,
61,61,159,194,239,27,232,179,13,205,88,176,96,193,162,50,168,31,23,99,123,227,222,249,180,231,149,33,94,72,49,251,
107,87,27,228,234,108,112,152,98,123,249,178,96,193,130,69,165,96,225,229,110,248,247,185,195,29,158,191,169,127,67,69,
50,164,159,239,115,252,25,31,201,229,108,47,29,22,44,88,176,120,87,72,44,204,244,126,218,183,61,254,73,69,93,203,
222,148,219,251,199,142,120,228,96,167,216,71,169,175,150,103,193,130,5,11,22,239,0,142,88,204,155,187,110,89,212,163,
202,4,216,52,146,125,49,29,26,233,60,196,159,19,207,225,84,75,134,3,124,9,220,150,220,6,190,83,135,36,14,75,
12,165,238,99,28,130,197,7,139,7,22,27,44,50,74,183,83,239,96,76,193,100,209,199,226,192,60,183,47,150,250,204,
251,180,32,48,62,173,177,180,100,190,163,170,128,171,173,132,88,140,177,56,98,241,100,158,23,198,189,9,51,15,213,49,
215,141,176,248,49,227,165,194,34,166,170,175,135,181,102,12,76,177,184,96,241,198,82,143,153,175,24,230,25,227,117,84,
96,45,52,99,198,235,195,4,159,207,165,184,28,206,132,165,179,154,20,23,221,232,90,105,226,5,178,94,179,184,25,50,
208,23,46,161,212,55,29,107,27,6,98,125,227,223,28,35,146,158,185,181,72,127,172,75,226,26,147,246,208,37,42,165,
200,49,162,93,190,109,104,203,28,11,223,134,247,148,78,62,231,21,150,14,127,8,165,250,235,57,60,222,56,252,252,157,
24,162,208,171,193,105,23,48,68,209,24,220,68,92,190,112,134,88,161,220,170,175,114,250,203,216,217,255,178,165,111,163,
123,118,13,90,229,58,53,109,95,224,18,149,92,132,223,235,81,149,198,166,101,151,199,246,225,241,79,249,98,189,211,148,
250,118,235,74,91,101,88,156,129,76,240,225,62,132,39,20,47,146,24,154,102,26,218,184,29,49,113,9,184,106,233,215,
248,158,93,88,28,60,111,62,243,188,15,181,63,215,169,15,157,35,59,21,226,247,202,133,241,82,58,120,255,39,85,90,
236,225,10,132,51,152,57,182,101,200,145,228,225,104,130,37,12,75,31,158,64,52,71,207,200,108,167,161,173,251,113,51,
247,224,155,214,193,209,217,14,141,19,242,170,235,253,171,178,22,172,2,34,158,115,184,188,237,212,135,220,241,144,81,82,
135,205,152,212,224,201,251,16,47,228,255,94,56,210,17,133,6,155,93,96,180,37,109,35,28,147,90,94,151,77,55,81,
247,204,92,212,125,135,46,73,14,234,182,61,27,117,219,118,31,101,252,116,7,117,217,120,3,165,172,58,135,146,22,28,
68,177,147,126,66,13,63,153,142,60,91,247,122,102,225,19,126,71,98,96,178,19,15,254,64,70,91,225,86,195,184,193,
161,8,55,74,119,23,234,41,86,99,162,56,139,55,106,97,64,202,103,37,77,135,45,66,113,223,100,162,118,139,14,163,
212,31,47,226,231,190,137,50,182,220,197,239,145,69,191,79,85,199,165,231,174,2,20,249,249,114,36,16,75,151,85,226,
112,134,84,25,127,14,135,251,25,30,171,29,152,92,174,97,178,123,28,210,99,28,138,26,245,3,106,61,109,15,234,240,
221,113,148,186,246,50,130,181,208,245,149,231,205,169,182,185,134,239,133,121,78,254,225,95,212,102,230,47,168,201,103,243,
145,71,171,238,79,141,236,60,206,113,249,130,47,25,141,188,42,144,99,137,228,9,132,211,245,173,28,143,226,3,49,63,
160,243,208,146,102,35,150,162,214,211,247,162,142,203,78,162,180,245,87,81,198,230,219,168,235,214,123,213,248,254,239,39,
61,118,230,163,160,140,47,16,126,167,225,120,124,62,120,119,195,192,41,99,66,138,138,174,87,46,165,172,52,249,14,232,
237,253,12,78,122,109,22,84,136,228,134,240,199,168,250,189,38,162,158,187,139,232,73,212,93,41,64,61,48,225,0,233,
244,220,93,136,122,238,41,66,189,246,60,160,255,95,218,186,171,40,110,106,38,242,239,52,184,88,233,232,125,137,203,227,
143,99,92,18,218,0,152,163,225,88,75,156,107,236,236,119,217,59,177,239,243,230,99,127,68,201,43,206,208,7,4,60,
27,60,23,60,31,252,55,60,51,45,240,252,164,198,34,51,143,62,112,240,115,164,112,184,111,61,99,64,187,109,33,208,
147,175,194,7,212,221,192,244,207,75,226,166,238,160,15,4,154,196,153,113,132,249,239,185,75,75,207,251,222,243,172,126,
182,238,248,125,59,126,119,2,19,204,40,164,176,176,63,201,184,88,42,187,49,192,61,213,14,91,119,59,237,194,90,21,
52,28,56,147,62,24,129,232,95,204,89,233,49,168,177,247,175,132,224,231,236,178,233,22,178,14,138,202,97,220,88,31,
60,6,125,53,182,254,131,247,37,94,252,123,104,229,194,166,72,46,19,204,209,178,143,75,33,53,182,250,21,52,11,221,
39,222,55,47,64,250,249,241,159,160,177,128,6,35,51,85,29,2,205,134,176,15,208,31,155,247,139,173,252,155,100,55,
194,27,23,200,22,190,191,39,108,90,216,176,213,240,174,64,72,41,43,255,67,38,46,1,151,222,162,253,193,243,134,8,
245,228,171,177,69,83,16,249,249,50,90,155,165,15,45,102,172,106,211,28,107,14,177,216,41,91,17,62,240,224,26,173,
22,88,123,127,215,185,243,23,74,21,107,29,26,183,125,216,98,226,70,108,61,221,126,121,48,238,44,168,181,235,30,230,
177,205,140,159,145,212,216,226,87,216,203,31,118,100,77,77,147,35,103,127,21,254,236,125,92,13,154,156,222,227,191,39,
34,15,55,195,131,248,179,12,181,248,184,33,224,203,2,211,178,182,109,196,55,110,80,252,103,139,9,235,145,210,209,231,
58,248,49,9,152,96,250,120,98,7,25,59,249,94,13,255,100,26,74,163,9,172,168,218,200,246,149,247,195,36,223,124,
204,26,36,212,83,172,124,67,128,81,142,73,233,83,76,206,55,155,12,153,71,187,58,128,104,234,194,28,195,251,199,78,
222,130,228,230,118,71,241,123,218,189,45,228,130,37,217,208,206,227,98,227,79,231,208,238,131,186,50,14,26,226,13,233,
49,30,220,12,163,120,130,15,188,232,74,170,39,160,120,92,206,228,229,115,35,158,191,47,241,130,220,249,47,21,181,106,
110,123,151,137,46,147,15,2,138,233,88,212,176,160,174,163,95,144,85,93,18,88,148,224,126,48,176,113,61,135,223,51,
160,10,67,229,40,208,147,173,113,107,145,254,180,253,146,163,12,225,214,236,198,245,78,236,91,140,159,43,131,195,45,215,
189,107,133,231,118,153,107,243,212,39,29,150,30,175,149,218,237,187,184,35,176,85,3,132,51,66,40,211,127,83,192,115,
160,85,64,68,94,219,89,191,189,116,251,212,149,49,192,239,2,7,137,109,253,22,121,224,250,98,157,12,216,196,147,74,
5,139,55,175,108,254,240,125,210,201,74,251,121,7,246,161,253,188,73,90,59,35,140,204,118,199,127,187,171,118,187,25,
222,66,190,160,233,8,36,178,213,239,153,245,16,40,85,90,236,15,237,61,233,133,47,176,70,223,7,111,182,206,107,46,
32,51,143,224,107,248,217,92,203,59,36,68,10,163,237,129,93,254,87,66,107,119,117,240,64,213,204,107,194,156,63,144,
204,204,102,127,5,22,33,248,32,250,217,132,196,20,130,235,169,46,174,111,120,167,182,179,127,71,50,83,213,31,144,153,
196,210,46,54,243,172,85,178,93,135,246,182,125,86,217,2,138,87,252,188,88,91,158,49,169,1,226,241,56,35,140,12,
181,98,70,4,96,109,224,126,250,134,235,117,80,35,42,29,124,184,137,108,67,99,243,213,254,222,74,185,203,131,229,230,
182,39,154,14,95,242,226,179,106,222,204,46,66,45,38,108,64,34,185,193,58,38,200,87,26,182,98,133,114,103,131,62,
83,80,247,237,57,53,174,149,107,125,94,55,222,64,170,122,77,239,49,169,132,47,93,125,106,43,160,173,133,79,120,86,
135,165,199,234,180,82,17,250,209,36,208,250,199,9,244,228,44,235,194,6,168,231,107,124,226,242,241,78,207,223,181,53,
100,69,249,188,235,151,71,33,125,133,112,62,233,0,27,79,64,239,217,129,245,82,71,212,136,159,178,58,5,162,213,160,
245,114,249,194,89,149,24,34,15,153,137,234,48,4,164,116,138,192,240,179,248,117,24,84,130,159,175,55,151,247,138,123,
215,8,111,190,53,33,221,199,209,169,79,61,234,50,233,50,2,239,233,18,157,2,133,70,205,203,204,157,155,194,202,241,
84,252,55,59,235,44,233,130,171,5,210,19,237,194,226,10,40,117,129,11,11,140,166,29,19,28,239,228,92,74,47,126,
95,210,213,148,15,239,219,30,143,172,44,164,63,49,57,152,36,33,17,235,27,111,107,245,213,182,58,188,56,95,6,219,
218,45,60,132,20,150,14,208,124,232,93,202,176,77,69,114,195,173,13,7,204,208,57,45,15,178,18,44,188,195,110,150,
209,242,4,88,203,251,210,171,109,159,231,144,119,250,33,144,174,70,220,99,51,158,224,247,79,40,157,234,199,19,138,23,
128,38,88,151,53,126,216,179,137,115,255,68,216,34,59,64,177,109,100,95,100,52,12,153,248,191,224,194,170,248,119,53,
153,13,71,127,77,64,110,206,6,127,50,57,136,36,225,13,69,7,105,235,174,212,253,141,138,223,15,220,41,150,126,141,
239,128,54,244,182,152,35,38,177,41,190,237,7,148,64,226,188,46,141,13,108,54,136,230,139,245,149,112,16,211,165,161,
140,214,155,104,29,20,149,7,190,223,186,110,189,188,166,241,70,37,63,40,163,241,182,180,9,105,158,15,5,16,117,121,
93,131,203,41,172,239,84,196,225,114,191,148,24,154,86,142,163,234,40,247,74,148,70,226,13,187,55,198,62,169,42,241,
66,103,179,51,7,218,163,0,95,227,99,36,157,231,204,102,253,216,63,121,200,139,148,168,154,151,2,173,110,20,168,192,
114,106,218,190,144,82,151,244,190,9,241,170,192,72,157,36,49,120,30,38,146,223,191,84,234,144,29,214,122,142,64,246,
134,54,44,151,151,133,5,133,116,177,5,20,136,116,221,114,143,14,52,190,187,220,163,73,146,104,160,143,137,232,99,146,
133,91,91,124,52,5,18,98,133,209,150,232,49,171,235,188,21,7,150,141,67,163,182,69,239,147,167,206,173,163,228,235,
219,168,129,197,197,235,167,83,170,228,223,213,100,53,192,21,240,245,131,204,142,19,206,229,21,11,36,178,205,141,7,207,
165,203,50,59,45,63,93,179,242,253,105,252,28,255,209,101,154,64,144,90,73,127,202,204,67,80,211,78,169,27,1,85,
4,115,169,177,229,159,177,147,127,210,218,198,213,84,99,65,46,106,175,202,200,222,135,116,48,201,210,191,49,164,23,250,
105,246,16,214,120,38,5,166,141,212,74,49,10,108,238,164,5,7,80,196,176,69,116,65,10,30,191,71,120,179,23,218,
134,182,204,7,173,242,93,197,182,126,203,2,215,152,180,199,45,39,109,38,122,8,193,154,81,58,122,67,170,160,166,87,
69,43,251,134,173,139,160,180,156,228,250,41,93,65,167,11,210,251,231,71,140,235,204,254,111,74,221,212,232,195,38,94,
161,128,174,162,25,50,102,88,96,97,101,111,159,168,176,103,195,209,142,40,44,196,252,4,97,63,142,10,107,189,153,6,
42,231,83,74,7,239,147,74,7,175,26,23,99,103,191,51,102,158,33,55,28,35,146,30,64,32,76,27,5,29,238,177,
93,225,118,143,196,114,243,234,140,233,11,158,135,248,36,245,43,214,212,191,147,118,19,64,217,107,231,213,231,232,74,163,
232,209,43,81,147,193,243,16,248,145,161,223,196,91,101,224,12,20,144,50,20,220,12,153,165,210,226,130,204,60,66,110,
193,225,73,74,59,7,173,20,180,84,120,62,199,38,137,15,228,230,118,135,177,118,61,19,44,36,44,209,148,186,91,89,
48,124,119,37,36,16,75,123,83,247,160,107,41,43,207,18,241,189,106,114,180,37,6,38,91,153,236,14,1,86,38,86,
52,131,96,232,158,34,98,7,16,252,9,85,130,80,45,215,104,208,108,84,191,231,4,20,220,109,76,141,10,4,80,157,
35,59,34,46,95,240,181,145,163,119,229,243,247,41,117,13,121,93,34,95,83,91,107,249,111,7,118,181,121,82,149,52,
178,106,208,120,33,177,28,186,50,153,234,144,88,50,121,169,145,60,161,120,117,189,212,225,197,208,176,71,11,17,240,152,
10,198,196,222,192,218,229,12,52,223,33,105,18,3,33,130,22,15,190,89,143,248,30,79,77,92,235,93,150,24,154,238,
225,139,245,22,242,4,194,177,248,0,28,197,225,241,222,77,184,220,209,180,105,169,14,36,240,49,33,206,11,239,255,45,
49,237,28,222,27,114,94,65,59,21,201,12,182,80,234,54,136,74,66,123,212,216,200,206,227,40,157,83,75,224,144,0,
114,133,180,57,252,185,99,152,170,68,47,51,207,250,55,59,175,185,72,134,216,241,103,128,5,22,212,245,139,18,19,23,
255,43,120,60,54,225,185,154,0,5,71,88,6,99,249,180,134,101,16,22,247,247,153,8,216,104,208,135,192,161,14,17,
111,122,247,84,183,236,156,203,85,203,102,208,182,143,183,54,164,227,97,77,252,95,112,67,144,209,228,94,164,222,64,35,
17,255,178,95,166,111,69,183,59,24,9,26,37,105,255,104,50,214,150,188,218,244,126,138,201,246,23,88,31,204,122,151,
80,85,239,158,22,106,225,19,126,79,237,139,46,32,147,249,177,232,111,100,229,223,36,135,33,22,210,137,161,13,108,66,
154,231,102,108,190,69,196,146,1,95,179,99,147,36,8,172,197,48,253,26,62,246,239,52,152,76,38,3,248,143,127,186,
131,60,226,122,60,229,242,232,94,41,46,229,228,76,215,90,168,56,28,206,41,124,120,143,170,43,218,174,149,133,116,239,
207,155,91,61,46,36,160,237,86,67,86,131,46,67,164,167,52,223,67,172,113,15,104,47,235,174,64,181,23,52,86,113,
42,231,251,172,244,85,206,39,147,22,146,211,118,225,115,192,119,13,205,105,48,49,124,65,145,189,77,132,11,57,201,208,
51,130,196,248,0,89,65,167,50,219,6,177,16,124,236,77,145,239,1,205,229,112,121,95,133,126,52,153,200,248,194,103,
36,205,63,80,218,199,201,23,202,244,127,132,194,18,18,110,6,24,83,104,17,41,148,42,160,72,165,206,53,158,49,49,
50,16,29,180,52,215,251,143,210,82,47,130,234,130,141,138,230,196,79,250,118,247,204,205,37,164,237,86,67,30,175,78,
19,175,212,216,114,175,186,190,190,136,144,54,119,24,242,120,95,107,56,196,104,75,221,160,197,34,49,215,6,83,85,229,
220,172,227,35,240,27,83,228,111,202,112,55,113,13,184,146,252,195,25,98,190,221,192,244,145,8,147,227,84,198,13,69,
142,113,213,110,128,22,230,94,13,238,146,242,69,195,154,128,54,166,120,242,198,51,21,91,166,134,118,30,167,59,46,63,
69,228,243,33,141,208,57,146,158,187,184,58,153,118,229,96,167,200,252,184,187,231,19,185,76,176,152,170,217,219,3,170,
156,201,224,229,110,116,234,216,111,137,68,124,187,21,84,174,85,39,192,167,39,102,180,108,32,42,43,74,221,5,202,177,
26,4,76,113,63,3,27,215,227,208,148,155,196,70,130,72,112,204,248,117,72,168,39,95,85,142,137,47,149,24,152,100,
66,240,132,152,175,20,63,115,120,191,111,17,95,36,89,70,122,93,203,76,172,104,183,72,96,250,231,196,92,12,137,243,
246,35,125,149,19,4,112,109,9,175,35,232,94,147,6,157,193,212,227,91,72,70,59,95,123,25,89,250,54,188,203,4,
238,0,1,214,65,145,247,33,189,172,202,45,30,233,156,239,107,144,243,125,131,42,191,23,70,237,135,161,129,104,209,138,
249,77,81,114,146,19,212,91,119,53,51,145,212,198,215,80,200,164,130,21,243,190,105,248,160,128,64,38,67,133,189,26,
12,180,170,240,2,25,193,117,242,77,176,12,192,132,49,83,172,80,238,80,88,216,31,80,58,120,31,51,113,9,248,207,
212,45,240,34,150,203,213,33,198,206,126,215,176,198,241,148,84,102,3,16,106,112,247,177,16,136,25,130,77,244,178,239,
30,162,10,108,150,13,26,42,145,239,162,211,156,254,69,248,61,160,137,141,159,54,44,69,185,185,221,161,132,185,127,18,
115,195,64,62,55,254,92,184,54,38,21,136,178,138,210,5,75,63,46,143,63,25,91,45,251,156,154,117,120,216,118,214,
175,196,170,200,192,149,208,116,216,98,104,122,180,162,148,223,53,26,175,151,199,164,44,22,72,163,99,10,51,32,155,163,
39,227,155,79,35,44,112,149,81,27,74,125,159,91,40,4,7,41,117,230,146,118,125,201,152,76,224,143,193,211,38,54,
64,160,41,250,120,26,253,67,213,190,14,234,224,11,27,210,45,213,45,251,222,249,180,42,231,237,150,219,157,236,35,237,
118,39,163,212,89,4,179,177,134,121,10,18,178,225,118,2,240,111,65,199,50,200,21,4,243,45,101,213,89,186,35,86,
117,10,221,184,103,103,30,153,226,137,173,247,145,67,227,132,215,146,205,153,219,55,190,128,171,111,200,101,6,20,33,104,
144,206,244,133,208,198,245,67,109,192,133,1,153,18,100,10,75,238,163,240,254,211,160,205,228,115,159,164,254,88,250,85,
73,124,219,15,40,174,151,58,162,4,198,0,8,151,104,71,55,38,211,192,58,40,42,23,143,67,211,82,201,22,177,30,
113,61,158,145,204,99,238,132,215,125,88,223,175,225,80,42,241,105,87,245,113,121,85,232,207,123,6,65,87,183,22,233,
143,236,195,91,23,90,248,132,223,198,123,240,152,80,166,191,150,195,225,12,98,130,192,90,35,225,216,94,93,220,31,129,
121,190,102,73,228,35,115,51,189,189,84,213,239,83,170,22,40,213,221,194,218,69,52,180,188,118,246,80,135,167,36,93,
12,175,246,227,181,209,70,63,94,240,57,54,21,201,12,54,66,240,7,242,102,161,139,147,250,218,154,82,215,192,236,46,
83,85,86,221,66,40,200,5,239,102,96,227,2,215,197,152,149,53,133,161,165,30,180,214,35,69,188,80,165,229,208,176,
77,33,69,246,230,139,23,7,61,95,172,247,29,28,140,196,114,85,75,231,172,18,146,210,107,136,228,237,14,240,121,144,
247,140,45,178,165,101,98,30,100,137,151,177,92,52,21,123,218,92,219,234,106,192,44,90,209,128,222,201,112,59,70,189,
180,17,37,22,62,97,119,249,98,233,82,134,128,137,167,220,58,53,9,183,188,122,245,100,50,104,119,197,223,140,15,45,
84,200,133,107,25,159,162,174,35,218,199,83,121,230,207,204,214,143,181,65,186,47,110,160,112,37,126,3,133,18,155,129,
227,45,124,195,179,34,255,183,28,117,217,124,171,212,21,40,117,179,51,89,211,17,75,16,214,234,203,235,240,22,6,77,
164,137,248,6,75,71,219,45,236,15,17,206,98,208,192,209,196,197,255,18,164,168,125,72,61,25,52,164,11,233,110,74,
71,159,43,212,235,41,129,205,28,35,146,30,210,93,217,106,245,213,85,133,47,246,98,234,218,75,244,33,99,100,231,113,
145,82,23,253,16,37,95,137,202,82,186,253,215,45,113,116,32,41,251,98,122,241,152,97,129,5,50,169,96,165,142,147,
111,164,155,179,193,137,204,117,45,31,21,106,129,116,75,223,185,38,35,116,231,26,211,188,199,94,36,211,223,224,147,248,
241,243,206,171,206,98,82,42,170,219,61,91,65,163,200,204,67,30,113,221,193,93,211,145,195,121,57,140,2,9,157,137,
242,57,92,155,66,204,205,128,199,19,170,204,240,193,54,5,91,18,100,163,157,234,11,45,211,189,218,124,244,156,148,11,
166,214,144,46,115,161,163,75,84,50,116,34,235,31,152,58,242,53,5,206,204,35,248,42,164,196,213,214,198,56,61,203,
8,188,71,215,157,69,40,122,234,30,164,112,12,128,64,95,99,138,67,136,123,165,122,124,138,203,225,12,159,58,174,62,
77,188,224,211,204,186,144,86,60,110,68,80,129,129,190,112,131,14,70,21,193,167,155,224,229,110,244,79,230,218,150,143,
10,180,68,186,180,127,247,10,125,203,48,148,184,146,186,101,216,154,103,96,190,205,42,117,50,106,180,226,14,138,221,144,
143,18,55,231,161,228,173,121,168,203,142,124,212,45,179,212,2,216,85,106,1,212,234,13,171,14,116,25,59,251,129,214,
96,95,102,60,228,82,99,203,95,160,124,151,20,241,130,201,232,24,209,174,108,183,44,82,16,192,165,149,116,3,152,61,
69,31,14,241,98,2,234,190,61,155,78,119,227,139,36,75,168,242,243,217,197,34,185,225,166,152,9,235,233,30,24,181,
134,92,119,170,247,93,250,246,124,212,9,239,195,132,77,185,168,197,186,92,212,100,117,14,10,89,145,141,188,191,203,66,
174,75,115,145,89,191,85,136,167,111,6,41,165,68,139,90,66,219,182,178,203,185,115,54,149,38,27,32,95,232,99,59,
115,114,88,145,149,165,116,31,19,105,231,234,0,233,194,132,15,104,212,192,226,202,190,237,241,143,181,74,186,120,12,206,
31,233,136,66,131,204,46,148,67,24,239,3,35,174,212,112,181,97,199,73,200,122,238,93,100,61,47,11,217,204,187,143,
236,230,223,71,206,139,178,144,231,146,44,84,111,121,54,10,91,153,141,154,253,152,131,90,173,207,69,73,155,115,105,82,
78,223,158,135,186,226,197,209,189,244,162,169,37,196,12,155,48,122,244,42,36,208,147,255,80,78,46,109,176,117,80,100,
54,185,204,137,66,212,110,241,223,72,95,229,12,85,134,166,90,88,127,206,38,174,245,174,166,172,58,87,231,173,148,87,
202,173,49,233,66,206,46,38,214,237,21,90,193,106,77,176,189,67,227,132,135,80,25,87,83,227,83,222,254,128,125,3,
251,39,13,239,163,78,91,242,176,178,147,139,98,241,254,106,186,38,7,53,248,33,27,249,47,203,70,30,120,255,57,45,
204,162,247,163,53,222,151,42,144,185,204,159,32,179,110,33,105,253,14,5,212,203,114,113,34,144,219,90,203,246,252,182,
53,14,105,204,118,134,128,75,54,175,108,254,40,200,223,228,60,16,30,85,179,37,179,174,18,9,127,113,106,7,231,172,
51,7,218,63,213,38,233,106,242,119,87,47,110,6,249,187,75,168,170,87,17,9,56,124,225,4,69,236,167,207,85,179,
111,35,235,249,89,244,228,106,68,85,90,230,170,255,173,52,41,187,227,69,225,135,23,7,156,192,141,87,229,160,232,181,
185,40,126,67,46,106,199,104,203,176,160,186,150,213,152,117,136,156,189,19,62,126,14,41,78,140,169,174,54,91,132,116,
92,102,104,80,198,40,114,149,106,88,11,109,60,120,14,226,10,132,211,137,39,85,171,139,60,210,212,110,134,15,199,167,
155,190,254,26,242,79,254,172,132,233,27,241,54,5,68,42,16,75,151,193,197,173,234,107,143,10,181,163,169,238,122,93,
99,205,216,193,16,43,222,15,73,120,95,196,225,253,17,181,54,7,53,194,251,37,24,239,27,95,172,185,186,47,126,73,
174,54,229,144,171,245,155,100,65,46,50,74,159,137,40,30,127,52,87,70,168,87,150,80,72,243,74,191,255,13,14,40,
41,75,104,64,196,167,247,183,123,218,61,213,45,199,64,95,4,229,123,141,40,194,149,53,111,1,144,125,119,103,71,253,
35,223,78,12,45,194,90,249,115,109,147,46,72,246,197,116,148,145,236,10,38,107,60,167,10,39,28,135,71,15,85,156,
196,191,85,142,213,212,243,175,145,238,187,136,170,204,34,161,137,25,47,30,251,5,47,137,217,231,187,108,20,244,61,104,
204,57,248,36,87,155,75,173,55,230,161,118,63,169,23,99,234,118,245,226,236,166,209,156,119,85,44,68,47,133,92,125,
30,153,186,7,93,165,212,181,246,175,22,77,24,154,237,34,121,53,12,104,102,46,81,201,218,170,118,226,241,49,169,68,
141,90,161,211,166,52,169,118,148,16,233,135,206,99,118,97,173,138,120,66,241,44,38,199,252,93,96,3,55,135,4,164,
124,86,146,250,227,37,117,160,234,13,218,239,43,100,90,134,80,53,154,42,172,219,212,109,121,168,227,22,53,169,198,111,
204,69,49,120,125,71,96,141,53,12,107,172,129,216,82,244,94,154,133,220,202,16,171,117,101,201,245,141,196,155,131,76,
7,111,65,60,185,201,15,164,173,127,167,160,0,147,243,255,30,104,143,202,18,27,252,29,252,190,171,22,53,123,212,56,
204,226,138,72,200,155,65,169,219,204,9,180,76,184,109,141,149,226,45,152,0,179,15,236,166,187,141,149,144,206,211,125,
83,153,176,131,157,98,31,85,245,86,144,166,124,99,219,223,77,135,108,167,39,207,186,42,147,175,17,32,111,248,172,249,
217,72,53,231,46,109,6,89,149,18,248,187,245,236,91,200,6,139,221,156,91,200,113,222,45,228,58,255,54,242,92,120,
27,249,47,185,131,130,151,221,65,225,223,223,65,17,43,239,162,230,171,239,162,184,181,247,80,194,250,123,168,253,198,251,
40,121,115,22,74,195,139,28,22,59,237,222,200,172,64,227,216,245,186,175,236,245,108,134,34,4,62,63,172,45,173,45,
39,31,210,223,202,191,201,61,82,151,124,130,118,5,85,118,134,182,238,167,41,117,243,39,210,176,50,180,243,56,67,170,
179,215,11,146,171,105,129,40,190,38,245,12,191,23,20,177,180,250,122,59,242,140,239,249,76,102,170,130,108,158,14,20,
115,211,70,37,96,193,19,136,166,91,5,68,228,68,12,93,136,192,53,67,191,239,238,7,168,251,174,34,212,117,103,33,
202,200,44,192,26,106,62,182,216,242,81,123,76,168,9,180,150,154,135,154,51,132,26,190,18,124,172,57,180,27,192,115,
105,54,114,213,144,234,130,44,172,116,100,209,174,58,85,89,107,145,196,222,122,3,241,154,141,216,131,248,74,235,173,20,
225,242,115,142,72,196,155,12,197,20,21,221,218,0,255,126,249,68,167,103,51,39,135,61,8,11,49,187,168,39,225,47,
196,191,7,161,99,99,66,169,22,64,228,208,64,165,167,153,137,100,71,199,4,199,123,91,87,199,60,206,186,144,94,92,
29,90,110,105,25,220,215,7,204,227,222,114,217,251,159,45,140,73,242,177,34,102,192,51,235,185,247,8,44,128,44,154,
108,45,39,157,66,202,30,139,144,162,229,160,103,210,240,212,66,189,144,118,249,122,193,73,111,21,73,25,129,127,147,130,
132,36,229,203,235,39,229,25,132,180,45,50,75,24,94,226,58,255,22,242,194,139,29,220,27,160,69,131,31,12,76,182,
102,120,67,128,166,209,10,155,113,109,55,229,210,218,71,7,188,105,82,24,119,7,4,8,95,37,236,2,228,219,97,32,
92,10,217,139,83,234,82,72,166,119,192,192,192,212,225,168,23,108,252,157,85,119,137,168,171,169,22,65,202,218,60,74,
59,109,78,163,156,34,218,61,32,85,52,1,105,87,80,118,91,221,69,49,47,4,91,34,16,244,108,191,228,40,106,61,
125,47,130,11,69,161,80,1,42,8,37,134,166,187,241,251,246,40,39,231,186,82,134,52,228,169,11,36,210,197,230,94,
13,206,121,38,244,125,236,211,111,46,242,30,157,137,60,191,62,130,220,103,158,71,46,179,175,32,167,57,215,145,253,156,
27,88,73,184,129,172,103,221,192,74,195,13,100,53,179,124,81,105,100,214,155,228,38,178,198,202,136,90,49,201,34,75,
188,195,118,34,158,161,229,70,138,124,3,35,202,59,44,196,252,234,217,195,29,80,193,213,140,10,131,78,152,128,75,174,
96,2,94,62,55,226,17,38,199,187,246,182,242,125,124,62,119,18,254,253,214,76,22,132,226,29,31,78,200,144,118,0,
150,110,82,169,96,169,191,183,242,244,160,62,62,121,123,55,181,122,114,31,107,217,85,189,186,231,125,114,119,255,218,217,
26,185,58,25,28,174,132,121,85,161,182,43,48,119,57,104,62,106,31,77,152,85,213,114,85,88,131,53,234,50,11,137,
28,130,46,112,132,18,240,99,118,98,92,63,193,4,164,30,150,47,229,205,251,149,148,245,57,151,118,113,104,252,207,182,
140,171,195,17,107,33,224,238,0,51,15,2,20,16,5,6,45,37,8,107,43,65,243,206,35,35,207,240,203,229,100,198,
136,5,10,227,159,26,142,223,130,58,108,45,164,77,72,240,85,119,222,86,134,192,25,18,239,198,16,121,247,10,34,211,
180,123,36,51,23,110,183,120,162,141,10,67,166,9,204,72,8,48,245,34,144,205,208,11,46,73,156,247,39,50,243,172,
95,164,116,240,190,172,116,244,169,9,185,104,100,239,249,175,129,181,203,65,61,35,243,76,158,80,4,57,214,189,25,75,
150,100,23,62,56,113,161,255,68,27,138,39,24,203,81,152,174,229,91,184,237,23,58,6,255,43,242,108,122,93,226,215,
242,158,36,32,62,91,47,176,13,9,201,209,11,74,200,149,134,117,46,52,236,56,169,216,234,219,75,228,200,23,92,13,
3,55,34,174,212,104,153,54,14,118,142,80,200,157,240,229,168,96,244,54,13,147,33,96,58,239,247,200,47,9,79,231,
125,211,240,97,215,20,215,172,208,32,179,179,42,75,233,110,104,186,195,225,80,163,33,231,15,75,6,150,100,44,157,153,
147,244,83,76,212,83,140,12,69,171,157,29,244,255,108,222,84,117,101,72,63,223,252,117,203,162,30,159,63,210,241,25,
4,245,10,171,89,195,125,225,219,189,148,142,250,246,240,132,20,178,158,6,250,239,95,45,200,81,247,35,232,44,143,236,
243,132,136,182,59,231,14,50,72,28,93,204,149,26,254,136,63,215,67,11,147,207,231,202,148,203,77,62,89,87,105,151,
72,121,38,159,10,127,134,241,128,13,136,43,55,94,89,142,75,202,89,236,26,126,197,230,155,115,200,1,19,183,134,188,
93,74,17,184,215,210,44,58,32,2,36,14,62,188,96,172,121,215,95,161,214,190,193,12,5,13,28,82,126,64,11,143,
90,155,135,34,230,159,70,74,151,122,224,102,80,105,65,219,21,138,228,70,27,162,39,109,65,93,118,22,209,169,71,26,
129,67,162,172,148,254,255,26,129,3,69,35,233,153,69,168,201,200,239,65,59,95,206,4,172,106,66,236,152,12,5,67,
70,1,170,174,172,37,32,98,125,102,158,156,152,181,236,69,80,160,176,163,33,71,36,93,99,220,235,59,114,238,189,5,
185,72,217,109,1,226,240,4,227,121,114,19,173,12,140,3,116,249,58,184,167,45,122,87,243,30,126,174,72,173,153,150,
92,59,149,252,236,240,207,109,159,111,90,17,253,104,238,215,225,69,147,71,135,60,253,252,83,255,7,216,116,207,251,172,
191,111,254,232,97,245,30,79,29,31,250,100,201,172,198,69,187,55,196,62,61,253,103,187,103,119,206,166,130,43,161,68,
147,71,92,19,132,171,113,165,108,89,21,3,45,32,119,17,240,237,234,241,12,44,182,152,14,222,90,245,201,95,144,141,
140,63,250,30,242,8,183,85,209,252,123,99,69,150,200,185,193,69,171,175,255,35,163,37,224,207,80,180,26,2,238,154,
174,76,128,145,241,51,208,134,80,186,162,229,160,231,111,204,238,40,39,219,227,21,41,237,211,3,146,239,181,20,113,197,
178,153,90,114,51,40,69,214,94,199,28,167,28,67,238,75,114,232,232,248,11,89,82,142,44,126,93,220,74,203,146,92,
100,218,126,52,52,197,233,201,229,241,41,22,132,45,20,107,111,138,35,16,77,82,118,95,64,19,38,25,226,205,70,250,
241,195,138,105,37,146,203,35,255,208,140,79,179,91,183,206,110,143,238,157,75,171,52,17,194,207,3,17,3,137,65,103,
47,16,112,77,0,177,50,228,90,66,255,251,117,245,207,84,228,210,168,110,129,155,38,174,156,232,132,90,70,219,192,141,
169,209,4,10,38,26,232,5,196,101,171,102,92,83,251,102,171,224,215,85,77,191,130,176,73,118,31,127,102,184,118,74,
82,232,205,223,153,246,69,207,35,67,186,86,223,92,64,98,247,38,208,29,204,237,53,205,90,106,244,189,201,39,107,201,
105,35,216,162,144,69,244,120,196,184,186,180,1,47,137,79,243,219,86,120,46,85,111,59,32,222,65,96,124,228,81,125,
224,210,207,120,150,38,181,2,11,129,133,203,65,243,209,127,86,221,197,167,81,10,102,221,68,122,129,109,115,24,183,156,
246,10,21,140,12,69,171,22,76,107,132,10,174,233,6,49,86,135,140,25,86,175,4,2,140,85,141,90,74,252,90,64,
26,217,56,163,212,111,9,104,187,57,200,108,228,207,16,77,221,73,105,175,95,50,159,43,195,100,216,159,16,25,210,169,
55,91,65,67,95,79,189,222,60,222,94,228,84,255,130,213,87,255,18,211,172,45,39,157,68,66,187,128,211,148,246,74,
220,99,100,77,123,62,182,158,119,143,88,86,138,188,89,47,56,40,98,89,142,36,207,93,28,190,112,170,126,235,17,197,
100,2,218,247,105,242,182,24,119,8,9,44,221,181,213,255,227,213,83,222,219,195,232,31,72,171,170,238,0,87,77,184,
24,54,44,143,66,54,42,217,47,4,2,106,0,35,124,226,254,101,49,230,64,213,79,220,133,185,180,155,129,35,148,76,
19,251,198,104,107,174,29,68,206,161,4,201,16,155,101,109,70,66,54,195,71,216,228,43,229,248,166,173,136,78,242,232,
126,79,73,70,155,141,251,172,64,92,137,124,190,54,252,148,140,155,164,167,65,194,23,37,228,252,133,57,200,160,253,4,
112,53,12,229,74,13,89,170,172,58,184,140,223,184,33,87,79,255,7,121,228,71,143,173,190,189,72,48,176,6,254,221,
121,136,35,16,127,109,152,58,77,187,111,194,20,85,36,198,70,219,100,159,255,187,67,157,213,124,33,136,119,120,111,91,
20,92,207,20,162,239,97,132,134,47,76,47,56,41,151,78,109,33,48,233,38,253,127,196,196,162,248,145,137,14,195,78,
53,32,40,16,193,238,170,136,249,228,25,41,109,206,106,218,37,36,246,138,186,5,89,50,101,157,26,120,99,44,54,233,
187,138,156,155,1,11,4,48,241,103,183,211,202,142,150,27,3,249,254,207,40,125,6,57,127,33,163,65,137,156,27,128,
43,6,110,171,133,235,218,29,153,128,147,149,142,136,138,170,184,82,85,68,113,121,253,56,66,189,233,28,145,244,219,154,
20,174,88,62,3,130,194,2,115,231,253,122,129,109,114,149,61,23,35,213,204,235,68,83,201,32,155,72,27,229,194,111,
246,254,241,56,67,123,164,185,61,190,121,166,51,237,7,173,75,164,11,135,201,185,195,29,80,124,11,91,104,234,156,218,
48,212,156,64,90,8,125,131,71,95,131,164,177,132,200,37,11,169,166,93,70,250,241,195,159,98,173,244,146,208,198,231,
136,208,218,251,16,65,57,40,180,245,189,110,58,104,19,49,55,131,217,80,58,223,17,18,205,203,94,103,98,35,116,8,
252,207,114,242,105,114,110,134,41,103,144,200,49,248,44,69,254,202,28,117,222,155,107,67,10,111,240,175,137,70,200,153,
103,183,24,123,8,97,77,186,88,47,56,49,87,236,17,113,85,228,18,118,1,207,241,121,176,62,106,90,240,252,93,100,
50,144,202,131,7,158,199,27,202,110,243,233,160,102,141,202,71,203,17,172,93,139,177,7,233,28,95,245,28,17,206,223,
29,177,23,241,141,109,127,102,180,234,106,131,84,79,194,159,62,164,159,239,243,187,231,82,107,52,235,128,52,233,66,15,
226,244,142,46,15,121,92,206,103,20,185,106,20,14,54,123,231,18,213,234,128,164,230,222,67,86,83,207,33,203,47,143,
35,203,137,199,200,202,164,147,136,238,33,65,202,140,78,26,3,102,244,0,142,168,180,75,154,214,20,18,229,205,122,63,
33,230,43,197,223,101,210,111,13,226,234,25,124,71,105,33,169,29,128,181,29,138,43,150,205,48,254,248,7,178,196,203,
104,190,180,204,185,141,173,132,203,244,252,66,86,73,205,202,89,122,61,72,124,91,228,129,233,94,65,154,100,15,136,240,
219,44,204,83,91,1,53,42,57,47,170,56,181,85,181,166,104,49,0,178,115,122,113,248,213,127,187,188,161,66,46,92,
60,242,83,255,98,53,249,102,212,9,210,5,77,94,40,228,141,163,42,95,18,249,38,136,120,70,170,109,230,159,255,162,
133,141,154,245,114,179,18,21,82,26,2,214,206,103,92,133,12,12,184,191,47,160,172,213,142,9,108,46,104,40,36,15,
36,112,145,224,207,78,209,150,9,40,246,104,162,214,120,123,127,71,126,62,95,171,74,212,1,193,239,104,49,250,47,132,
77,247,63,42,112,53,8,121,10,147,31,77,7,109,214,242,120,232,128,44,200,70,230,95,252,129,4,150,110,71,40,237,
148,161,191,19,140,129,124,65,243,5,183,67,109,245,249,194,115,95,56,210,17,117,73,118,121,40,18,242,38,80,234,59,
207,136,70,85,5,86,238,7,44,198,29,214,234,41,172,155,11,85,147,129,97,179,139,122,189,250,201,82,104,235,119,202,
242,203,19,196,220,12,160,157,137,92,26,92,162,180,120,85,21,79,237,227,29,5,157,169,136,249,120,117,124,14,141,210,
166,67,161,192,56,161,125,189,242,134,196,89,236,218,240,10,104,231,68,75,114,117,81,230,222,69,242,232,190,112,176,247,
198,135,111,141,70,15,13,193,237,208,45,213,237,241,185,191,59,212,186,108,7,120,222,163,191,37,162,182,173,236,242,249,
124,238,240,114,124,144,68,198,72,104,235,123,20,92,2,31,34,241,26,118,248,18,97,237,115,24,54,255,203,142,75,188,
172,73,183,71,234,94,196,164,74,56,55,32,174,76,89,94,101,28,193,232,26,237,193,232,162,223,122,120,113,157,215,240,
52,129,164,208,142,16,72,138,120,173,22,69,157,239,93,110,241,75,93,92,203,224,59,198,214,235,158,234,72,33,123,39,
159,47,144,86,203,40,155,156,63,118,196,211,26,164,174,251,125,225,249,64,160,42,173,65,176,217,117,136,226,107,113,179,
234,11,173,189,255,6,223,233,135,69,188,89,116,52,89,175,94,235,108,234,245,155,170,57,16,1,87,246,88,76,208,205,
144,141,244,153,202,56,138,163,245,106,215,16,189,160,132,28,34,89,42,186,44,144,109,49,22,242,85,221,14,86,64,54,
144,239,189,226,125,202,202,107,219,56,128,53,37,241,137,129,98,170,230,213,176,190,222,61,225,30,2,37,222,30,70,103,
22,78,107,132,160,194,77,87,93,15,160,229,222,248,39,5,77,250,34,184,196,222,86,254,23,165,190,77,67,155,57,33,
98,190,177,237,78,243,255,253,70,251,136,62,28,109,55,27,153,143,250,29,241,77,237,127,165,212,77,146,74,195,76,96,
237,125,204,98,194,81,50,135,209,139,202,184,198,229,85,198,105,197,210,227,155,57,253,1,254,190,58,61,167,152,76,149,
93,231,34,142,64,52,197,116,192,250,242,198,129,108,241,139,78,146,174,186,25,21,196,14,56,60,193,24,138,112,11,200,
170,91,96,234,67,192,19,26,221,64,121,49,221,219,225,170,238,148,0,107,14,130,61,155,98,81,98,156,125,190,84,143,
15,205,156,109,180,61,46,118,171,17,164,148,125,3,109,27,63,8,159,96,105,55,67,202,84,132,77,243,47,248,198,54,
175,87,126,53,76,123,0,141,126,136,153,129,208,148,90,97,90,94,101,28,121,63,175,1,212,212,112,6,65,36,159,104,
170,146,174,9,158,31,105,120,106,145,90,203,227,148,183,225,59,201,155,19,44,126,209,65,210,165,155,81,181,27,7,153,
50,43,40,178,55,139,107,161,68,143,195,233,230,233,102,120,250,203,81,193,37,144,23,75,247,96,168,33,13,24,190,23,
228,196,190,68,52,244,19,191,231,14,118,138,253,248,25,219,86,199,6,45,85,157,21,43,13,75,41,130,147,243,67,33,
94,186,150,61,56,9,82,144,26,149,30,14,199,237,248,32,18,136,191,82,118,157,71,214,205,208,90,93,25,71,85,95,
147,25,43,190,169,195,126,32,252,58,105,102,131,155,1,91,36,2,107,47,184,175,174,188,70,76,80,252,178,132,116,241,
139,46,189,63,184,202,244,19,70,149,112,229,202,117,53,153,197,80,233,178,83,177,136,55,49,44,196,236,234,180,137,161,
72,115,147,5,221,113,172,26,124,184,154,64,223,241,223,19,209,184,17,129,37,254,222,202,255,248,124,46,228,231,154,215,
192,88,40,224,70,82,173,228,126,234,234,166,29,67,167,32,193,33,87,182,171,155,177,192,202,253,16,185,44,15,77,101,
92,36,84,198,121,85,215,132,50,141,220,35,69,78,33,215,204,134,239,38,223,104,91,23,220,12,61,22,35,142,72,175,
162,251,234,200,22,191,232,146,150,11,41,116,227,255,70,178,198,25,143,185,18,249,130,26,226,140,42,215,76,123,137,197,
188,201,112,65,230,231,131,3,138,225,2,77,184,189,184,144,233,70,70,42,16,167,33,91,144,155,255,164,160,204,117,45,
209,160,62,222,207,188,61,140,78,9,4,220,145,76,138,17,167,70,70,65,173,245,214,23,218,250,159,55,27,186,163,238,
109,210,242,82,144,210,103,33,14,95,56,81,242,122,63,137,102,210,6,157,10,172,9,22,104,152,13,205,132,202,184,45,
90,202,74,121,227,204,130,53,35,80,121,157,49,74,155,129,232,126,0,90,78,222,175,206,212,41,200,58,161,224,190,186,
178,193,36,142,22,138,95,106,56,16,172,41,188,128,162,17,104,102,37,180,175,119,145,226,114,251,104,33,189,180,218,9,
216,137,203,229,244,183,81,201,246,194,213,241,83,199,213,71,191,110,137,163,11,23,128,56,161,45,100,17,227,146,128,130,
12,77,230,65,126,153,76,4,186,205,36,254,255,133,76,207,95,32,218,156,75,233,232,226,209,142,104,39,38,91,208,110,
99,34,173,239,90,152,233,193,157,247,25,76,141,57,167,198,7,64,78,7,133,155,11,84,158,255,64,94,164,213,212,179,
234,13,10,126,95,77,209,2,115,119,84,173,95,196,115,110,35,105,131,228,66,170,76,45,187,196,175,37,84,58,77,0,
82,38,215,23,53,7,25,36,210,149,113,159,188,210,128,167,122,225,193,21,203,231,97,173,251,174,97,202,215,200,124,244,
126,166,63,64,246,203,106,170,215,230,56,75,167,45,22,186,195,155,173,95,69,247,213,113,225,125,213,197,47,185,181,103,
93,190,40,12,201,102,136,54,87,29,60,155,126,153,46,3,198,235,168,68,228,26,126,13,107,249,211,32,94,165,11,188,
65,18,112,111,74,40,159,199,25,161,178,148,110,111,18,102,113,181,87,23,247,71,223,140,15,69,235,151,71,161,63,51,
91,211,110,137,203,199,59,209,217,7,183,255,235,76,107,200,183,255,237,140,110,156,78,65,151,142,117,66,255,252,213,14,
253,190,45,30,173,89,18,9,217,9,168,75,178,235,131,208,96,179,11,102,166,146,13,152,220,7,80,234,174,243,18,29,
125,127,119,142,88,54,91,236,218,240,154,126,252,240,98,147,126,171,233,141,10,145,97,48,153,161,95,175,170,244,125,82,
181,77,102,223,162,223,71,96,229,254,55,126,215,178,173,249,141,248,102,78,251,205,63,255,149,254,185,42,127,23,220,199,
53,245,28,146,248,52,191,203,204,121,77,2,210,17,3,241,193,50,22,50,30,36,254,173,178,160,241,59,220,82,0,126,
96,232,76,7,102,57,220,44,13,189,54,212,243,124,93,71,231,240,54,82,246,92,130,128,92,43,32,31,43,161,141,207,
105,104,236,3,190,124,221,95,151,215,233,30,214,144,249,98,57,229,31,122,46,76,63,253,9,25,101,204,70,138,230,253,
159,65,3,39,190,210,122,23,197,229,13,166,212,55,96,240,168,58,14,32,71,184,238,35,22,43,70,131,13,244,133,139,
108,173,229,153,62,158,70,71,194,235,155,95,140,105,102,125,51,190,133,237,45,172,33,223,138,139,177,189,25,29,161,186,
209,32,216,236,188,167,155,225,33,107,43,217,86,185,76,48,135,82,95,37,20,69,169,155,162,8,107,201,123,131,131,208,
29,75,15,174,68,127,33,223,212,225,23,145,67,224,25,177,103,211,27,18,191,216,187,122,1,241,247,177,100,213,74,169,
215,58,11,107,13,185,88,251,156,88,206,123,7,115,101,70,23,37,190,45,8,125,87,124,150,196,59,42,151,43,53,220,
160,99,38,33,52,79,129,50,175,84,14,95,48,145,167,48,93,13,115,140,53,200,19,120,108,46,129,63,26,107,255,119,
37,1,113,247,116,114,174,241,28,10,172,189,110,83,112,47,90,249,183,43,68,242,244,205,174,195,225,82,11,214,228,125,
252,156,119,37,222,209,183,197,110,141,174,8,109,253,79,242,77,29,127,225,201,77,86,114,120,252,177,248,93,218,51,218,
173,148,250,128,193,97,200,216,152,113,17,216,51,190,89,39,230,79,248,187,21,19,176,17,213,161,119,150,49,14,124,7,
230,196,245,101,52,184,218,44,229,93,68,5,233,56,126,90,248,46,27,29,159,99,30,51,199,166,88,172,169,151,119,139,
121,107,105,60,72,136,15,85,113,163,125,227,90,180,14,125,153,160,171,11,179,78,76,153,185,224,82,44,88,176,96,193,
130,5,11,22,44,88,176,96,193,130,5,11,22,44,88,176,96,193,130,69,37,241,127,238,146,187,72,236,7,218,235,0,
0,0,37,116,69,88,116,100,97,116,101,58,99,114,101,97,116,101,0,50,48,50,48,45,48,56,45,49,48,84,48,57,
58,50,49,58,49,53,43,48,57,58,48,48,81,58,8,144,0,0,0,37,116,69,88,116,100,97,116,101,58,109,111,100,
105,102,121,0,50,48,50,48,45,48,56,45,49,48,84,48,57,58,50,49,58,49,53,43,48,57,58,48,48,32,103,176,
44,0,0,0,0,73,69,78,68,174,66,96,130,
};
}
namespace Sprite {
+1 -1
View File
@@ -1,7 +1,7 @@
namespace Resource {
namespace Ares {
extern const unsigned char Icon[6562];
extern const unsigned char Logo[13719];
extern const unsigned char Logo[11533];
}
namespace Sprite {
namespace SuperFamicom {
+4 -4
View File
@@ -2,11 +2,11 @@ inline auto Scheduler::reset() -> void {
_threads.reset();
}
inline auto Scheduler::threads() const -> uint {
inline auto Scheduler::threads() const -> u32 {
return _threads.size();
}
inline auto Scheduler::thread(uint uniqueID) const -> maybe<Thread&> {
inline auto Scheduler::thread(u32 uniqueID) const -> maybe<Thread&> {
for(auto& thread : _threads) {
if(thread->_uniqueID == uniqueID) return *thread;
}
@@ -16,8 +16,8 @@ inline auto Scheduler::thread(uint uniqueID) const -> maybe<Thread&> {
//if threads A and B both have a clock value of 0, it is ambiguous which should run first.
//to resolve this, a uniqueID is assigned to each thread when appended to the scheduler.
//the first unused ID is selected, to avoid the uniqueID growing in an unbounded fashion.
inline auto Scheduler::uniqueID() const -> uint {
uint uniqueID = 0;
inline auto Scheduler::uniqueID() const -> u32 {
u32 uniqueID = 0;
while(thread(uniqueID)) uniqueID++;
return uniqueID;
}
+4 -4
View File
@@ -1,7 +1,7 @@
struct Thread;
struct Scheduler {
enum class Mode : uint {
enum class Mode : u32 {
Run,
Synchronize,
SynchronizePrimary,
@@ -13,9 +13,9 @@ struct Scheduler {
auto operator=(const Scheduler&) = delete;
auto reset() -> void;
auto threads() const -> uint;
auto thread(uint threadID) const -> maybe<Thread&>;
auto uniqueID() const -> uint;
auto threads() const -> u32;
auto thread(u32 threadID) const -> maybe<Thread&>;
auto uniqueID() const -> u32;
auto minimum() const -> uintmax;
auto maximum() const -> uintmax;
+18 -17
View File
@@ -4,7 +4,7 @@ inline auto Thread::EntryPoints() -> vector<EntryPoint>& {
}
inline auto Thread::Enter() -> void {
for(uint64_t index : range(EntryPoints().size())) {
for(u32 index : range(EntryPoints().size())) {
if(co_active() == EntryPoints()[index].handle) {
auto entryPoint = EntryPoints()[index].entryPoint;
EntryPoints().remove(index);
@@ -57,13 +57,19 @@ inline auto Thread::create(double frequency, function<void ()> entryPoint) -> vo
scheduler.append(*this);
}
//returns a thread to its entry point (eg for a reset), without resetting the clock value
inline auto Thread::restart(function<void()> entryPoint) -> void {
co_derive(_handle, Thread::Size, &Thread::Enter);
EntryPoints().append({_handle, entryPoint});
}
inline auto Thread::destroy() -> void {
scheduler.remove(*this);
if(_handle) co_delete(_handle);
_handle = nullptr;
}
inline auto Thread::step(uint clocks) -> void {
inline auto Thread::step(u32 clocks) -> void {
_clock += _scalar * clocks;
}
@@ -89,30 +95,25 @@ inline auto Thread::synchronize(Thread& thread, P&&... p) -> void {
}
inline auto Thread::serialize(serializer& s) -> void {
s.integer(_frequency);
s.integer(_scalar);
s.integer(_clock);
s(_frequency);
s(_scalar);
s(_clock);
if(!scheduler._synchronize) {
static uint8_t stack[Thread::Size];
static u8 stack[Thread::Size];
bool resume = co_active() == _handle;
if(s.mode() == serializer::Size) {
s.array(stack, Thread::Size);
s.boolean(resume);
}
if(s.mode() == serializer::Load) {
s.array(stack, Thread::Size);
s.boolean(resume);
if(s.reading()) {
s(stack);
s(resume);
memory::copy(_handle, stack, Thread::Size);
if(resume) scheduler._resume = _handle;
}
if(s.mode() == serializer::Save) {
if(s.writing()) {
memory::copy(stack, _handle, Thread::Size);
s.array(stack, Thread::Size);
s.boolean(resume);
s(stack);
s(resume);
}
}
}
+4 -3
View File
@@ -2,7 +2,7 @@ struct Scheduler;
struct Thread {
enum : uintmax { Second = (uintmax)-1 >> 1 };
enum : uintmax { Size = 8_KiB * sizeof(void*) };
enum : uintmax { Size = 16_KiB * sizeof(void*) };
struct EntryPoint {
cothread_t handle = nullptr;
@@ -30,9 +30,10 @@ struct Thread {
auto setClock(uintmax clock) -> void;
auto create(double frequency, function<void ()> entryPoint) -> void;
auto restart(function<void ()> entryPoint) -> void;
auto destroy() -> void;
auto step(uint clocks) -> void;
auto step(u32 clocks) -> void;
auto synchronize() -> void;
template<typename... P> auto synchronize(Thread&, P&&...) -> void;
@@ -40,7 +41,7 @@ struct Thread {
protected:
cothread_t _handle = nullptr;
uint _uniqueID = 0;
u32 _uniqueID = 0;
uintmax _frequency = 0;
uintmax _scalar = 0;
uintmax _clock = 0;
+131 -141
View File
@@ -1,144 +1,134 @@
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using i128 = int128_t;
using b1 = nall::Boolean;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using u128 = uint128_t;
using i1 = nall::Integer< 1>; using s1 = nall::IntegerPrimitive< 1>;
using i2 = nall::Integer< 2>; using s2 = nall::IntegerPrimitive< 2>;
using i3 = nall::Integer< 3>; using s3 = nall::IntegerPrimitive< 3>;
using i4 = nall::Integer< 4>; using s4 = nall::IntegerPrimitive< 4>;
using i5 = nall::Integer< 5>; using s5 = nall::IntegerPrimitive< 5>;
using i6 = nall::Integer< 6>; using s6 = nall::IntegerPrimitive< 6>;
using i7 = nall::Integer< 7>; using s7 = nall::IntegerPrimitive< 7>;
using i8 = nall::Integer< 8>;
using i9 = nall::Integer< 9>; using s9 = nall::IntegerPrimitive< 9>;
using i10 = nall::Integer<10>; using s10 = nall::IntegerPrimitive<10>;
using i11 = nall::Integer<11>; using s11 = nall::IntegerPrimitive<11>;
using i12 = nall::Integer<12>; using s12 = nall::IntegerPrimitive<12>;
using i13 = nall::Integer<13>; using s13 = nall::IntegerPrimitive<13>;
using i14 = nall::Integer<14>; using s14 = nall::IntegerPrimitive<14>;
using i15 = nall::Integer<15>; using s15 = nall::IntegerPrimitive<15>;
using i16 = nall::Integer<16>;
using i17 = nall::Integer<17>; using s17 = nall::IntegerPrimitive<17>;
using i18 = nall::Integer<18>; using s18 = nall::IntegerPrimitive<18>;
using i19 = nall::Integer<19>; using s19 = nall::IntegerPrimitive<19>;
using i20 = nall::Integer<20>; using s20 = nall::IntegerPrimitive<20>;
using i21 = nall::Integer<21>; using s21 = nall::IntegerPrimitive<21>;
using i22 = nall::Integer<22>; using s22 = nall::IntegerPrimitive<22>;
using i23 = nall::Integer<23>; using s23 = nall::IntegerPrimitive<23>;
using i24 = nall::Integer<24>; using s24 = nall::IntegerPrimitive<24>;
using i25 = nall::Integer<25>; using s25 = nall::IntegerPrimitive<25>;
using i26 = nall::Integer<26>; using s26 = nall::IntegerPrimitive<26>;
using i27 = nall::Integer<27>; using s27 = nall::IntegerPrimitive<27>;
using i28 = nall::Integer<28>; using s28 = nall::IntegerPrimitive<28>;
using i29 = nall::Integer<29>; using s29 = nall::IntegerPrimitive<29>;
using i30 = nall::Integer<30>; using s30 = nall::IntegerPrimitive<30>;
using i31 = nall::Integer<31>; using s31 = nall::IntegerPrimitive<31>;
using i32 = nall::Integer<32>;
using i33 = nall::Integer<33>; using s33 = nall::IntegerPrimitive<33>;
using i34 = nall::Integer<34>; using s34 = nall::IntegerPrimitive<34>;
using i35 = nall::Integer<35>; using s35 = nall::IntegerPrimitive<35>;
using i36 = nall::Integer<36>; using s36 = nall::IntegerPrimitive<36>;
using i37 = nall::Integer<37>; using s37 = nall::IntegerPrimitive<37>;
using i38 = nall::Integer<38>; using s38 = nall::IntegerPrimitive<38>;
using i39 = nall::Integer<39>; using s39 = nall::IntegerPrimitive<39>;
using i40 = nall::Integer<40>; using s40 = nall::IntegerPrimitive<40>;
using i41 = nall::Integer<41>; using s41 = nall::IntegerPrimitive<41>;
using i42 = nall::Integer<42>; using s42 = nall::IntegerPrimitive<42>;
using i43 = nall::Integer<43>; using s43 = nall::IntegerPrimitive<43>;
using i44 = nall::Integer<44>; using s44 = nall::IntegerPrimitive<44>;
using i45 = nall::Integer<45>; using s45 = nall::IntegerPrimitive<45>;
using i46 = nall::Integer<46>; using s46 = nall::IntegerPrimitive<46>;
using i47 = nall::Integer<47>; using s47 = nall::IntegerPrimitive<47>;
using i48 = nall::Integer<48>; using s48 = nall::IntegerPrimitive<48>;
using i49 = nall::Integer<49>; using s49 = nall::IntegerPrimitive<49>;
using i50 = nall::Integer<50>; using s50 = nall::IntegerPrimitive<50>;
using i51 = nall::Integer<51>; using s51 = nall::IntegerPrimitive<51>;
using i52 = nall::Integer<52>; using s52 = nall::IntegerPrimitive<52>;
using i53 = nall::Integer<53>; using s53 = nall::IntegerPrimitive<53>;
using i54 = nall::Integer<54>; using s54 = nall::IntegerPrimitive<54>;
using i55 = nall::Integer<55>; using s55 = nall::IntegerPrimitive<55>;
using i56 = nall::Integer<56>; using s56 = nall::IntegerPrimitive<56>;
using i57 = nall::Integer<57>; using s57 = nall::IntegerPrimitive<57>;
using i58 = nall::Integer<58>; using s58 = nall::IntegerPrimitive<58>;
using i59 = nall::Integer<59>; using s59 = nall::IntegerPrimitive<59>;
using i60 = nall::Integer<60>; using s60 = nall::IntegerPrimitive<60>;
using i61 = nall::Integer<61>; using s61 = nall::IntegerPrimitive<61>;
using i62 = nall::Integer<62>; using s62 = nall::IntegerPrimitive<62>;
using i63 = nall::Integer<63>; using s63 = nall::IntegerPrimitive<63>;
using i64 = nall::Integer<64>;
using f32 = float32_t;
using f64 = float64_t;
using n1 = nall::Natural< 1>; using u1 = nall::NaturalPrimitive< 1>;
using n2 = nall::Natural< 2>; using u2 = nall::NaturalPrimitive< 2>;
using n3 = nall::Natural< 3>; using u3 = nall::NaturalPrimitive< 3>;
using n4 = nall::Natural< 4>; using u4 = nall::NaturalPrimitive< 4>;
using n5 = nall::Natural< 5>; using u5 = nall::NaturalPrimitive< 5>;
using n6 = nall::Natural< 6>; using u6 = nall::NaturalPrimitive< 6>;
using n7 = nall::Natural< 7>; using u7 = nall::NaturalPrimitive< 7>;
using n8 = nall::Natural< 8>;
using n9 = nall::Natural< 9>; using u9 = nall::NaturalPrimitive< 9>;
using n10 = nall::Natural<10>; using u10 = nall::NaturalPrimitive<10>;
using n11 = nall::Natural<11>; using u11 = nall::NaturalPrimitive<11>;
using n12 = nall::Natural<12>; using u12 = nall::NaturalPrimitive<12>;
using n13 = nall::Natural<13>; using u13 = nall::NaturalPrimitive<13>;
using n14 = nall::Natural<14>; using u14 = nall::NaturalPrimitive<14>;
using n15 = nall::Natural<15>; using u15 = nall::NaturalPrimitive<15>;
using n16 = nall::Natural<16>;
using n17 = nall::Natural<17>; using u17 = nall::NaturalPrimitive<17>;
using n18 = nall::Natural<18>; using u18 = nall::NaturalPrimitive<18>;
using n19 = nall::Natural<19>; using u19 = nall::NaturalPrimitive<19>;
using n20 = nall::Natural<20>; using u20 = nall::NaturalPrimitive<20>;
using n21 = nall::Natural<21>; using u21 = nall::NaturalPrimitive<21>;
using n22 = nall::Natural<22>; using u22 = nall::NaturalPrimitive<22>;
using n23 = nall::Natural<23>; using u23 = nall::NaturalPrimitive<23>;
using n24 = nall::Natural<24>; using u24 = nall::NaturalPrimitive<24>;
using n25 = nall::Natural<25>; using u25 = nall::NaturalPrimitive<25>;
using n26 = nall::Natural<26>; using u26 = nall::NaturalPrimitive<26>;
using n27 = nall::Natural<27>; using u27 = nall::NaturalPrimitive<27>;
using n28 = nall::Natural<28>; using u28 = nall::NaturalPrimitive<28>;
using n29 = nall::Natural<29>; using u29 = nall::NaturalPrimitive<29>;
using n30 = nall::Natural<30>; using u30 = nall::NaturalPrimitive<30>;
using n31 = nall::Natural<31>; using u31 = nall::NaturalPrimitive<31>;
using n32 = nall::Natural<32>;
using n33 = nall::Natural<33>; using u33 = nall::NaturalPrimitive<33>;
using n34 = nall::Natural<34>; using u34 = nall::NaturalPrimitive<34>;
using n35 = nall::Natural<35>; using u35 = nall::NaturalPrimitive<35>;
using n36 = nall::Natural<36>; using u36 = nall::NaturalPrimitive<36>;
using n37 = nall::Natural<37>; using u37 = nall::NaturalPrimitive<37>;
using n38 = nall::Natural<38>; using u38 = nall::NaturalPrimitive<38>;
using n39 = nall::Natural<39>; using u39 = nall::NaturalPrimitive<39>;
using n40 = nall::Natural<40>; using u40 = nall::NaturalPrimitive<40>;
using n41 = nall::Natural<41>; using u41 = nall::NaturalPrimitive<41>;
using n42 = nall::Natural<42>; using u42 = nall::NaturalPrimitive<42>;
using n43 = nall::Natural<43>; using u43 = nall::NaturalPrimitive<43>;
using n44 = nall::Natural<44>; using u44 = nall::NaturalPrimitive<44>;
using n45 = nall::Natural<45>; using u45 = nall::NaturalPrimitive<45>;
using n46 = nall::Natural<46>; using u46 = nall::NaturalPrimitive<46>;
using n47 = nall::Natural<47>; using u47 = nall::NaturalPrimitive<47>;
using n48 = nall::Natural<48>; using u48 = nall::NaturalPrimitive<48>;
using n49 = nall::Natural<49>; using u49 = nall::NaturalPrimitive<49>;
using n50 = nall::Natural<50>; using u50 = nall::NaturalPrimitive<50>;
using n51 = nall::Natural<51>; using u51 = nall::NaturalPrimitive<51>;
using n52 = nall::Natural<52>; using u52 = nall::NaturalPrimitive<52>;
using n53 = nall::Natural<53>; using u53 = nall::NaturalPrimitive<53>;
using n54 = nall::Natural<54>; using u54 = nall::NaturalPrimitive<54>;
using n55 = nall::Natural<55>; using u55 = nall::NaturalPrimitive<55>;
using n56 = nall::Natural<56>; using u56 = nall::NaturalPrimitive<56>;
using n57 = nall::Natural<57>; using u57 = nall::NaturalPrimitive<57>;
using n58 = nall::Natural<58>; using u58 = nall::NaturalPrimitive<58>;
using n59 = nall::Natural<59>; using u59 = nall::NaturalPrimitive<59>;
using n60 = nall::Natural<60>; using u60 = nall::NaturalPrimitive<60>;
using n61 = nall::Natural<61>; using u61 = nall::NaturalPrimitive<61>;
using n62 = nall::Natural<62>; using u62 = nall::NaturalPrimitive<62>;
using n63 = nall::Natural<63>; using u63 = nall::NaturalPrimitive<63>;
using n64 = nall::Natural<64>;
using int1 = nall::Integer< 1>;
using int2 = nall::Integer< 2>;
using int3 = nall::Integer< 3>;
using int4 = nall::Integer< 4>;
using int5 = nall::Integer< 5>;
using int6 = nall::Integer< 6>;
using int7 = nall::Integer< 7>;
using int8 = nall::Integer< 8>;
using int9 = nall::Integer< 9>;
using int10 = nall::Integer<10>;
using int11 = nall::Integer<11>;
using int12 = nall::Integer<12>;
using int13 = nall::Integer<13>;
using int14 = nall::Integer<14>;
using int15 = nall::Integer<15>;
using int16 = nall::Integer<16>;
using int17 = nall::Integer<17>;
using int18 = nall::Integer<18>;
using int19 = nall::Integer<19>;
using int20 = nall::Integer<20>;
using int21 = nall::Integer<21>;
using int22 = nall::Integer<22>;
using int23 = nall::Integer<23>;
using int24 = nall::Integer<24>;
using int25 = nall::Integer<25>;
using int26 = nall::Integer<26>;
using int27 = nall::Integer<27>;
using int28 = nall::Integer<28>;
using int29 = nall::Integer<29>;
using int30 = nall::Integer<30>;
using int31 = nall::Integer<31>;
using int32 = nall::Integer<32>;
using int33 = nall::Integer<33>;
using int34 = nall::Integer<34>;
using int35 = nall::Integer<35>;
using int36 = nall::Integer<36>;
using int37 = nall::Integer<37>;
using int38 = nall::Integer<38>;
using int39 = nall::Integer<39>;
using int40 = nall::Integer<40>;
using int41 = nall::Integer<41>;
using int42 = nall::Integer<42>;
using int43 = nall::Integer<43>;
using int44 = nall::Integer<44>;
using int45 = nall::Integer<45>;
using int46 = nall::Integer<46>;
using int47 = nall::Integer<47>;
using int48 = nall::Integer<48>;
using int49 = nall::Integer<49>;
using int50 = nall::Integer<50>;
using int51 = nall::Integer<51>;
using int52 = nall::Integer<52>;
using int53 = nall::Integer<53>;
using int54 = nall::Integer<54>;
using int55 = nall::Integer<55>;
using int56 = nall::Integer<56>;
using int57 = nall::Integer<57>;
using int58 = nall::Integer<58>;
using int59 = nall::Integer<59>;
using int60 = nall::Integer<60>;
using int61 = nall::Integer<61>;
using int62 = nall::Integer<62>;
using int63 = nall::Integer<63>;
using int64 = nall::Integer<64>;
using uint1 = nall::Natural< 1>;
using uint2 = nall::Natural< 2>;
using uint3 = nall::Natural< 3>;
using uint4 = nall::Natural< 4>;
using uint5 = nall::Natural< 5>;
using uint6 = nall::Natural< 6>;
using uint7 = nall::Natural< 7>;
using uint8 = nall::Natural< 8>;
using uint9 = nall::Natural< 9>;
using uint10 = nall::Natural<10>;
using uint11 = nall::Natural<11>;
using uint12 = nall::Natural<12>;
using uint13 = nall::Natural<13>;
using uint14 = nall::Natural<14>;
using uint15 = nall::Natural<15>;
using uint16 = nall::Natural<16>;
using uint17 = nall::Natural<17>;
using uint18 = nall::Natural<18>;
using uint19 = nall::Natural<19>;
using uint20 = nall::Natural<20>;
using uint21 = nall::Natural<21>;
using uint22 = nall::Natural<22>;
using uint23 = nall::Natural<23>;
using uint24 = nall::Natural<24>;
using uint25 = nall::Natural<25>;
using uint26 = nall::Natural<26>;
using uint27 = nall::Natural<27>;
using uint28 = nall::Natural<28>;
using uint29 = nall::Natural<29>;
using uint30 = nall::Natural<30>;
using uint31 = nall::Natural<31>;
using uint32 = nall::Natural<32>;
using uint33 = nall::Natural<33>;
using uint34 = nall::Natural<34>;
using uint35 = nall::Natural<35>;
using uint36 = nall::Natural<36>;
using uint37 = nall::Natural<37>;
using uint38 = nall::Natural<38>;
using uint39 = nall::Natural<39>;
using uint40 = nall::Natural<40>;
using uint41 = nall::Natural<41>;
using uint42 = nall::Natural<42>;
using uint43 = nall::Natural<43>;
using uint44 = nall::Natural<44>;
using uint45 = nall::Natural<45>;
using uint46 = nall::Natural<46>;
using uint47 = nall::Natural<47>;
using uint48 = nall::Natural<48>;
using uint49 = nall::Natural<49>;
using uint50 = nall::Natural<50>;
using uint51 = nall::Natural<51>;
using uint52 = nall::Natural<52>;
using uint53 = nall::Natural<53>;
using uint54 = nall::Natural<54>;
using uint55 = nall::Natural<55>;
using uint56 = nall::Natural<56>;
using uint57 = nall::Natural<57>;
using uint58 = nall::Natural<58>;
using uint59 = nall::Natural<59>;
using uint60 = nall::Natural<60>;
using uint61 = nall::Natural<61>;
using uint62 = nall::Natural<62>;
using uint63 = nall::Natural<63>;
using uint64 = nall::Natural<64>;
using r32 = nall::Real<32>;
using r64 = nall::Real<64>;
+16 -4
View File
@@ -6,18 +6,24 @@ ares.objects += $(if $(findstring sn76489,$(ares.components)),ares-audio-sn76489
ares.objects += $(if $(findstring t6w28,$(ares.components)),ares-audio-t6w28)
ares.objects += $(if $(findstring ym2149,$(ares.components)),ares-audio-ym2149)
ares.objects += $(if $(findstring ym2413,$(ares.components)),ares-audio-ym2413)
ares.objects += $(if $(findstring ym2610,$(ares.components)),ares-audio-ym2610)
ares.objects += $(if $(findstring ym2612,$(ares.components)),ares-audio-ym2612)
ares.objects += $(if $(findstring m24c,$(ares.components)),ares-eeprom-m24c)
ares.objects += $(if $(findstring m93lcx6,$(ares.components)),ares-eeprom-m93lcx6)
ares.objects += $(if $(findstring x24c01,$(ares.components)),ares-eeprom-x24c01)
ares.objects += $(if $(findstring arm7tdmi,$(ares.components)),ares-processor-arm7tdmi)
ares.objects += $(if $(findstring gsu,$(ares.components)),ares-processor-gsu)
ares.objects += $(if $(findstring hg51b,$(ares.components)),ares-processor-hg51b)
ares.objects += $(if $(findstring huc6280,$(ares.components)),ares-processor-huc6280)
ares.objects += $(if $(findstring m68k,$(ares.components)),ares-processor-m68k)
ares.objects += $(if $(findstring m68hc05,$(ares.components)),ares-processor-m68hc05)
ares.objects += $(if $(findstring m68000,$(ares.components)),ares-processor-m68000)
ares.objects += $(if $(findstring mos6502,$(ares.components)),ares-processor-mos6502)
ares.objects += $(if $(findstring sh2,$(ares.components)),ares-processor-sh2)
ares.objects += $(if $(findstring sm5k,$(ares.components)),ares-processor-sm5k)
ares.objects += $(if $(findstring sm83,$(ares.components)),ares-processor-sm83)
ares.objects += $(if $(findstring spc700,$(ares.components)),ares-processor-spc700)
ares.objects += $(if $(findstring ssp1601,$(ares.components)),ares-processor-ssp1601)
ares.objects += $(if $(findstring tlcs900h,$(ares.components)),ares-processor-tlcs900h)
ares.objects += $(if $(findstring upd96050,$(ares.components)),ares-processor-upd96050)
ares.objects += $(if $(findstring v30mz,$(ares.components)),ares-processor-v30mz)
@@ -33,18 +39,24 @@ $(object.path)/ares-audio-sn76489.o: $(ares.path)/component/audio/sn76489/s
$(object.path)/ares-audio-t6w28.o: $(ares.path)/component/audio/t6w28/t6w28.cpp
$(object.path)/ares-audio-ym2149.o: $(ares.path)/component/audio/ym2149/ym2149.cpp
$(object.path)/ares-audio-ym2413.o: $(ares.path)/component/audio/ym2413/ym2413.cpp
$(object.path)/ares-audio-ym2610.o: $(ares.path)/component/audio/ym2610/ym2610.cpp
$(object.path)/ares-audio-ym2612.o: $(ares.path)/component/audio/ym2612/ym2612.cpp
$(object.path)/ares-eeprom-m24c.o: $(ares.path)/component/eeprom/m24c/m24c.cpp
$(object.path)/ares-eeprom-m93lcx6.o: $(ares.path)/component/eeprom/m93lcx6/m93lcx6.cpp
$(object.path)/ares-eeprom-x24c01.o: $(ares.path)/component/eeprom/x24c01/x24c01.cpp
$(object.path)/ares-processor-arm7tdmi.o: $(ares.path)/component/processor/arm7tdmi/arm7tdmi.cpp
$(object.path)/ares-processor-gsu.o: $(ares.path)/component/processor/gsu/gsu.cpp
$(object.path)/ares-processor-hg51b.o: $(ares.path)/component/processor/hg51b/hg51b.cpp
$(object.path)/ares-processor-huc6280.o: $(ares.path)/component/processor/huc6280/huc6280.cpp
$(object.path)/ares-processor-m68k.o: $(ares.path)/component/processor/m68k/m68k.cpp
$(object.path)/ares-processor-m68hc05.o: $(ares.path)/component/processor/m68hc05/m68hc05.cpp
$(object.path)/ares-processor-m68000.o: $(ares.path)/component/processor/m68000/m68000.cpp
$(object.path)/ares-processor-mos6502.o: $(ares.path)/component/processor/mos6502/mos6502.cpp
$(object.path)/ares-processor-sh2.o: $(ares.path)/component/processor/sh2/sh2.cpp
$(object.path)/ares-processor-sm5k.o: $(ares.path)/component/processor/sm5k/sm5k.cpp
$(object.path)/ares-processor-sm83.o: $(ares.path)/component/processor/sm83/sm83.cpp
$(object.path)/ares-processor-spc700.o: $(ares.path)/component/processor/spc700/spc700.cpp
$(object.path)/ares-processor-ssp1601.o: $(ares.path)/component/processor/ssp1601/ssp1601.cpp
$(object.path)/ares-processor-tlcs900h.o: $(ares.path)/component/processor/tlcs900h/tlcs900h.cpp
$(object.path)/ares-processor-upd96050.o: $(ares.path)/component/processor/upd96050/upd96050.cpp
$(object.path)/ares-processor-v30mz.o: $(ares.path)/component/processor/v30mz/v30mz.cpp
+6 -6
View File
@@ -5,14 +5,14 @@ namespace ares {
#include "serialization.cpp"
auto AY38910::clock() -> array<uint4[3]> {
auto AY38910::clock() -> array<n4[3]> {
toneA.clock();
toneB.clock();
toneC.clock();
noise.clock();
envelope.clock();
array<uint4[3]> output;
array<n4[3]> output;
if((toneA.output | channelA.tone) & (noise.output | channelA.noise)) {
output[0] = channelA.envelope ? envelope.output : channelA.volume;
}
@@ -65,8 +65,8 @@ auto AY38910::Envelope::clock() -> void {
}
}
auto AY38910::read() -> uint8 {
uint8 data;
auto AY38910::read() -> n8 {
n8 data;
switch(io.register) {
case 0:
@@ -135,7 +135,7 @@ auto AY38910::read() -> uint8 {
return data;
}
auto AY38910::write(uint8 data) -> void {
auto AY38910::write(n8 data) -> void {
switch(io.register) {
case 0:
toneA.period.bit(0, 7) = data.bit(0,7);
@@ -204,7 +204,7 @@ auto AY38910::write(uint8 data) -> void {
}
}
auto AY38910::select(uint4 data) -> void {
auto AY38910::select(n4 data) -> void {
io.register = data;
}
+30 -30
View File
@@ -5,14 +5,14 @@ namespace ares {
//General Instrument AY-3-8910
struct AY38910 {
virtual auto readIO(uint1 port) -> uint8 { return 0xff; }
virtual auto writeIO(uint1 port, uint8 data) -> void {}
virtual auto readIO(n1 port) -> n8 { return 0xff; }
virtual auto writeIO(n1 port, n8 data) -> void {}
//ay38910.cpp
auto clock() -> array<uint4[3]>;
auto read() -> uint8;
auto write(uint8 data) -> void;
auto select(uint4 data) -> void;
auto clock() -> array<n4[3]>;
auto read() -> n8;
auto write(n8 data) -> void;
auto select(n4 data) -> void;
auto power() -> void;
//serialization.cpp
@@ -23,51 +23,51 @@ protected:
//ay38910.cpp
auto clock() -> void;
uint12 counter;
uint12 period;
uint1 output;
n12 counter;
n12 period;
n1 output;
};
struct Noise {
//ay38910.cpp
auto clock() -> void;
uint5 counter;
uint5 period;
uint1 flip;
uint17 lfsr = 1;
uint1 output;
n5 counter;
n5 period;
n1 flip;
n17 lfsr = 1;
n1 output;
};
struct Envelope {
//ay38910.cpp
auto clock() -> void;
uint16 counter;
uint16 period;
uint1 holding;
uint1 attacking;
uint1 hold;
uint1 alternate;
uint1 attack;
uint1 repeat; //continue
uint4 output;
n16 counter;
n16 period;
n1 holding;
n1 attacking;
n1 hold;
n1 alternate;
n1 attack;
n1 repeat; //continue
n4 output;
};
struct Channel {
uint1 tone; //0 = enable, 1 = disable
uint1 noise; //0 = enable, 1 = disable
uint1 envelope; //0 = use fixed volume, 1 = use envelope phase
uint4 volume;
n1 tone; //0 = enable, 1 = disable
n1 noise; //0 = enable, 1 = disable
n1 envelope; //0 = use fixed volume, 1 = use envelope phase
n4 volume;
};
struct Port {
uint1 direction; //0 = input, 1 = output
uint8 data;
n1 direction; //0 = input, 1 = output
n8 data;
};
struct IO {
uint4 register;
n4 register;
};
Tone toneA;
+40 -40
View File
@@ -1,52 +1,52 @@
auto AY38910::serialize(serializer& s) -> void {
s.integer(toneA.counter);
s.integer(toneA.period);
s.integer(toneA.output);
s(toneA.counter);
s(toneA.period);
s(toneA.output);
s.integer(toneB.counter);
s.integer(toneB.period);
s.integer(toneB.output);
s(toneB.counter);
s(toneB.period);
s(toneB.output);
s.integer(toneC.counter);
s.integer(toneC.period);
s.integer(toneC.output);
s(toneC.counter);
s(toneC.period);
s(toneC.output);
s.integer(noise.counter);
s.integer(noise.period);
s.integer(noise.flip);
s.integer(noise.lfsr);
s.integer(noise.output);
s(noise.counter);
s(noise.period);
s(noise.flip);
s(noise.lfsr);
s(noise.output);
s.integer(envelope.counter);
s.integer(envelope.period);
s.integer(envelope.holding);
s.integer(envelope.attacking);
s.integer(envelope.hold);
s.integer(envelope.alternate);
s.integer(envelope.attack);
s.integer(envelope.repeat);
s.integer(envelope.output);
s(envelope.counter);
s(envelope.period);
s(envelope.holding);
s(envelope.attacking);
s(envelope.hold);
s(envelope.alternate);
s(envelope.attack);
s(envelope.repeat);
s(envelope.output);
s.integer(channelA.tone);
s.integer(channelA.noise);
s.integer(channelA.envelope);
s.integer(channelA.volume);
s(channelA.tone);
s(channelA.noise);
s(channelA.envelope);
s(channelA.volume);
s.integer(channelB.tone);
s.integer(channelB.noise);
s.integer(channelB.envelope);
s.integer(channelB.volume);
s(channelB.tone);
s(channelB.noise);
s(channelB.envelope);
s(channelB.volume);
s.integer(channelC.tone);
s.integer(channelC.noise);
s.integer(channelC.envelope);
s.integer(channelC.volume);
s(channelC.tone);
s(channelC.noise);
s(channelC.envelope);
s(channelC.volume);
s.integer(portA.direction);
s.integer(portA.data);
s(portA.direction);
s(portA.data);
s.integer(portB.direction);
s.integer(portB.data);
s(portB.direction);
s(portB.data);
s.integer(io.register);
s(io.register);
}
+21 -21
View File
@@ -5,36 +5,36 @@ namespace ares {
#include "serialization.cpp"
auto MSM5205::sample() const -> int12 {
auto MSM5205::sample() const -> i12 {
//note: technically this should return io.sample & ~3;
//the DAC output is only 10-bits
return io.sample;
}
auto MSM5205::scaler() const -> uint {
auto MSM5205::scaler() const -> u32 {
//0 = 4khz (384khz / 96); 8khz (768khz / 96)
//1 = 6khz (384khz / 64); 12khz (768khz / 64)
//2 = 8khz (384khz / 48); 16khz (768khz / 48)
//3 = prohibited (unknown behavior: treat as 8khz)
static const uint scaler[4] = {96, 64, 48, 48};
static const u32 scaler[4] = {96, 64, 48, 48};
return scaler[io.scaler];
}
auto MSM5205::setReset(uint1 reset) -> void {
auto MSM5205::setReset(n1 reset) -> void {
io.reset = reset;
}
auto MSM5205::setWidth(uint1 width) -> void {
auto MSM5205::setWidth(n1 width) -> void {
io.width = width;
}
auto MSM5205::setScaler(uint2 scaler) -> void {
auto MSM5205::setScaler(n2 scaler) -> void {
io.scaler = scaler;
}
auto MSM5205::setData(uint4 data) -> void {
if(io.width == 0) io.data = (uint3)data << 1;
if(io.width == 1) io.data = (uint4)data << 0;
auto MSM5205::setData(n4 data) -> void {
if(io.width == 0) io.data = (n3)data << 1;
if(io.width == 1) io.data = (n4)data << 0;
}
auto MSM5205::clock() -> void {
@@ -44,13 +44,13 @@ auto MSM5205::clock() -> void {
return;
}
int sample = io.sample + lookup[io.step * 16 + io.data];
s32 sample = io.sample + lookup[io.step * 16 + io.data];
if(sample > 2047) sample = 2047;
if(sample < -2048) sample = -2048;
io.sample = sample;
static const int shift[8] = {-1, -1, -1, -1, 2, 4, 6, 8};
io.step += shift[(uint3)io.data];
static const s32 shift[8] = {-1, -1, -1, -1, 2, 4, 6, 8};
io.step += shift[(n3)io.data];
if(io.step > 48) io.step = 48;
if(io.step < 0) io.step = 0;
}
@@ -58,21 +58,21 @@ auto MSM5205::clock() -> void {
auto MSM5205::power() -> void {
io = {};
static const int map[16][4] = {
static const s32 map[16][4] = {
{ 1,0,0,0}, { 1,0,0,1}, { 1,0,1,0}, { 1,0,1,1},
{ 1,1,0,0}, { 1,1,0,1}, { 1,1,1,0}, { 1,1,1,1},
{-1,0,0,0}, {-1,0,0,1}, {-1,0,1,0}, {-1,0,1,1},
{-1,1,0,0}, {-1,1,0,1}, {-1,1,1,0}, {-1,1,1,1},
};
for(int step : range(49)) {
int scale = floor(16.0 * pow(11.0 / 10.0, (double)step));
for(int nibble : range(16)) {
int a = map[nibble][0];
int b = map[nibble][1] * scale / 1;
int c = map[nibble][2] * scale / 2;
int d = map[nibble][3] * scale / 4;
int e = scale / 8;
for(s32 step : range(49)) {
s32 scale = floor(16.0 * pow(11.0 / 10.0, (f64)step));
for(s32 nibble : range(16)) {
s32 a = map[nibble][0];
s32 b = map[nibble][1] * scale / 1;
s32 c = map[nibble][2] * scale / 2;
s32 d = map[nibble][3] * scale / 4;
s32 e = scale / 8;
lookup[step * 16 + nibble] = a * (b + c + d + e);
}
}
+13 -13
View File
@@ -6,13 +6,13 @@ namespace ares {
struct MSM5205 {
//msm5205.cpp
auto sample() const -> int12;
auto scaler() const -> uint;
auto sample() const -> i12;
auto scaler() const -> u32;
auto setReset(uint1 reset) -> void;
auto setWidth(uint1 width) -> void;
auto setScaler(uint2 frequency) -> void;
auto setData(uint4 data) -> void;
auto setReset(n1 reset) -> void;
auto setWidth(n1 width) -> void;
auto setScaler(n2 frequency) -> void;
auto setData(n4 data) -> void;
auto clock() -> void;
auto power() -> void;
@@ -21,16 +21,16 @@ struct MSM5205 {
auto serialize(serializer&) -> void;
struct IO {
uint1 reset; //RESET
uint1 width; //4B
uint2 scaler; //S0-S1
uint4 data; //D0-D7
int12 sample; //DAOUT
int8 step;
n1 reset; //RESET
n1 width; //4B
n2 scaler; //S0-S1
n4 data; //D0-D7
i12 sample; //DAOUT
i8 step;
} io;
//unserialized:
int lookup[49 * 16];
s32 lookup[49 * 16];
};
}
@@ -1,8 +1,8 @@
auto MSM5205::serialize(serializer& s) -> void {
s.integer(io.reset);
s.integer(io.width);
s.integer(io.scaler);
s.integer(io.data);
s.integer(io.sample);
s.integer(io.step);
s(io.reset);
s(io.width);
s(io.scaler);
s(io.data);
s(io.sample);
s(io.step);
}
+22 -17
View File
@@ -1,25 +1,30 @@
auto SN76489::serialize(serializer& s) -> void {
tone0.serialize(s);
tone1.serialize(s);
tone2.serialize(s);
noise.serialize(s);
s.integer(io.register);
s(tone0);
s(tone1);
s(tone2);
s(noise);
s(latch);
}
auto SN76489::Tone::serialize(serializer& s) -> void {
s.integer(volume);
s.integer(counter);
s.integer(pitch);
s.integer(output);
s(volume);
s(counter);
s(pitch);
s(output);
}
auto SN76489::Noise::serialize(serializer& s) -> void {
s.integer(volume);
s.integer(counter);
s.integer(pitch);
s.integer(enable);
s.integer(rate);
s.integer(lfsr);
s.integer(flip);
s.integer(output);
s(volume);
s(counter);
s(pitch);
s(enable);
s(rate);
s(lfsr);
s(flip);
s(output);
}
auto SN76489::Latch::serialize(serializer& s) -> void {
s(type);
s(channel);
}
+32 -29
View File
@@ -5,13 +5,13 @@ namespace ares {
#include "serialization.cpp"
auto SN76489::clock() -> array<uint4[4]> {
auto SN76489::clock() -> array<n4[4]> {
tone0.clock();
tone1.clock();
tone2.clock();
noise.clock();
array<uint4[4]> output{15, 15, 15, 15};
array<n4[4]> output{15, 15, 15, 15};
if(tone0.output) output[0] = tone0.volume;
if(tone1.output) output[1] = tone1.volume;
if(tone2.output) output[2] = tone2.volume;
@@ -28,7 +28,7 @@ auto SN76489::Tone::clock() -> void {
auto SN76489::Noise::clock() -> void {
if(!counter--) {
counter = array<uint10[4]>{0x10, 0x20, 0x40, pitch}[rate];
counter = array<n10[4]>{0x10, 0x20, 0x40, pitch}[rate];
if(flip ^= 1) { //0->1 transition
output = !lfsr.bit(0);
lfsr = (lfsr.bit(0) ^ lfsr.bit(3) & enable) << 15 | lfsr >> 1;
@@ -36,31 +36,34 @@ auto SN76489::Noise::clock() -> void {
}
}
auto SN76489::write(uint8 data) -> void {
if(data.bit(7)) io.register = data.bit(4,6);
if(io.register.bit(0)) switch(io.register.bit(1,2)) {
case 0: tone0.volume = data.bit(0,3); break;
case 1: tone1.volume = data.bit(0,3); break;
case 2: tone2.volume = data.bit(0,3); break;
case 3: noise.volume = data.bit(0,3); break;
}
else if(data.bit(7)) switch(io.register.bit(1,2)) {
case 0: tone0.pitch.bit(0,3) = data.bit(0,3); break;
case 1: tone1.pitch.bit(0,3) = data.bit(0,3); break;
case 2: tone2.pitch.bit(0,3) = data.bit(0,3); noise.pitch = tone2.pitch; break;
case 3: noise.rate = data.bit(0,1);
noise.enable = data.bit(2);
noise.lfsr = 0x8000;
break;
}
else switch(io.register.bit(1,2)) {
case 0: tone0.pitch.bit(4,9) = data.bit(0,5); break;
case 1: tone1.pitch.bit(4,9) = data.bit(0,5); break;
case 2: tone2.pitch.bit(4,9) = data.bit(0,5); noise.pitch = tone2.pitch; break;
case 3: noise.volume = data.bit(0,3); break;
auto SN76489::write(n8 data) -> void {
if(data.bit(7)) {
latch.type = data.bit(4);
latch.channel = data.bit(5,6);
if(latch.type) {
switch(latch.channel) {
case 0: tone0.volume = data.bit(0,3); break;
case 1: tone1.volume = data.bit(0,3); break;
case 2: tone2.volume = data.bit(0,3); break;
case 3: noise.volume = data.bit(0,3); break;
}
} else {
switch(latch.channel) {
case 0: tone0.pitch.bit(0,3) = data.bit(0,3); break;
case 1: tone1.pitch.bit(0,3) = data.bit(0,3); break;
case 2: tone2.pitch.bit(0,3) = data.bit(0,3); noise.pitch = tone2.pitch; break;
case 3: noise.rate = data.bit(0,1);
noise.enable = data.bit(2);
noise.lfsr = 0x8000;
break;
}
}
} else if(!latch.type) {
switch(latch.channel) {
case 0: tone0.pitch.bit(4,9) = data.bit(0,5); break;
case 1: tone1.pitch.bit(4,9) = data.bit(0,5); break;
case 2: tone2.pitch.bit(4,9) = data.bit(0,5); noise.pitch = tone2.pitch; break;
}
}
}
@@ -69,7 +72,7 @@ auto SN76489::power() -> void {
tone1 = {};
tone2 = {};
noise = {};
io = {};
latch = {};
}
}
+24 -20
View File
@@ -6,8 +6,8 @@ namespace ares {
struct SN76489 {
//sn76489.cpp
auto clock() -> array<uint4[4]>;
auto write(uint8 data) -> void;
auto clock() -> array<n4[4]>;
auto write(n8 data) -> void;
auto power() -> void;
//serialization.cpp
@@ -21,10 +21,10 @@ protected:
//serialization.cpp
auto serialize(serializer&) -> void;
uint4 volume = 15;
uint10 counter;
uint10 pitch;
uint1 output;
n4 volume = 15;
n10 counter;
n10 pitch;
n1 output;
};
struct Noise {
@@ -34,25 +34,29 @@ protected:
//serialization.cpp
auto serialize(serializer&) -> void;
uint4 volume = 15;
uint10 counter;
uint10 pitch;
uint1 enable;
uint2 rate;
uint16 lfsr = 0x8000;
uint1 flip;
uint1 output;
n4 volume = 15;
n10 counter;
n10 pitch;
n1 enable;
n2 rate;
n16 lfsr = 0x8000;
n1 flip;
n1 output;
};
struct IO {
uint3 register;
struct Latch {
//serialization.cpp
auto serialize(serializer&) -> void;
n1 type;
n2 channel;
};
Tone tone0;
Tone tone1;
Tone tone2;
Tone tone0;
Tone tone1;
Tone tone2;
Noise noise;
IO io;
Latch latch;
};
}
+24 -19
View File
@@ -1,27 +1,32 @@
auto T6W28::serialize(serializer& s) -> void {
tone0.serialize(s);
tone1.serialize(s);
tone2.serialize(s);
noise.serialize(s);
s.integer(io.register);
s(tone0);
s(tone1);
s(tone2);
s(noise);
s(latch);
}
auto T6W28::Tone::serialize(serializer& s) -> void {
s.integer(counter);
s.integer(pitch);
s.integer(output);
s.integer(volume.left);
s.integer(volume.right);
s(counter);
s(pitch);
s(output);
s(volume.left);
s(volume.right);
}
auto T6W28::Noise::serialize(serializer& s) -> void {
s.integer(counter);
s.integer(pitch);
s.integer(enable);
s.integer(rate);
s.integer(lfsr);
s.integer(flip);
s.integer(output);
s.integer(volume.left);
s.integer(volume.right);
s(counter);
s(pitch);
s(enable);
s(rate);
s(lfsr);
s(flip);
s(output);
s(volume.left);
s(volume.right);
}
auto T6W28::Latch::serialize(serializer& s) -> void {
s(type);
s(channel);
}
+53 -45
View File
@@ -5,13 +5,13 @@ namespace ares {
#include "serialization.cpp"
auto T6W28::clock() -> array<uint4[8]> {
auto T6W28::clock() -> array<n4[8]> {
tone0.clock();
tone1.clock();
tone2.clock();
noise.clock();
array<uint4[8]> output{15, 15, 15, 15, 15, 15, 15, 15};
array<n4[8]> output{15, 15, 15, 15, 15, 15, 15, 15};
if(tone0.output) output[0] = tone0.volume.left, output[4] = tone0.volume.right;
if(tone1.output) output[1] = tone1.volume.left, output[5] = tone1.volume.right;
if(tone2.output) output[2] = tone2.volume.left, output[6] = tone2.volume.right;
@@ -28,57 +28,65 @@ auto T6W28::Tone::clock() -> void {
auto T6W28::Noise::clock() -> void {
if(!counter--) {
counter = array<uint10[4]>{0x10, 0x20, 0x40, pitch}[rate];
if(flip ^= 1) {
counter = array<n10[4]>{0x10, 0x20, 0x40, pitch}[rate];
if(flip ^= 1) { //0->1 transition
output = !lfsr.bit(0);
lfsr = (lfsr.bit(0) ^ lfsr.bit(2) & enable) << 14 | lfsr >> 1;
}
}
}
auto T6W28::writeLeft(uint8 data) -> void {
if(data.bit(7)) io.register = data.bit(4,6);
if(io.register.bit(0)) switch(io.register.bit(1,2)) {
case 0: tone0.volume.left = data.bit(0,3); break;
case 1: tone1.volume.left = data.bit(0,3); break;
case 2: tone2.volume.left = data.bit(0,3); break;
case 3: noise.volume.left = data.bit(0,3); break;
}
else if(data.bit(7)) switch(io.register.bit(1,2)) {
case 0: tone0.pitch.bit(0,3) = data.bit(0,3); break;
case 1: tone1.pitch.bit(0,3) = data.bit(0,3); break;
case 2: tone2.pitch.bit(0,3) = data.bit(0,3); break;
}
else switch(io.register.bit(1,2)) {
case 0: tone0.pitch.bit(4,9) = data.bit(0,5); break;
case 1: tone1.pitch.bit(4,9) = data.bit(0,5); break;
case 2: tone2.pitch.bit(4,9) = data.bit(0,5); break;
auto T6W28::writeLeft(n8 data) -> void {
if(data.bit(7)) {
latch.type = data.bit(4);
latch.channel = data.bit(5,6);
if(latch.type) {
switch(latch.channel) {
case 0: tone0.volume.left = data.bit(0,3); break;
case 1: tone1.volume.left = data.bit(0,3); break;
case 2: tone2.volume.left = data.bit(0,3); break;
case 3: noise.volume.left = data.bit(0,3); break;
}
} else {
switch(latch.channel) {
case 0: tone0.pitch.bit(0,3) = data.bit(0,3); break;
case 1: tone1.pitch.bit(0,3) = data.bit(0,3); writePitch(tone1.pitch); break;
case 2: tone2.pitch.bit(0,3) = data.bit(0,3); break;
}
}
} else if(!latch.type) {
switch(latch.channel) {
case 0: tone0.pitch.bit(4,9) = data.bit(0,5); break;
case 1: tone1.pitch.bit(4,9) = data.bit(0,5); writePitch(tone1.pitch); break;
case 2: tone2.pitch.bit(4,9) = data.bit(0,5); break;
}
}
}
auto T6W28::writeRight(uint8 data) -> void {
if(data.bit(7)) io.register = data.bit(4,6);
if(io.register.bit(0)) switch(io.register.bit(1,2)) {
case 0: tone0.volume.right = data.bit(0,3); break;
case 1: tone1.volume.right = data.bit(0,3); break;
case 2: tone2.volume.right = data.bit(0,3); break;
case 3: noise.volume.right = data.bit(0,3); break;
}
else if(data.bit(7)) switch(io.register.bit(1,2)) {
case 2: noise.pitch.bit(0,3) = data.bit(0,3); break;
case 3: noise.rate = data.bit(0,1);
noise.enable = data.bit(2);
noise.lfsr = 0x4000;
break;
}
else switch(io.register.bit(1,2)) {
case 2: noise.pitch.bit(4,9) = data.bit(0,5); break;
auto T6W28::writeRight(n8 data) -> void {
if(data.bit(7)) {
latch.type = data.bit(4);
latch.channel = data.bit(5,6);
if(latch.type) {
switch(latch.channel) {
case 0: tone0.volume.right = data.bit(0,3); break;
case 1: tone1.volume.right = data.bit(0,3); break;
case 2: tone2.volume.right = data.bit(0,3); break;
case 3: noise.volume.right = data.bit(0,3); break;
}
} else {
switch(latch.channel) {
case 2: noise.pitch.bit(0,3) = data.bit(0,3); break;
case 3: noise.rate = data.bit(0,1);
noise.enable = data.bit(2);
noise.lfsr = 0x4000;
break;
}
}
} else if(!latch.type) {
switch(latch.channel) {
case 2: noise.pitch.bit(4,9) = data.bit(0,5); break;
}
}
}
@@ -87,7 +95,7 @@ auto T6W28::power() -> void {
tone1 = {};
tone2 = {};
noise = {};
io = {};
latch = {};
}
}
+29 -23
View File
@@ -5,10 +5,12 @@ namespace ares {
//T6W28 (SN76489 variant)
struct T6W28 {
virtual auto writePitch(u32) -> void = 0;
//t6w28.cpp
auto clock() -> array<uint4[8]>;
auto writeLeft(uint8 data) -> void;
auto writeRight(uint8 data) -> void;
auto clock() -> array<n4[8]>;
auto writeLeft(n8 data) -> void;
auto writeRight(n8 data) -> void;
auto power() -> void;
//serialization.cpp
@@ -22,12 +24,12 @@ protected:
//serialization.cpp
auto serialize(serializer&) -> void;
uint10 counter;
uint10 pitch;
uint1 output;
n10 counter;
n10 pitch;
n1 output;
struct Volume {
uint4 left = 15;
uint4 right = 15;
n4 left = 15;
n4 right = 15;
} volume;
};
@@ -38,28 +40,32 @@ protected:
//serialization.cpp
auto serialize(serializer&) -> void;
uint10 counter;
uint10 pitch;
uint1 enable;
uint2 rate;
uint15 lfsr = 0x4000;
uint1 flip;
uint1 output;
n10 counter;
n10 pitch;
n1 enable;
n2 rate;
n15 lfsr = 0x4000;
n1 flip;
n1 output;
struct Volume {
uint4 left = 15;
uint4 right = 15;
n4 left = 15;
n4 right = 15;
} volume;
};
struct IO {
uint3 register;
struct Latch {
//serialization.cpp
auto serialize(serializer&) -> void;
n1 type;
n2 channel;
};
Tone tone0;
Tone tone1;
Tone tone2;
Tone tone0;
Tone tone1;
Tone tone2;
Noise noise;
IO io;
Latch latch;
};
}
+48 -48
View File
@@ -1,60 +1,60 @@
auto YM2149::serialize(serializer& s) -> void {
s.integer(toneA.counter);
s.integer(toneA.period);
s.integer(toneA.unused);
s.integer(toneA.output);
s(toneA.counter);
s(toneA.period);
s(toneA.unused);
s(toneA.output);
s.integer(toneB.counter);
s.integer(toneB.period);
s.integer(toneB.unused);
s.integer(toneB.output);
s(toneB.counter);
s(toneB.period);
s(toneB.unused);
s(toneB.output);
s.integer(toneC.counter);
s.integer(toneC.period);
s.integer(toneC.unused);
s.integer(toneC.output);
s(toneC.counter);
s(toneC.period);
s(toneC.unused);
s(toneC.output);
s.integer(noise.counter);
s.integer(noise.period);
s.integer(noise.unused);
s.integer(noise.flip);
s.integer(noise.lfsr);
s.integer(noise.output);
s(noise.counter);
s(noise.period);
s(noise.unused);
s(noise.flip);
s(noise.lfsr);
s(noise.output);
s.integer(envelope.counter);
s.integer(envelope.period);
s.integer(envelope.holding);
s.integer(envelope.attacking);
s.integer(envelope.hold);
s.integer(envelope.alternate);
s.integer(envelope.attack);
s.integer(envelope.repeat);
s.integer(envelope.unused);
s.integer(envelope.output);
s(envelope.counter);
s(envelope.period);
s(envelope.holding);
s(envelope.attacking);
s(envelope.hold);
s(envelope.alternate);
s(envelope.attack);
s(envelope.repeat);
s(envelope.unused);
s(envelope.output);
s.integer(channelA.tone);
s.integer(channelA.noise);
s.integer(channelA.envelope);
s.integer(channelA.volume);
s.integer(channelA.unused);
s(channelA.tone);
s(channelA.noise);
s(channelA.envelope);
s(channelA.volume);
s(channelA.unused);
s.integer(channelB.tone);
s.integer(channelB.noise);
s.integer(channelB.envelope);
s.integer(channelB.volume);
s.integer(channelB.unused);
s(channelB.tone);
s(channelB.noise);
s(channelB.envelope);
s(channelB.volume);
s(channelB.unused);
s.integer(channelC.tone);
s.integer(channelC.noise);
s.integer(channelC.envelope);
s.integer(channelC.volume);
s.integer(channelC.unused);
s(channelC.tone);
s(channelC.noise);
s(channelC.envelope);
s(channelC.volume);
s(channelC.unused);
s.integer(portA.direction);
s.integer(portA.data);
s(portA.direction);
s(portA.data);
s.integer(portB.direction);
s.integer(portB.data);
s(portB.direction);
s(portB.data);
s.integer(io.register);
s(io.register);
}
+9 -9
View File
@@ -5,22 +5,22 @@ namespace ares {
#include "serialization.cpp"
auto YM2149::clock() -> array<uint5[3]> {
auto YM2149::clock() -> array<n5[3]> {
toneA.clock();
toneB.clock();
toneC.clock();
noise.clock();
envelope.clock();
array<uint5[3]> output;
array<n5[3]> output;
if((toneA.output | channelA.tone) & (noise.output | channelA.noise)) {
output[0] = channelA.envelope ? envelope.output : uint5(channelA.volume << 1 | 1);
output[0] = channelA.envelope ? envelope.output : n5(channelA.volume << 1 | 1);
}
if((toneB.output | channelB.tone) & (noise.output | channelB.noise)) {
output[1] = channelB.envelope ? envelope.output : uint5(channelB.volume << 1 | 1);
output[1] = channelB.envelope ? envelope.output : n5(channelB.volume << 1 | 1);
}
if((toneC.output | channelC.tone) & (noise.output | channelC.noise)) {
output[2] = channelC.envelope ? envelope.output : uint5(channelC.volume << 1 | 1);
output[2] = channelC.envelope ? envelope.output : n5(channelC.volume << 1 | 1);
}
return output;
}
@@ -67,8 +67,8 @@ auto YM2149::Envelope::clock() -> void {
}
}
auto YM2149::read() -> uint8 {
uint8 data;
auto YM2149::read() -> n8 {
n8 data;
switch(io.register) {
case 0:
@@ -145,7 +145,7 @@ auto YM2149::read() -> uint8 {
return data;
}
auto YM2149::write(uint8 data) -> void {
auto YM2149::write(n8 data) -> void {
switch(io.register) {
case 0:
toneA.period.bit(0, 7) = data.bit(0,7);
@@ -222,7 +222,7 @@ auto YM2149::write(uint8 data) -> void {
}
}
auto YM2149::select(uint4 data) -> void {
auto YM2149::select(n4 data) -> void {
io.register = data;
}
+32 -32
View File
@@ -6,10 +6,10 @@ namespace ares {
struct YM2149 {
//ym2149.cpp
auto clock() -> array<uint5[3]>;
auto read() -> uint8;
auto write(uint8 data) -> void;
auto select(uint4 data) -> void;
auto clock() -> array<n5[3]>;
auto read() -> n8;
auto write(n8 data) -> void;
auto select(n4 data) -> void;
auto power() -> void;
//serialization.cpp
@@ -20,55 +20,55 @@ protected:
//ym2149.cpp
auto clock() -> void;
uint12 counter;
uint12 period;
uint4 unused;
uint1 output;
n12 counter;
n12 period;
n4 unused;
n1 output;
};
struct Noise {
//ym2149.cpp
auto clock() -> void;
uint5 counter;
uint5 period;
uint3 unused;
uint1 flip;
uint17 lfsr = 1;
uint1 output;
n5 counter;
n5 period;
n3 unused;
n1 flip;
n17 lfsr = 1;
n1 output;
};
struct Envelope {
//ym2149.cpp
auto clock() -> void;
uint16 counter;
uint16 period;
uint1 holding;
uint1 attacking;
uint1 hold;
uint1 alternate;
uint1 attack;
uint1 repeat; //continue
uint4 unused;
uint5 output;
n16 counter;
n16 period;
n1 holding;
n1 attacking;
n1 hold;
n1 alternate;
n1 attack;
n1 repeat; //continue
n4 unused;
n5 output;
};
struct Channel {
uint1 tone; //0 = enable, 1 = disable
uint1 noise; //0 = enable, 1 = disable
uint1 envelope; //0 = use fixed volume, 1 = use envelope volume
uint4 volume;
uint3 unused;
n1 tone; //0 = enable, 1 = disable
n1 noise; //0 = enable, 1 = disable
n1 envelope; //0 = use fixed volume, 1 = use envelope volume
n4 volume;
n3 unused;
};
struct Port {
uint1 direction; //0 = input, 1 = output
uint8 data;
n1 direction; //0 = input, 1 = output
n8 data;
};
struct IO {
uint4 register;
n4 register;
};
Tone toneA;
+26 -30
View File
@@ -1,10 +1,10 @@
const int8 YM2413::levelScaling[16] = {
const i8 YM2413::levelScaling[16] = {
//-6 dB/octave, -6 dB/8 units
//input: fnumber.bits(5,8)
0, 24, 32, 37, 40, 43, 45, 47, 48, 50, 51, 52, 53, 54, 55, 56,
};
const uint64 YM2413::envelopeSteps[17][2] = {
const n64 YM2413::envelopeSteps[17][2] = {
//{attack sequence, decay sequence },
{0x0101010101010101, 0x0101010101010101}, // 4..44
{0x0101110101011101, 0x0101110101011101}, // 5..45
@@ -25,35 +25,31 @@ const uint64 YM2413::envelopeSteps[17][2] = {
{0x0000000000000000, 0x2222222222222222}, //60+
};
/* these are approximations and are not hardware accurate */
const uint8 YM2413::melodicTonesOPLL[15][8] = {
{0x61, 0x61, 0x1e, 0x17, 0xf0, 0x78, 0x00, 0x17},
{0x13, 0x41, 0x1e, 0x0d, 0xd7, 0xf7, 0x13, 0x13},
{0x13, 0x01, 0x99, 0x04, 0xf2, 0xf4, 0x11, 0x23},
{0x21, 0x61, 0x1b, 0x07, 0xaf, 0x64, 0x40, 0x27},
{0x22, 0x21, 0x1e, 0x06, 0xf0, 0x75, 0x08, 0x18},
{0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x13},
{0x21, 0x61, 0x1d, 0x07, 0x82, 0x80, 0x10, 0x17},
{0x23, 0x21, 0x2d, 0x16, 0xc0, 0x70, 0x07, 0x07},
const n8 YM2413::melodicTonesOPLL[15][8] = {
{0x71, 0x61, 0x1e, 0x17, 0xd0, 0x78, 0x00, 0x17},
{0x13, 0x41, 0x1a, 0x0d, 0xd8, 0xf7, 0x23, 0x13},
{0x13, 0x01, 0x99, 0x00, 0xf2, 0xc4, 0x11, 0x23},
{0x31, 0x61, 0x0e, 0x07, 0xa8, 0x64, 0x70, 0x27},
{0x32, 0x21, 0x1e, 0x06, 0xe0, 0x76, 0x00, 0x28},
{0x31, 0x22, 0x16, 0x05, 0xe0, 0x71, 0x00, 0x18},
{0x21, 0x61, 0x1d, 0x07, 0x82, 0x81, 0x10, 0x07},
{0x23, 0x21, 0x2d, 0x14, 0xa2, 0x72, 0x00, 0x07},
{0x61, 0x61, 0x1b, 0x06, 0x64, 0x65, 0x10, 0x17},
{0x61, 0x61, 0x0c, 0x18, 0x85, 0xf0, 0x70, 0x07},
{0x23, 0x01, 0x07, 0x11, 0xf0, 0xa4, 0x00, 0x22},
{0x97, 0xc1, 0x24, 0x07, 0xff, 0xf8, 0x22, 0x12},
{0x61, 0x10, 0x0c, 0x05, 0xf2, 0xf4, 0x40, 0x44},
{0x01, 0x01, 0x55, 0x03, 0xf3, 0x92, 0xf3, 0xf3},
{0x61, 0x41, 0x89, 0x03, 0xf1, 0xf4, 0xf0, 0x13},
{0x41, 0x61, 0x0b, 0x18, 0x85, 0xf7, 0x71, 0x07},
{0x13, 0x01, 0x83, 0x11, 0xfa, 0xe4, 0x10, 0x04},
{0x17, 0xc1, 0x24, 0x07, 0xf8, 0xf8, 0x22, 0x12},
{0x61, 0x50, 0x0c, 0x05, 0xc2, 0xf5, 0x20, 0x42},
{0x01, 0x01, 0x55, 0x03, 0xc9, 0x95, 0x03, 0x02},
{0x61, 0x41, 0x89, 0x03, 0xf1, 0xe4, 0x40, 0x13},
};
const uint8 YM2413::rhythmTonesOPLL[3][8] = {
{0x01, 0x01, 0x16, 0x00, 0xfd, 0xf8, 0x2f, 0x6d},
{0x01, 0x01, 0x00, 0x00, 0xd8, 0xd8, 0xf9, 0xf8},
{0x05, 0x01, 0x00, 0x00, 0xf8, 0xba, 0x49, 0x55},
const n8 YM2413::rhythmTonesOPLL[3][8] = {
{0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d},
{0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x48},
{0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55},
};
/* these tables were extracted from the VRC7 debug mode: likely inaccurate for the YM2413 */
const uint8 YM2413::melodicTonesVRC7[15][8] = {
const n8 YM2413::melodicTonesVRC7[15][8] = {
{0x03, 0x21, 0x05, 0x06, 0xe8, 0x81, 0x42, 0x27}, //1: violin
{0x13, 0x41, 0x14, 0x0d, 0xd8, 0xf6, 0x23, 0x12}, //2: guitar
{0x11, 0x11, 0x08, 0x08, 0xfa, 0xb2, 0x20, 0x12}, //3: piano
@@ -71,11 +67,11 @@ const uint8 YM2413::melodicTonesVRC7[15][8] = {
{0x21, 0x72, 0x0d, 0x00, 0xc1, 0xd5, 0x56, 0x06}, //f: electric guitar
};
const uint8 YM2413::rhythmTonesVRC7[3][8] = {
const n8 YM2413::rhythmTonesVRC7[3][8] = {
{0x01, 0x01, 0x18, 0x0f, 0xdf, 0xf8, 0x6a, 0x6d}, //7, 13/16: bass drum
{0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x68}, //8, 14/17: hihat, snare drum
{0x01, 0x01, 0x00, 0x00, 0xc8, 0xd8, 0xa7, 0x48}, //8, 14/17: hihat, snare drum
{0x05, 0x01, 0x00, 0x00, 0xf8, 0xaa, 0x59, 0x55}, //9, 15/18: tomtom, top cymbal
};
uint13 YM2413::sinTable[1 << 10];
int12 YM2413::expTable[1 << 9];
n13 YM2413::sinTable[1 << 10];
i12 YM2413::expTable[1 << 9];
+7 -7
View File
@@ -1,14 +1,14 @@
auto YM2413::address(uint8 data) -> void {
auto YM2413::address(n8 data) -> void {
io.address = data;
}
auto YM2413::write(uint8 data) -> void {
uint4 index = io.address.bit(0,3) % 9;
auto YM2413::write(n8 data) -> void {
n4 index = io.address.bit(0,3) % 9;
auto& voice = voices[index];
if(io.address >= 0x00 && io.address <= 0x07) {
customTone[io.address] = data;
for(uint n : range(9)) {
for(u32 n : range(9)) {
if(voices[n].tone == 0) reload(n);
}
return;
@@ -18,7 +18,7 @@ auto YM2413::write(uint8 data) -> void {
if(io.isVRC7) return;
if(io.rhythmMode != data.bit(5)) {
io.rhythmMode = data.bit(5);
for(uint n : range(9)) reload(n);
for(u32 n : range(9)) reload(n);
}
if(io.rhythmMode) {
hihat.trigger(data.bit(0));
@@ -46,8 +46,8 @@ auto YM2413::write(uint8 data) -> void {
if(io.isVRC7 && index >= 6) return;
voice.fnumber.bit(8) = data.bit(0);
voice.block = data.bit(1,3);
uint1 keyOn = data.bit(4);
uint1 sustainOn = data.bit(5);
n1 keyOn = data.bit(4);
n1 sustainOn = data.bit(5);
voice.update();
voice.carrier.trigger(keyOn, sustainOn);
return;
+11 -11
View File
@@ -1,15 +1,15 @@
auto YM2413::Operator::releaseRate() const -> uint4 {
auto YM2413::Operator::releaseRate() const -> n4 {
if(state == Trigger) return 13;
if(state == Attack) return attack;
if(state == Decay) return decay;
if(state == Sustain) return sustainable ? (uint4)0 : release;
if(state == Sustain) return sustainable ? (n4)0 : release;
// state == Release
if(!audible) return 0; //should never happen
if(sustainOn) return 5; //carrier only
return sustainable ? release : (uint4)7;
return sustainable ? release : (n4)7;
}
auto YM2413::Operator::update(maybe<uint> updateState) -> void {
auto YM2413::Operator::update(maybe<u32> updateState) -> void {
if(updateState) state = updateState();
auto baseRate = releaseRate();
@@ -29,12 +29,12 @@ auto YM2413::Operator::update(maybe<uint> updateState) -> void {
m += (m == 14) - (m == 13 || m == 11); //unimplemented; maps to 15, 12, or 10
m = max(1, 2 * m); //0 => 1/2, which truncates fnumber bit 0
for(uint n : range(8)) {
for(u32 n : range(8)) {
pitch[n] = (fnumber + lfo[n]) * m / 2 << block;
}
}
auto YM2413::Operator::synchronize(uint1 hard, maybe<Operator&> modulator) -> void {
auto YM2413::Operator::synchronize(n1 hard, maybe<Operator&> modulator) -> void {
if(state == Trigger && envelope.bit(2,6) == 31) {
update(Attack);
if(rate >= 60) update(Decay), envelope = 0;
@@ -51,15 +51,15 @@ auto YM2413::Operator::synchronize(uint1 hard, maybe<Operator&> modulator) -> vo
}
//only carriers (never modulators) call trigger()
auto YM2413::Operator::trigger(uint1 key, uint1 sustain) -> void {
auto YM2413::Operator::trigger(n1 key, n1 sustain) -> void {
sustainOn = sustain;
if(keyOn == key) return;
keyOn = key;
update(keyOn ? Trigger : Release);
}
auto YM2413::Operator::clock(natural clock, integer offset, integer modulation) -> int12 {
uint14 y = YM2413::sinTable[uint10(offset + modulation)];
auto YM2413::Operator::clock(natural clock, integer offset, integer modulation) -> i12 {
n14 y = YM2413::sinTable[n10(offset + modulation)];
if(waveform & ~y.bit(0)) y = sinTable[0];
auto w = clock / 64 % 210 * tremolo;
auto lfo = (w < 105 ? w : 210 - w) >> 3;
@@ -71,8 +71,8 @@ auto YM2413::Operator::clock(natural clock, integer offset, integer modulation)
phase += pitch[clock / 1024 % 8 * vibrato];
auto lsbs = divider ? clock.bit(0, divider - 1) : 0;
if(rate && (state == Attack ? lsbs & -4 : lsbs) == 0) {
natural msbs = uint4(clock >> divider);
integer step = uint4(sequence << 4 * msbs >> 60);
natural msbs = n4(clock >> divider);
integer step = n4(sequence << 4 * msbs >> 60);
if(state == Attack) step = ~envelope * step >> 4;
envelope = max(0x00, min(0x7f, envelope + step));
}
+42 -45
View File
@@ -1,55 +1,52 @@
auto YM2413::serialize(serializer& s) -> void {
//melodicTones and rhythmTones are not serialized here:
//they are reloaded during YM2413::power()
s.array(customTone);
for(auto& voice : voices) voice.serialize(s);
s.integer(io.clock);
s.integer(io.address);
s.integer(io.rhythmMode);
s.integer(io.noise);
s.integer(io.isVRC7);
s(customTone);
for(auto& voice : voices) s(voice);
s(io.clock);
s(io.address);
s(io.rhythmMode);
s(io.noise);
s(io.isVRC7);
}
auto YM2413::Voice::serialize(serializer& s) -> void {
s.integer(tone);
s.integer(fnumber);
s.integer(block);
s.integer(level);
s.integer(feedback);
modulator.serialize(s);
carrier.serialize(s);
s(tone);
s(fnumber);
s(block);
s(level);
s(feedback);
s(modulator);
s(carrier);
}
auto YM2413::Operator::serialize(serializer& s) -> void {
s.integer(slot);
s.integer(keyOn);
s.integer(sustainOn);
s.integer(multiple);
s.integer(scaleRate);
s.integer(sustainable);
s.integer(vibrato);
s.integer(tremolo);
s.integer(scaleLevel);
s.integer(waveform);
s.integer(attack);
s.integer(decay);
s.integer(sustain);
s.integer(release);
s.integer(totalLevel);
s.integer(audible);
s.integer(state);
s.integer(rate);
s.integer(divider);
s.integer(sequence);
s.integer(envelope);
s.integer(level);
s.integer(fnumber);
s.integer(block);
s.array(pitch);
s.integer(phase);
s.integer(output);
s.integer(prior);
s(slot);
s(keyOn);
s(sustainOn);
s(multiple);
s(scaleRate);
s(sustainable);
s(vibrato);
s(tremolo);
s(scaleLevel);
s(waveform);
s(attack);
s(decay);
s(sustain);
s(release);
s(totalLevel);
s(audible);
s(state);
s(rate);
s(divider);
s(sequence);
s(envelope);
s(level);
s(fnumber);
s(block);
s(pitch);
s(phase);
s(output);
s(prior);
}
+1 -1
View File
@@ -1,4 +1,4 @@
auto YM2413::Voice::update(const uint8* data) -> void {
auto YM2413::Voice::update(const n8* data) -> void {
if(data) {
modulator.multiple = data[0].bit(0,3);
modulator.scaleRate = data[0].bit(4);
+10 -10
View File
@@ -9,12 +9,12 @@ namespace ares {
#include "io.cpp"
#include "serialization.cpp"
auto YM2413::clock() -> double {
auto YM2413::clock() -> f64 {
auto melody = 0;
auto rhythm = 0;
auto mask = -(1 << 12 - 9);
for(uint index : range(io.rhythmMode ? 6 : 9)) {
for(u32 index : range(io.rhythmMode ? 6 : 9)) {
auto& voice = voices[index];
auto input = voice.modulator.output + voice.modulator.prior >> 8 - voice.feedback;
voice.modulator.clock(io.clock, voice.modulator.phase >> 9, voice.feedback ? input : 0);
@@ -50,7 +50,7 @@ auto YM2413::clock() -> double {
return mix / 32768.0 * 4.0;
}
auto YM2413::reload(uint4 index) -> void {
auto YM2413::reload(n4 index) -> void {
auto& voice = voices[index];
voice.modulator.audible = io.rhythmMode && index > 6;
voice.carrier.audible = true;
@@ -74,23 +74,23 @@ auto YM2413::power(bool isVRC7) -> void {
//10.9 fixed point phases
auto y = sin((2 * x + 1) * Math::Pi / 1024.0); //0x400 units to 2pi radians
auto z = -(1 << 8) * log(y) / log(2); //convert to -6 dB/256 units
auto s = (1 << 10) * pow(2, uint8(~x) / 256.0); //0x7fa .. 0x400
auto s = (1 << 10) * pow(2, n8(~x) / 256.0); //0x7fa .. 0x400
sinTable[0x000 + x] = sinTable[0x1ff - x] = uint(z + 0.5) * 2 + 1;
sinTable[0x200 + x] = sinTable[0x3ff - x] = uint(z + 0.5) * 2 + 0;
sinTable[0x000 + x] = sinTable[0x1ff - x] = u32(z + 0.5) * 2 + 1;
sinTable[0x200 + x] = sinTable[0x3ff - x] = u32(z + 0.5) * 2 + 0;
expTable[x * 2 + 1] = +uint(s + 0.5);
expTable[x * 2 + 0] = ~uint(s + 0.5);
expTable[x * 2 + 1] = +u32(s + 0.5);
expTable[x * 2 + 0] = ~u32(s + 0.5);
}
io = {};
io.isVRC7 = isVRC7;
for(uint n : range(9)) {
for(u32 n : range(9)) {
voices[n] = {};
reload(n);
}
for(uint n : range(3)) {
for(u32 n : range(3)) {
voices[3 * n + 0].modulator.slot = 1 + 6 * n;
voices[3 * n + 1].modulator.slot = 2 + 6 * n;
voices[3 * n + 2].modulator.slot = 3 + 6 * n;
+60 -60
View File
@@ -7,102 +7,102 @@ namespace ares {
struct YM2413 {
//ym2413.cpp
auto clock() -> double;
auto reload(uint4 voice) -> void;
auto clock() -> f64;
auto reload(n4 voice) -> void;
auto power(bool isVRC7 = false) -> void;
//io.cpp
auto address(uint8 data) -> void;
auto write(uint8 data) -> void;
auto address(n8 data) -> void;
auto write(n8 data) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
protected:
static const int8 levelScaling[16];
static const uint64 envelopeSteps[17][2];
static const uint8 melodicTonesOPLL[15][8];
static const uint8 rhythmTonesOPLL[3][8];
static const uint8 melodicTonesVRC7[15][8];
static const uint8 rhythmTonesVRC7[3][8];
static uint13 sinTable[1 << 10];
static int12 expTable[1 << 9];
uint8 melodicTones[15][8];
uint8 rhythmTones[3][8];
uint8 customTone[8];
static const i8 levelScaling[16];
static const n64 envelopeSteps[17][2];
static const n8 melodicTonesOPLL[15][8];
static const n8 rhythmTonesOPLL[3][8];
static const n8 melodicTonesVRC7[15][8];
static const n8 rhythmTonesVRC7[3][8];
static n13 sinTable[1 << 10];
static i12 expTable[1 << 9];
n8 melodicTones[15][8];
n8 rhythmTones[3][8];
n8 customTone[8];
enum : uint { Trigger, Attack, Decay, Sustain, Release };
enum : u32 { Trigger, Attack, Decay, Sustain, Release };
struct Operator {
//operator.cpp
auto releaseRate() const -> uint4;
auto update(maybe<uint> state = {}) -> void;
auto synchronize(uint1 hard, maybe<Operator&> modulator = {}) -> void;
auto trigger(uint1 key, uint1 sustain = 0) -> void;
auto clock(natural clock, integer offset, integer modulation = 0) -> int12;
auto releaseRate() const -> n4;
auto update(maybe<u32> state = {}) -> void;
auto synchronize(n1 hard, maybe<Operator&> modulator = {}) -> void;
auto trigger(n1 key, n1 sustain = 0) -> void;
auto clock(natural clock, integer offset, integer modulation = 0) -> i12;
//serialization.cpp
auto serialize(serializer&) -> void;
uint5 slot; //1-18
uint1 keyOn;
uint1 sustainOn;
uint4 multiple;
uint1 scaleRate;
uint1 sustainable;
uint1 vibrato;
uint1 tremolo;
uint2 scaleLevel;
uint1 waveform;
uint4 attack;
uint4 decay;
uint4 sustain;
uint4 release;
uint6 totalLevel;
uint1 audible;
n5 slot; //1-18
n1 keyOn;
n1 sustainOn;
n4 multiple;
n1 scaleRate;
n1 sustainable;
n1 vibrato;
n1 tremolo;
n2 scaleLevel;
n1 waveform;
n4 attack;
n4 decay;
n4 sustain;
n4 release;
n6 totalLevel;
n1 audible;
//envelope generator
uint3 state = Release;
uint7 rate;
uint4 divider;
uint64 sequence;
uint7 envelope = 0x7f;
uint7 level;
n3 state = Release;
n7 rate;
n4 divider;
n64 sequence;
n7 envelope = 0x7f;
n7 level;
//phase generator
uint9 fnumber;
uint3 block;
uint19 pitch[8];
uint19 phase;
n9 fnumber;
n3 block;
n19 pitch[8];
n19 phase;
//output
int12 output;
int12 prior;
i12 output;
i12 prior;
};
struct Voice {
//voice.cpp
auto update(const uint8* data = nullptr) -> void;
auto update(const n8* data = nullptr) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
uint4 tone;
uint9 fnumber;
uint3 block;
uint4 level;
uint3 feedback;
n4 tone;
n9 fnumber;
n3 block;
n4 level;
n3 feedback;
Operator modulator;
Operator carrier;
} voices[9];
struct IO {
uint32 clock;
uint8 address;
uint1 rhythmMode;
uint23 noise = 1;
uint1 isVRC7 = 0;
n32 clock;
n8 address;
n1 rhythmMode;
n23 noise = 1;
n1 isVRC7 = 0;
} io;
Voice& bass = voices[6];
+47
View File
@@ -0,0 +1,47 @@
auto YM2610::read(n2 address) -> n8 {
switch(address) {
case 0: return fm.readStatus();
}
return 0;
}
auto YM2610::write(n2 address, n8 data) -> void {
switch(address) {
case 0: register = 0x000 | data; return;
case 1: return writeLower(data);
case 2: register = 0x100 | data; return;
case 3: return writeUpper(data);
}
}
auto YM2610::writeLower(n8 data) -> void {
switch(register) {
case 0x000 ... 0x00f:
ssg.select(register);
ssg.write(data);
return;
case 0x010 ... 0x01b:
//ADPCM-B
return;
case 0x01c:
//EOS
return;
case 0x01d ... 0x1ff:
fm.writeAddress(register);
fm.writeData(data);
return;
}
unreachable;
}
auto YM2610::writeUpper(n8 data) -> void {
switch(register) {
case 0x000 ... 0x12f:
//ADPCM-A
return;
case 0x130 ... 0x1ff:
fm.writeAddress(register);
fm.writeData(data);
return;
}
}
@@ -0,0 +1,5 @@
auto YM2610::serialize(serializer& s) -> void {
s(register);
s(fm);
s(ssg);
}
+14
View File
@@ -0,0 +1,14 @@
#include <ares/ares.hpp>
#include "ym2610.hpp"
namespace ares {
#include "io.cpp"
#include "serialization.cpp"
auto YM2610::power() -> void {
fm.power();
ssg.power();
}
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <component/audio/ym2612/ym2612.hpp>
#include <component/audio/ym2149/ym2149.hpp>
namespace ares {
//Yamaha YM2610 (OPNB)
struct YM2610 {
//ym2610.cpp
auto power() -> void;
//io.cpp
auto read(n2 address) -> n8;
auto write(n2 address, n8 data) -> void;
auto writeLower(n8 data) -> void;
auto writeUpper(n8 data) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
protected:
n9 register;
YM2612 fm;
YM2149 ssg;
};
}
@@ -27,15 +27,15 @@ auto YM2612::Channel::Operator::trigger(bool state) -> void {
}
auto YM2612::Channel::Operator::runEnvelope() -> void {
uint sustain = envelope.sustainLevel < 15 ? envelope.sustainLevel << 5 : 0x3f0;
u32 sustain = envelope.sustainLevel < 15 ? envelope.sustainLevel << 5 : 0x3f0;
if(ym2612.envelope.clock & (1 << envelope.divider) - 1) return;
uint value = ym2612.envelope.clock >> envelope.divider;
uint step = envelope.steps >> ((~value & 7) << 2) & 0xf;
u32 value = ym2612.envelope.clock >> envelope.divider;
u32 step = envelope.steps >> ((~value & 7) << 2) & 0xf;
if(ssg.enable) step <<= 2; //SSG results in a 4x faster envelope
if(envelope.state == Attack) {
uint next = envelope.value + (~uint16(envelope.value) * step >> 4) & 0x3ff;
u32 next = envelope.value + (~u16(envelope.value) * step >> 4) & 0x3ff;
if(next <= envelope.value) {
envelope.value = next;
} else {
@@ -80,9 +80,9 @@ auto YM2612::Channel::Operator::runPhase() -> void {
}
auto YM2612::Channel::Operator::updateEnvelope() -> void {
uint key = min(max((uint)pitch.value, 0x300), 0x4ff);
uint ksr = (octave.value << 2) + ((key - 0x300) >> 7);
uint rate = 0;
u32 key = min(max((u32)pitch.value, 0x300), 0x4ff);
u32 ksr = (octave.value << 2) + ((key - 0x300) >> 7);
u32 rate = 0;
if(envelope.state == Attack) rate += (envelope.attackRate << 1);
if(envelope.state == Decay) rate += (envelope.decayRate << 1);
@@ -110,13 +110,13 @@ auto YM2612::Channel::Operator::updatePitch() -> void {
}
auto YM2612::Channel::Operator::updatePhase() -> void {
uint key = min(max((uint)pitch.value, 0x300), 0x4ff);
uint ksr = (octave.value << 2) + ((key - 0x300) >> 7);
uint tuning = detune & 3 ? detunes[(detune & 3) - 1][ksr & 7] >> (3 - (ksr >> 3)) : 0;
u32 key = min(max((u32)pitch.value, 0x300), 0x4ff);
u32 ksr = (octave.value << 2) + ((key - 0x300) >> 7);
u32 tuning = detune & 3 ? detunes[(detune & 3) - 1][ksr & 7] >> (3 - (ksr >> 3)) : 0;
uint lfo = ym2612.lfo.clock >> 2 & 0x1f;
uint pm = 4 * vibratos[channel.vibrato][lfo & 15] * (-lfo >> 4);
uint msb = 10;
u32 lfo = ym2612.lfo.clock >> 2 & 0x1f;
u32 pm = 4 * vibratos[channel.vibrato][lfo & 15] * (-lfo >> 4);
u32 msb = 10;
while(msb > 4 && ~pitch.value & 1 << msb) msb--;
phase.delta = pitch.value + (pm >> 10 - msb) << 6 >> 7 - octave.value;
@@ -125,11 +125,11 @@ auto YM2612::Channel::Operator::updatePhase() -> void {
}
auto YM2612::Channel::Operator::updateLevel() -> void {
uint lfo = ym2612.lfo.clock & 0x40 ? ym2612.lfo.clock & 0x3f : ~ym2612.lfo.clock & 0x3f;
uint depth = tremolos[channel.tremolo];
u32 lfo = ym2612.lfo.clock & 0x40 ? ym2612.lfo.clock & 0x3f : ~ym2612.lfo.clock & 0x3f;
u32 depth = tremolos[channel.tremolo];
bool invert = ssg.attack != ssg.invert && envelope.state != Release;
uint10 value = ssg.enable && invert ? 0x200 - envelope.value : 0 + envelope.value;
n10 value = ssg.enable && invert ? 0x200 - envelope.value : 0 + envelope.value;
outputLevel = ((totalLevel << 3) + value + (lfoEnable ? lfo << 1 >> depth : 0)) << 3;
}
Loaded 100 of 2336 files, more files were not shown because too many files have changed in this diff. Show more