mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-24 07:02:27 +01:00
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
108 lines
2.2 KiB
C++
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;
|
|
}
|
|
|
|
}
|