bsnes/higan/ws/ppu/ppu.cpp
Tim Allen 8af3e4a6e2 Update to v102r22 release.
byuu says:

Changelog:

  - higan: Emulator::Interface::videoSize() renamed to videoResolution()
  - higan: Emulator::Interface::rtcsync() renamed to rtcSynchronize()
  - higan: added video display rotation support to Video
  - GBA: substantially improved audio mixing
      - fixed bug with FIFO 50%/100% volume setting
      - now properly using SOUNDBIAS amplitude to control output
        frequencies
      - reduced quantization noise
      - corrected relative volumes between PSG and FIFO channels
      - both PSG and FIFO values cached based on amplitude; resulting in
        cleaner PCM samples
      - treating PSG volume=3 as 200% volume instead of 0% volume now
        (unverified: to match mGBA)
  - GBA: properly initialize ALL CPU state; including the vital
    prefetch.wait=1 (fixes Classic NES series games)
  - GBA: added video rotation with automatic key translation support
  - PCE: reduced output resolution scalar from 285x242 to 285x240
      - the extra two scanlines won't be visible on most TVs; and they
        make all other cores look worse
      - this is because all other cores output at 240p or less; so they
        were all receiving black bars in windowed mode
  - tomoko: added "Rotate Display" hotkey setting
  - tomoko: changed hotkey multi-key logic to OR instead of AND
      - left support for flipping it back inside the core; for those so
        inclined; by uncommenting one line in input.hpp
  - tomoko: when choosing Settings→Configuration, it will
    automatically select the currently loaded system
      - for instance, if you're playing a Game Gear game, it'll take you
        to the Game Gear input settings
      - if no games are loaded, it will take you to the hotkeys panel
        instead
  - WS(C): merged "Hardware-Vertical", "Hardware-Horizontal" controls
    into combined "Hardware"
  - WS(C): converted rotation support from being inside the core to
    using Emulator::Video
      - this lets WS(C) video content scale larger now that it's not
        bounded by a 224x224 square box
  - WS(C): added automatic key rotation support
  - WS(C): removed emulator "Rotate" key (use the general hotkey
    instead; I recommend F8 for this)
  - nall: added serializer support for nall::Boolean (boolean) types
      - although I will probably prefer the usage of uint1 in most cases
2017-06-09 00:08:02 +10:00

108 lines
2.2 KiB
C++

#include <ws/ws.hpp>
namespace WonderSwan {
PPU ppu;
#include "io.cpp"
#include "latch.cpp"
#include "render.cpp"
#include "serialization.cpp"
auto PPU::Enter() -> void {
while(true) scheduler.synchronize(), ppu.main();
}
auto PPU::main() -> void {
if(s.vclk == 142) {
latchOAM();
}
if(s.vclk < 144) {
latchRegisters();
latchSprites();
for(auto x : range(224)) {
s.pixel = {Pixel::Source::Back, 0x000};
if(r.lcdEnable) {
renderBack();
if(l.screenOneEnable) renderScreenOne();
if(l.screenTwoEnable) renderScreenTwo();
if(l.spriteEnable) renderSprite();
}
output[s.vclk * 224 + x] = s.pixel.color;
step(1);
}
step(32);
} else {
step(256);
}
scanline();
if(r.htimerEnable && r.htimerCounter < r.htimerFrequency) {
if(++r.htimerCounter == r.htimerFrequency) {
if(r.htimerRepeat) {
r.htimerCounter = 0;
} else {
r.htimerEnable = false;
}
cpu.raise(CPU::Interrupt::HblankTimer);
}
}
}
auto PPU::scanline() -> void {
s.hclk = 0;
if(++s.vclk == 159) frame();
if(s.vclk == r.lineCompare) {
cpu.raise(CPU::Interrupt::LineCompare);
}
if(s.vclk == 144) {
cpu.raise(CPU::Interrupt::Vblank);
if(r.vtimerEnable && r.vtimerCounter < r.vtimerFrequency) {
if(++r.vtimerCounter == r.vtimerFrequency) {
if(r.vtimerRepeat) {
r.vtimerCounter = 0;
} else {
r.vtimerEnable = false;
}
cpu.raise(CPU::Interrupt::VblankTimer);
}
}
}
}
auto PPU::frame() -> void {
s.field = !s.field;
s.vclk = 0;
scheduler.exit(Scheduler::Event::Frame);
}
auto PPU::refresh() -> void {
Emulator::video.refresh(output, 224 * sizeof(uint32), 224, 144);
}
auto PPU::step(uint clocks) -> void {
s.hclk += clocks;
Thread::step(clocks);
synchronize(cpu);
}
auto PPU::power() -> void {
create(PPU::Enter, 3'072'000);
bus.map(this, 0x0000, 0x0017);
bus.map(this, 0x001c, 0x003f);
bus.map(this, 0x00a2);
bus.map(this, 0x00a4, 0x00ab);
for(auto& n : output) n = 0;
memory::fill(&s, sizeof(State));
memory::fill(&l, sizeof(Latches));
memory::fill(&r, sizeof(Registers));
r.lcdEnable = 1;
r.vtotal = 158;
r.vblank = 155;
}
}