mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-22 22:22:42 +01:00
byuu says: Changelog: - SFC: fixed behavior of 21fx $21fe register when no device is connected (must return zero) - SFC: reduced 21fx buffer size to 1024 bytes in both directions to mirror the FT232H we are using - SFC: eliminated dsp/modulo-array.hpp [1] - higan: implemented higan/video interface and migrated all cores to it [2] [1] the echo history buffer was 8-bytes, so there was no need for it at all here. Not sure what I was thinking. The BRR buffer was 12-bytes, and has very weird behavior ... but there's only a single location in the code where it actually writes to this buffer. It's much easier to just write to the buffer three times there instead of implementing an entire class just to abstract away two lines of code. This change actually boosted the speed from ~124.5fps to around ~127.5fps, but that's within the margin of error for GCC. I doubt it's actually faster this way. The DSP core could really use a ton of work. It comes from a port of blargg's spc_dsp to my coding style, but he was extremely fond of using 32-bit signed integers everywhere. There's a lot of opportunity to remove red tape masking by resizing the variables to their actual state sizes. I really need to find where I put spc_dsp6.sfc from blargg. It's a great test to verify if I've made any mistakes in my implementation that would cause regressions. Don't suppose anyone has it? [2] so again, the idea is that higan/audio and higan/video are going to sit between the emulation cores and the user interfaces. The hope is to output raw encoding data from the emulation cores without having to worry about the video display format (generally 24-bit RGB) of the host display. And also to avoid having to repeat myself with eg three separate implementations of interframe blending, and so on. Furthermore, the idea is that the user interface can configure its side of the settings, and the emulation cores can configure their sides. Thus, neither has to worry about the other end. And now we can spin off new user interfaces much easier without having to mess with all of these things. Right now, I've implemented color emulation, interframe blending and SNES horizontal color bleed. I did not implement scanlines (and interlace effects for them) yet, but I probably will at some point. Further, for right now, the WonderSwan/Color screen rotation is busted and will only show games in the horizontal orientation. Obviously this must be fixed before the next official release, but I'll want to think about how to implement it. Also, the SNES light gun pointers are missing for now. Things are a bit messy right now as I've gone through several revisions of how to handle these things, so a good house cleaning is in order once everything is feature-complete again. I need to sit down and think through how and where I want to handle things like light gun cursors, LCD icons, and maybe even rasterized text messages. And obviously ... higan/audio is still just nall::DSP's headers. I need to revamp that whole interface. I want to make it quite powerful with a true audio mixer so I can handle things like SNES+SGB+MSU1+Voicer-Kun+SNES-CD (five separate audio streams at once.) The video system has the concept of "effects" for things like color bleed and interframe blending. I want to extend on this with useful other effects, such as NTSC simulation, maybe bringing back my mini-HQ2x filter, etc. I'd also like to restore the saturation/gamma/luma adjustment sliders ... I always liked allowing people to compensate for their displays without having to change settings system-wide. Lastly, I've always wanted to see some audio effects. Although I doubt we'll ever get my dream of CoreAudio-style profiles, I'd like to get some basic equalizer settings and echo/reverb effects in there.
168 lines
3.5 KiB
C++
168 lines
3.5 KiB
C++
struct PPU : Thread, PPUcounter {
|
|
alwaysinline auto interlace() const -> bool { return display.interlace; }
|
|
alwaysinline auto overscan() const -> bool { return display.overscan; }
|
|
alwaysinline auto vdisp() const -> uint { return !regs.overscan ? 225 : 240; }
|
|
|
|
PPU();
|
|
~PPU();
|
|
|
|
alwaysinline auto step(uint clocks) -> void;
|
|
alwaysinline auto synchronizeCPU() -> void;
|
|
|
|
static auto Enter() -> void;
|
|
auto main() -> void;
|
|
auto power() -> void;
|
|
auto reset() -> void;
|
|
|
|
auto serialize(serializer&) -> void;
|
|
|
|
//memory.cpp
|
|
alwaysinline auto getVramAddress() -> uint16;
|
|
alwaysinline auto vramRead(uint addr) -> uint8;
|
|
alwaysinline auto vramWrite(uint addr, uint8 data) -> void;
|
|
alwaysinline auto oamRead(uint addr) -> uint8;
|
|
alwaysinline auto oamWrite(uint addr, uint8 data) -> void;
|
|
alwaysinline auto cgramRead(uint addr) -> uint8;
|
|
alwaysinline auto cgramWrite(uint addr, uint8 data) -> void;
|
|
|
|
//mmio.cpp
|
|
auto read(uint24 addr, uint8 data) -> uint8;
|
|
auto write(uint24 addr, uint8 data) -> void;
|
|
auto latchCounters() -> void;
|
|
auto updateVideoMode() -> void;
|
|
|
|
uint8 vram[64 * 1024];
|
|
uint8 oam[544];
|
|
uint8 cgram[512];
|
|
|
|
privileged:
|
|
uint ppu1_version = 1; //allowed: 1
|
|
uint ppu2_version = 3; //allowed: 1, 2, 3
|
|
|
|
uint32* output = nullptr;
|
|
|
|
struct {
|
|
bool interlace;
|
|
bool overscan;
|
|
} display;
|
|
|
|
alwaysinline auto addClocks(uint) -> void;
|
|
|
|
auto scanline() -> void;
|
|
auto frame() -> void;
|
|
|
|
struct Registers {
|
|
uint8 ppu1_mdr;
|
|
uint8 ppu2_mdr;
|
|
|
|
uint16 vram_readbuffer;
|
|
uint8 oam_latchdata;
|
|
uint8 cgram_latchdata;
|
|
uint8 bgofs_latchdata;
|
|
uint8 mode7_latchdata;
|
|
bool counters_latched;
|
|
bool latch_hcounter;
|
|
bool latch_vcounter;
|
|
|
|
uint10 oam_iaddr;
|
|
uint9 cgram_iaddr;
|
|
|
|
//$2100 INIDISP
|
|
bool display_disable;
|
|
uint4 display_brightness;
|
|
|
|
//$2102 OAMADDL
|
|
//$2103 OAMADDH
|
|
uint10 oam_baseaddr;
|
|
uint10 oam_addr;
|
|
bool oam_priority;
|
|
|
|
//$2105 BGMODE
|
|
bool bg3_priority;
|
|
uint8 bgmode;
|
|
|
|
//$210d BG1HOFS
|
|
uint16 mode7_hoffset;
|
|
|
|
//$210e BG1VOFS
|
|
uint16 mode7_voffset;
|
|
|
|
//$2115 VMAIN
|
|
bool vram_incmode;
|
|
uint2 vram_mapping;
|
|
uint8 vram_incsize;
|
|
|
|
//$2116 VMADDL
|
|
//$2117 VMADDH
|
|
uint16 vram_addr;
|
|
|
|
//$211a M7SEL
|
|
uint2 mode7_repeat;
|
|
bool mode7_vflip;
|
|
bool mode7_hflip;
|
|
|
|
//$211b M7A
|
|
uint16 m7a;
|
|
|
|
//$211c M7B
|
|
uint16 m7b;
|
|
|
|
//$211d M7C
|
|
uint16 m7c;
|
|
|
|
//$211e M7D
|
|
uint16 m7d;
|
|
|
|
//$211f M7X
|
|
uint16 m7x;
|
|
|
|
//$2120 M7Y
|
|
uint16 m7y;
|
|
|
|
//$2121 CGADD
|
|
uint9 cgram_addr;
|
|
|
|
//$2133 SETINI
|
|
bool mode7_extbg;
|
|
bool pseudo_hires;
|
|
bool overscan;
|
|
bool interlace;
|
|
|
|
//$213c OPHCT
|
|
uint16 hcounter;
|
|
|
|
//$213d OPVCT
|
|
uint16 vcounter;
|
|
} regs;
|
|
|
|
#include "background/background.hpp"
|
|
#include "screen/screen.hpp"
|
|
#include "sprite/sprite.hpp"
|
|
#include "window/window.hpp"
|
|
|
|
Background bg1;
|
|
Background bg2;
|
|
Background bg3;
|
|
Background bg4;
|
|
Sprite sprite;
|
|
Window window;
|
|
Screen screen;
|
|
|
|
friend class PPU::Background;
|
|
friend class PPU::Sprite;
|
|
friend class PPU::Window;
|
|
friend class PPU::Screen;
|
|
friend class Video;
|
|
|
|
struct Debugger {
|
|
hook<auto (uint16, uint8) -> void> vram_read;
|
|
hook<auto (uint16, uint8) -> void> oam_read;
|
|
hook<auto (uint16, uint8) -> void> cgram_read;
|
|
hook<auto (uint16, uint8) -> void> vram_write;
|
|
hook<auto (uint16, uint8) -> void> oam_write;
|
|
hook<auto (uint16, uint8) -> void> cgram_write;
|
|
} debugger;
|
|
};
|
|
|
|
extern PPU ppu;
|