From cb3460a673bc4351ba85a3ce6788e8946c76c006 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 15 Sep 2011 22:27:34 +1000 Subject: [PATCH] Update to v082r11 release. byuu says: Emulates grayscale and color emphasis modes, improves sprite timing and PPU bus fetching behavior with the PPU disabled. --- bsnes/Makefile | 2 +- bsnes/nes/interface/interface.hpp | 2 +- bsnes/nes/nes.hpp | 2 +- bsnes/nes/ppu/ppu.cpp | 176 ++++++++++++----------- bsnes/nes/ppu/ppu.hpp | 19 ++- bsnes/snes/snes.hpp | 2 +- bsnes/ui-gameboy/Makefile | 91 ------------ bsnes/ui-gameboy/base.hpp | 34 ----- bsnes/ui-gameboy/general/main-window.cpp | 134 ----------------- bsnes/ui-gameboy/general/main-window.hpp | 36 ----- bsnes/ui-gameboy/interface.cpp | 61 -------- bsnes/ui-gameboy/interface.hpp | 12 -- bsnes/ui-gameboy/main.cpp | 78 ---------- bsnes/ui-gameboy/utility/utility.cpp | 48 ------- bsnes/ui-gameboy/utility/utility.hpp | 11 -- bsnes/ui/interface/nes.cpp | 41 +++++- bsnes/ui/interface/nes.hpp | 7 +- 17 files changed, 151 insertions(+), 605 deletions(-) delete mode 100755 bsnes/ui-gameboy/Makefile delete mode 100755 bsnes/ui-gameboy/base.hpp delete mode 100755 bsnes/ui-gameboy/general/main-window.cpp delete mode 100755 bsnes/ui-gameboy/general/main-window.hpp delete mode 100755 bsnes/ui-gameboy/interface.cpp delete mode 100755 bsnes/ui-gameboy/interface.hpp delete mode 100755 bsnes/ui-gameboy/main.cpp delete mode 100755 bsnes/ui-gameboy/utility/utility.cpp delete mode 100755 bsnes/ui-gameboy/utility/utility.hpp diff --git a/bsnes/Makefile b/bsnes/Makefile index 7ad84c06..beb37c5c 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -75,6 +75,6 @@ clean: -@$(call delete,*.manifest) archive-all: - tar -cjf bsnes.tar.bz2 data gameboy libco nall nes obj out phoenix ruby snes ui ui-gameboy ui-libsnes ui-snes Makefile cc.bat clean.bat sync.sh + tar -cjf bsnes.tar.bz2 data gameboy libco nall nes obj out phoenix ruby snes ui ui-libsnes ui-snes Makefile cc.bat clean.bat sync.sh help:; diff --git a/bsnes/nes/interface/interface.hpp b/bsnes/nes/interface/interface.hpp index 2e22c488..4618bb57 100755 --- a/bsnes/nes/interface/interface.hpp +++ b/bsnes/nes/interface/interface.hpp @@ -1,5 +1,5 @@ struct Interface { - virtual void video_refresh(const uint32_t *data) {} + virtual void video_refresh(const uint16_t *data) {} virtual void audio_sample(int16_t sample) {} virtual int16_t input_poll(bool port, unsigned device, unsigned id) { return 0; } diff --git a/bsnes/nes/nes.hpp b/bsnes/nes/nes.hpp index 727476f1..565f6d9c 100755 --- a/bsnes/nes/nes.hpp +++ b/bsnes/nes/nes.hpp @@ -4,7 +4,7 @@ namespace NES { namespace Info { static const char Name[] = "bnes"; - static const char Version[] = "000.06"; + static const char Version[] = "000.07"; } } diff --git a/bsnes/nes/ppu/ppu.cpp b/bsnes/nes/ppu/ppu.cpp index 6dfc2da4..83ad9663 100755 --- a/bsnes/nes/ppu/ppu.cpp +++ b/bsnes/nes/ppu/ppu.cpp @@ -38,25 +38,6 @@ void PPU::frame_edge() { } void PPU::power() { - paletteRGB = { - 0x7c7c7c, 0x0000fc, 0x0000bc, 0x4428bc, - 0x940084, 0xa80020, 0xa81000, 0x881400, - 0x503000, 0x007800, 0x006800, 0x005800, - 0x004058, 0x000000, 0x000000, 0x000000, - 0xbcbcbc, 0x0078f8, 0x0058f8, 0x6844fc, - 0xd800cc, 0xe40058, 0xf83800, 0xe45c10, - 0xac7c00, 0x00b800, 0x00a800, 0x00a844, - 0x008888, 0x000000, 0x000000, 0x000000, - 0xf8f8f8, 0x3cbcfc, 0x6888fc, 0x9878f8, - 0xf878f8, 0xf85898, 0xf87858, 0xfca044, - 0xf8b800, 0xb8f818, 0x58d854, 0x58f898, - 0x00e8d8, 0x787878, 0x000000, 0x000000, - 0xfcfcfc, 0xa4e4fc, 0xb8b8b8, 0xd8d8f8, - 0xf8b8f8, 0xf8a4c0, 0xf0d0b0, 0xfce0a8, - 0xf8d878, 0xd8f878, 0xb8f8b8, 0xb8f8d8, - 0x00fcfc, 0xf8d8f8, 0x000000, 0x000000, - }; - reset(); } @@ -82,9 +63,7 @@ void PPU::reset() { status.vram_increment = 1; //$2001 - status.intensify_blue = false; - status.intensify_green = false; - status.intensify_red = false; + status.emphasis = 0; status.sprite_enable = false; status.bg_enable = false; status.sprite_edge_enable = false; @@ -132,7 +111,8 @@ uint8 PPU::read(uint16 addr) { result = status.bus_data; status.bus_data = cartridge.ciram_read(addr); } else if(addr <= 0x3fff) { - result = status.bus_data = cgram_read(addr); + result = cgram_read(addr); + status.bus_data = cartridge.ciram_read(addr); } status.vaddr += status.vram_increment; break; @@ -156,9 +136,7 @@ void PPU::write(uint16 addr, uint8 data) { status.taddr = (status.taddr & 0x73ff) | ((data & 0x03) << 10); return; case 1: //PPUMASK - status.intensify_blue = data & 0x80; - status.intensify_green = data & 0x40; - status.intensify_red = data & 0x20; + status.emphasis = data >> 5; status.sprite_enable = data & 0x10; status.bg_enable = data & 0x08; status.sprite_edge_enable = data & 0x04; @@ -215,7 +193,9 @@ void PPU::ciram_write(uint16 addr, uint8 data) { uint8 PPU::cgram_read(uint16 addr) { if((addr & 0x13) == 0x10) addr &= ~0x10; - return cgram[addr & 0x1f]; + uint8 data = cgram[addr & 0x1f]; + if(status.grayscale) data &= 0x30; + return data; } void PPU::cgram_write(uint16 addr, uint8 data) { @@ -233,7 +213,7 @@ void PPU::cgram_write(uint16 addr, uint8 data) { //XXXXX = X nametable (x:d3-d7) bool PPU::raster_enable() const { - return status.bg_enable || status.sprite_enable; + return (status.bg_enable || status.sprite_enable); } unsigned PPU::nametable_addr() const { @@ -248,6 +228,22 @@ unsigned PPU::scrolly() const { return (((status.vaddr >> 5) & 0x1f) << 3) | ((status.vaddr >> 12) & 7); } +unsigned PPU::sprite_height() const { + return status.sprite_size == 0 ? 8 : 16; +} + +// + +uint8 PPU::chr_load(uint16 addr) { + if(raster_enable() == false) return 0x00; + return cartridge.chr_read(addr); +} + +uint8 PPU::ciram_load(uint16 addr) { + if(raster_enable() == false) return 0x00; + return cartridge.ciram_read(addr); +} + // void PPU::ly_increment() { @@ -259,6 +255,7 @@ void PPU::ly_increment() { } void PPU::scrollx_increment() { + if(raster_enable() == false) return; status.vaddr = (status.vaddr & 0x7fe0) | ((status.vaddr + 0x0001) & 0x001f); if((status.vaddr & 0x001f) == 0x0000) { status.vaddr ^= 0x0400; @@ -266,6 +263,7 @@ void PPU::scrollx_increment() { } void PPU::scrolly_increment() { + if(raster_enable() == false) return; status.vaddr = (status.vaddr & 0x0fff) | ((status.vaddr + 0x1000) & 0x7000); if((status.vaddr & 0x7000) == 0x0000) { status.vaddr = (status.vaddr & 0x7c1f) | ((status.vaddr + 0x0020) & 0x03e0); @@ -279,10 +277,11 @@ void PPU::scrolly_increment() { // void PPU::raster_pixel(unsigned x) { - uint32 *output = buffer + status.ly * 256; + uint16 *output = buffer + status.ly * 256; unsigned mask = 0x8000 >> (status.xaddr + x); - unsigned palette = 0; + unsigned palette = 0, object_palette = 0; + bool object_priority = 0; palette |= (raster.tiledatalo & mask) ? 1 : 0; palette |= (raster.tiledatahi & mask) ? 2 : 0; if(palette) { @@ -293,7 +292,7 @@ void PPU::raster_pixel(unsigned x) { if(status.bg_edge_enable == false && status.lx < 8) palette = 0; - for(unsigned sprite = 0; sprite < 8; sprite++) { + for(signed sprite = 7; sprite >= 0; sprite--) { if(status.sprite_edge_enable == false && status.lx < 8) continue; if(raster.oam[sprite].id == 64) continue; @@ -310,14 +309,37 @@ void PPU::raster_pixel(unsigned x) { if(raster.oam[sprite].id == 0 && palette) status.sprite_zero_hit = 1; sprite_palette |= (raster.oam[sprite].attr & 3) << 2; - if((raster.oam[sprite].attr & 0x20) == 0 || palette == 0) { - palette = 16 + sprite_palette; - break; - } + object_priority = raster.oam[sprite].attr & 0x20; + object_palette = 16 + sprite_palette; + } + + if(object_palette) { + if(palette == 0 || object_priority == 0) palette = object_palette; } if(raster_enable() == false) palette = 0; - output[status.lx++] = paletteRGB[cgram[palette]]; + output[status.lx++] = (status.emphasis << 6) | cgram_read(palette); +} + +void PPU::raster_sprite() { + if(status.sprite_enable == false) return; + + unsigned n = raster.oam_iterator++; + signed ly = (status.ly == 261 ? -1 : status.ly); + unsigned y = ly - oam[(n * 4) + 0]; + + if(y >= sprite_height()) return; + if(raster.oam_counter == 8) { + status.sprite_overflow = 1; + return; + } + + raster.soam[raster.oam_counter].id = n; + raster.soam[raster.oam_counter].y = y; + raster.soam[raster.oam_counter].tile = oam[(n * 4) + 1]; + raster.soam[raster.oam_counter].attr = oam[(n * 4) + 2]; + raster.soam[raster.oam_counter].x = oam[(n * 4) + 3]; + raster.oam_counter++; } void PPU::raster_scanline() { @@ -327,12 +349,20 @@ void PPU::raster_scanline() { return ly_increment(); } - uint32 *output = buffer + status.ly * 256; signed lx = 0, ly = (status.ly == 261 ? -1 : status.ly); status.lx = 0; + raster.oam_iterator = 0; + raster.oam_counter = 0; + + for(unsigned n = 0; n < 8; n++) { + raster.soam[n].id = 64; + raster.soam[n].tiledatalo = 0; + raster.soam[n].tiledatahi = 0; + } + for(unsigned tile = 0; tile < 32; tile++) { // 0-255 - unsigned nametable = cartridge.ciram_read((uint13)status.vaddr); + unsigned nametable = ciram_load(status.vaddr & 0x0fff); unsigned tileaddr = status.bg_addr + (nametable << 4) + (scrolly() & 7); raster_pixel(0); tick(); @@ -340,31 +370,31 @@ void PPU::raster_scanline() { raster_pixel(1); tick(); - unsigned attribute = cartridge.ciram_read(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); + unsigned attribute = ciram_load(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); if(scrolly() & 16) attribute >>= 4; if(scrollx() & 16) attribute >>= 2; raster_pixel(2); tick(); - if(raster_enable()) { - scrollx_increment(); - if(tile == 31) scrolly_increment(); - } + scrollx_increment(); + if(tile == 31) scrolly_increment(); raster_pixel(3); + raster_sprite(); tick(); - unsigned tiledatalo = cartridge.chr_read(tileaddr + 0); + unsigned tiledatalo = chr_load(tileaddr + 0); raster_pixel(4); tick(); raster_pixel(5); tick(); - unsigned tiledatahi = cartridge.chr_read(tileaddr + 8); + unsigned tiledatahi = chr_load(tileaddr + 8); raster_pixel(6); tick(); raster_pixel(7); + raster_sprite(); tick(); raster.nametable = (raster.nametable << 8) | nametable; @@ -373,54 +403,32 @@ void PPU::raster_scanline() { raster.tiledatahi = (raster.tiledatahi << 8) | tiledatahi; } - for(unsigned n = 0; n < 8; n++) { - raster.oam[n].id = 64; - raster.oam[n].tiledatalo = 0; - raster.oam[n].tiledatahi = 0; - } - - //should occur every 4 cycles during main screen rendering - unsigned counter = 0; - unsigned sprite_height = status.sprite_size ? 16 : 8; - if(status.sprite_enable) for(unsigned n = 0; n < 64; n++) { - unsigned y = ly - oam[(n * 4) + 0]; - if(y >= sprite_height) continue; - if(counter == 8) { - status.sprite_overflow = 1; - break; - } - - raster.oam[counter].id = n; - raster.oam[counter].y = y; - raster.oam[counter].tile = oam[(n * 4) + 1]; - raster.oam[counter].attr = oam[(n * 4) + 2]; - raster.oam[counter].x = oam[(n * 4) + 3]; - counter++; - } + for(unsigned n = 0; n < 8; n++) raster.oam[n] = raster.soam[n]; for(unsigned sprite = 0; sprite < 8; sprite++) { //256-319 - unsigned nametable = cartridge.ciram_read((uint13)status.vaddr); + unsigned nametable = ciram_load(status.vaddr & 0x0fff); tick(); if(raster_enable() && sprite == 0) status.vaddr = (status.vaddr & 0x7be0) | (status.taddr & 0x041f); //257 tick(); - unsigned attribute = cartridge.ciram_read(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); - unsigned tileaddr = (sprite_height == 8) + unsigned attribute = ciram_load(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); + unsigned tileaddr = (sprite_height() == 8) ? status.sprite_addr + raster.oam[sprite].tile * 16 : ((raster.oam[sprite].tile & ~1) * 16) + ((raster.oam[sprite].tile & 1) * 0x1000); tick(); tick(); unsigned spritey = raster.oam[sprite].y; - if(raster.oam[sprite].attr & 0x80) spritey ^= (sprite_height - 1); - if(spritey & 8) spritey += 8; + if(raster.oam[sprite].attr & 0x80) spritey ^= (sprite_height() - 1); + tileaddr += spritey + (spritey & 8); + if(raster.oam[sprite].id == 64) tileaddr = status.sprite_addr; - raster.oam[sprite].tiledatalo = cartridge.chr_read(tileaddr + spritey + 0); + raster.oam[sprite].tiledatalo = chr_load(tileaddr + 0); tick(); tick(); - raster.oam[sprite].tiledatahi = cartridge.chr_read(tileaddr + spritey + 8); + raster.oam[sprite].tiledatahi = chr_load(tileaddr + 8); tick(); tick(); @@ -428,26 +436,24 @@ void PPU::raster_scanline() { } for(unsigned tile = 0; tile < 2; tile++) { //320-335 - unsigned nametable = cartridge.ciram_read((uint13)status.vaddr & 0x1fff); + unsigned nametable = ciram_load(status.vaddr & 0x0fff); unsigned tileaddr = status.bg_addr + (nametable << 4) + (scrolly() & 7); tick(); tick(); - unsigned attribute = cartridge.ciram_read(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); + unsigned attribute = ciram_load(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); if(scrolly() & 16) attribute >>= 4; if(scrollx() & 16) attribute >>= 2; tick(); - if(raster_enable()) { - scrollx_increment(); - } + scrollx_increment(); tick(); - unsigned tiledatalo = cartridge.chr_read(tileaddr + 0); + unsigned tiledatalo = chr_load(tileaddr + 0); tick(); tick(); - unsigned tiledatahi = cartridge.chr_read(tileaddr + 8); + unsigned tiledatahi = chr_load(tileaddr + 8); tick(); tick(); @@ -458,11 +464,11 @@ void PPU::raster_scanline() { } //336-339 - unsigned nametable = cartridge.ciram_read((uint13)status.vaddr & 0x1fff); + unsigned nametable = ciram_load(status.vaddr & 0x0fff); tick(); tick(); - unsigned attribute = cartridge.ciram_read(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); + unsigned attribute = ciram_load(0x03c0 | (status.vaddr & 0x0fc0) | ((scrolly() >> 5) << 3) | (scrollx() >> 5)); tick(); tick(); diff --git a/bsnes/nes/ppu/ppu.hpp b/bsnes/nes/ppu/ppu.hpp index 55f12433..f16d85e1 100755 --- a/bsnes/nes/ppu/ppu.hpp +++ b/bsnes/nes/ppu/ppu.hpp @@ -22,12 +22,17 @@ struct PPU : Processor { unsigned nametable_addr() const; unsigned scrollx() const; unsigned scrolly() const; + unsigned sprite_height() const; + + uint8 chr_load(uint16 addr); + uint8 ciram_load(uint16 addr); void ly_increment(); void scrollx_increment(); void scrolly_increment(); void raster_pixel(unsigned x); + void raster_sprite(); void raster_scanline(); struct Status { @@ -43,7 +48,7 @@ struct PPU : Processor { uint15 vaddr; uint15 taddr; - uint8 xaddr; + uint8 xaddr; //$2000 bool nmi_enable; @@ -54,9 +59,7 @@ struct PPU : Processor { unsigned vram_increment; //$2001 - bool intensify_blue; - bool intensify_green; - bool intensify_red; + uint3 emphasis; bool sprite_enable; bool bg_enable; bool sprite_edge_enable; @@ -78,6 +81,9 @@ struct PPU : Processor { uint16 tiledatalo; uint16 tiledatahi; + unsigned oam_iterator; + unsigned oam_counter; + struct OAM { uint8 id; uint8 y; @@ -87,11 +93,10 @@ struct PPU : Processor { uint8 tiledatalo; uint8 tiledatahi; - } oam[8]; + } oam[8], soam[8]; } raster; - uint32 buffer[256 * 262]; - uint32 paletteRGB[64]; + uint16 buffer[256 * 262]; uint8 ciram[2048]; uint8 cgram[32]; uint8 oam[256]; diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 84bee861..0c3549dc 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -4,7 +4,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "082.10"; + static const char Version[] = "082.11"; static const unsigned SerializerVersion = 21; } } diff --git a/bsnes/ui-gameboy/Makefile b/bsnes/ui-gameboy/Makefile deleted file mode 100755 index 00911327..00000000 --- a/bsnes/ui-gameboy/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -include $(gameboy)/Makefile - -ui_objects := ui-main ui-utility -ui_objects += ruby phoenix - -# platform -ifeq ($(platform),x) - ifeq ($(phoenix),gtk) - phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`) - link += `pkg-config --libs gtk+-2.0` - else - phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`) - link += `pkg-config --libs QtCore QtGui` - endif - - ruby := video.glx video.xv video.sdl - ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao - ruby += input.sdl input.x - - link += $(if $(findstring audio.openal,$(ruby)),-lopenal) -else ifeq ($(platform),osx) - phoenix_compile = $(call compile,-DPHOENIX_QT) - link += - - ruby := - ruby += audio.openal - ruby += input.carbon - - link += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL) -else ifeq ($(platform),win) - phoenix_compile = $(call compile,-DPHOENIX_WINDOWS) - link += - - ruby := video.direct3d video.wgl video.directdraw video.gdi - ruby += audio.directsound audio.xaudio2 - ruby += input.rawinput input.directinput - - link += $(if $(findstring audio.openal,$(ruby)),-lopenal32) -endif - -# ruby -rubyflags := $(if $(finstring .sdl,$(ruby)),`sdl-config --cflags`) - -link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`) -link += $(if $(findstring video.direct3d,$(ruby)),-ld3d9) -link += $(if $(findstring video.directdraw,$(ruby)),-lddraw) -link += $(if $(findstring video.glx,$(ruby)),-lGL) -link += $(if $(findstring video.wgl,$(ruby)),-lopengl32) -link += $(if $(findstring video.xv,$(ruby)),-lXv) -link += $(if $(findstring audio.alsa,$(ruby)),-lasound) -link += $(if $(findstring audio.ao,$(ruby)),-lao) -link += $(if $(findstring audio.directsound,$(ruby)),-ldsound) -link += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse) -link += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple) -link += $(if $(findstring audio.xaudio2,$(ruby)),-lole32) -link += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid) -link += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid) - -rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c) - -# rules -objects := $(ui_objects) $(objects) -objects := $(patsubst %,obj/%.o,$(objects)) - -obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*) -obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/utility/*) - -obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*) - $(call compile,$(rubydef) $(rubyflags)) - -obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*) - $(phoenix_compile) - -# targets -build: $(objects) -ifeq ($(platform),osx) - test -d ../bgameboy.app || mkdir -p ../bgameboy.app/Contents/MacOS - $(strip $(cpp) -o ../bgameboy.app/Contents/MacOS/bgameboy $(objects) $(link)) -else - $(strip $(cpp) -o out/bgameboy $(objects) $(link)) -endif - -install: -ifeq ($(platform),x) - install -D -m 755 out/bgameboy $(DESTDIR)$(prefix)/bin/bgameboy -endif - -uninstall: -ifeq ($(platform),x) - rm $(DESTDIR)$(prefix)/bin/bgameboy -endif diff --git a/bsnes/ui-gameboy/base.hpp b/bsnes/ui-gameboy/base.hpp deleted file mode 100755 index 840925ff..00000000 --- a/bsnes/ui-gameboy/base.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace nall; - -#include -using namespace ruby; - -#include -using namespace phoenix; - -#include - -#include "interface.hpp" - -#include "general/main-window.hpp" - -#include "utility/utility.hpp" - -struct Application { - bool quit; - - string proportionalFont; - string proportionalFontBold; - string monospaceFont; - - void main(int argc, char **argv); -}; - -extern nall::DSP dspaudio; -extern Application application; diff --git a/bsnes/ui-gameboy/general/main-window.cpp b/bsnes/ui-gameboy/general/main-window.cpp deleted file mode 100755 index c64ba9a4..00000000 --- a/bsnes/ui-gameboy/general/main-window.cpp +++ /dev/null @@ -1,134 +0,0 @@ -MainWindow mainWindow; - -void MainWindow::create() { - setTitle({ GameBoy::Info::Name, " v", GameBoy::Info::Version }); - setResizable(false); - setMenuFont(application.proportionalFont); - setWidgetFont(application.proportionalFont); - setStatusFont(application.proportionalFontBold); - - system.setText("System"); - append(system); - - systemLoadCartridge.setText("Load Cartridge ..."); - system.append(systemLoadCartridge); - - system.append(systemSeparator1); - - systemPower.setText("Power Cycle"); - system.append(systemPower); - - settings.setText("Settings"); - append(settings); - - settingsVideoSync.setText("Synchronize Video"); - settingsVideoSync.setChecked(false); - settings.append(settingsVideoSync); - - settingsAudioSync.setText("Synchronize Audio"); - settingsAudioSync.setChecked(true); - settings.append(settingsAudioSync); - - tools.setText("Tools"); - append(tools); - - toolsSaveState.setText("Save State"); - tools.append(toolsSaveState); - - toolsSaveState1.setText("Slot 1"); - toolsSaveState.append(toolsSaveState1); - - toolsSaveState2.setText("Slot 2"); - toolsSaveState.append(toolsSaveState2); - - toolsSaveState3.setText("Slot 3"); - toolsSaveState.append(toolsSaveState3); - - toolsSaveState4.setText("Slot 4"); - toolsSaveState.append(toolsSaveState4); - - toolsSaveState5.setText("Slot 5"); - toolsSaveState.append(toolsSaveState5); - - toolsLoadState.setText("Load State"); - tools.append(toolsLoadState); - - toolsLoadState1.setText("Slot 1"); - toolsLoadState.append(toolsLoadState1); - - toolsLoadState2.setText("Slot 2"); - toolsLoadState.append(toolsLoadState2); - - toolsLoadState3.setText("Slot 3"); - toolsLoadState.append(toolsLoadState3); - - toolsLoadState4.setText("Slot 4"); - toolsLoadState.append(toolsLoadState4); - - toolsLoadState5.setText("Slot 5"); - toolsLoadState.append(toolsLoadState5); - - tools.append(toolsSeparator1); - - toolsTraceCPU.setText("Trace CPU"); - tools.append(toolsTraceCPU); - - help.setText("Help"); - append(help); - - helpAbout.setText("About ..."); - help.append(helpAbout); - - layout.append(viewport, { 0, 0, 160 * 2, 144 * 2 }); - append(layout); - setGeometry({ 128, 128, 160 * 2, 144 * 2 }); - - setMenuVisible(true); - setStatusVisible(true); - - onClose = []() { - application.quit = true; - }; - - systemLoadCartridge.onTick = []() { - string filename = OS::fileLoad(mainWindow, "/media/sdb1/root/gameboy_images/", "Game Boy cartridges (*.gb,*.gbc)"); - if(filename != "") utility.loadCartridge(filename); - }; - - systemPower.onTick = []() { - if(GameBoy::cartridge.loaded()) GameBoy::system.power(); - }; - - settingsVideoSync.onTick = []() { - video.set(Video::Synchronize, mainWindow.settingsVideoSync.checked()); - }; - - settingsAudioSync.onTick = []() { - audio.set(Audio::Synchronize, mainWindow.settingsAudioSync.checked()); - }; - - toolsSaveState1.onTick = []() { utility.saveState(1); }; - toolsSaveState2.onTick = []() { utility.saveState(2); }; - toolsSaveState3.onTick = []() { utility.saveState(3); }; - toolsSaveState4.onTick = []() { utility.saveState(4); }; - toolsSaveState5.onTick = []() { utility.saveState(5); }; - - toolsLoadState1.onTick = []() { utility.loadState(1); }; - toolsLoadState2.onTick = []() { utility.loadState(2); }; - toolsLoadState3.onTick = []() { utility.loadState(3); }; - toolsLoadState4.onTick = []() { utility.loadState(4); }; - toolsLoadState5.onTick = []() { utility.loadState(5); }; - - toolsTraceCPU.onTick = []() { - GameBoy::cpu.trace = mainWindow.toolsTraceCPU.checked(); - }; - - helpAbout.onTick = []() { - MessageWindow::information(mainWindow, { - "bgameboy\n\n", - "Version: ", GameBoy::Info::Version, "\n", - "Author: byuu\n", - "Homepage: http://byuu.org/" - }); - }; -} diff --git a/bsnes/ui-gameboy/general/main-window.hpp b/bsnes/ui-gameboy/general/main-window.hpp deleted file mode 100755 index 4c1bd71d..00000000 --- a/bsnes/ui-gameboy/general/main-window.hpp +++ /dev/null @@ -1,36 +0,0 @@ -struct MainWindow : Window { - Menu system; - Item systemLoadCartridge; - Separator systemSeparator1; - Item systemPower; - - Menu settings; - CheckItem settingsVideoSync; - CheckItem settingsAudioSync; - - Menu tools; - Menu toolsSaveState; - Item toolsSaveState1; - Item toolsSaveState2; - Item toolsSaveState3; - Item toolsSaveState4; - Item toolsSaveState5; - Menu toolsLoadState; - Item toolsLoadState1; - Item toolsLoadState2; - Item toolsLoadState3; - Item toolsLoadState4; - Item toolsLoadState5; - Separator toolsSeparator1; - CheckItem toolsTraceCPU; - - Menu help; - Item helpAbout; - - FixedLayout layout; - Viewport viewport; - - void create(); -}; - -extern MainWindow mainWindow; diff --git a/bsnes/ui-gameboy/interface.cpp b/bsnes/ui-gameboy/interface.cpp deleted file mode 100755 index 77c13052..00000000 --- a/bsnes/ui-gameboy/interface.cpp +++ /dev/null @@ -1,61 +0,0 @@ -Interface interface; - -void Interface::video_refresh(const uint8_t *data) { - uint32_t *buffer; - unsigned pitch; - if(video.lock(buffer, pitch, 160, 144)) { - for(unsigned y = 0; y < 144; y++) { - uint32_t *line = buffer + y * (pitch >> 2); - const uint8_t *source = data + y * 160; - for(unsigned x = 0; x < 160; x++) { - uint32_t color = *source++; - *line++ = (color << 16) | (color << 8) | (color << 0); - } - } - video.unlock(); - video.refresh(); - } - - static unsigned frameCounter = 0; - static time_t timeCounter = time(0); - - frameCounter++; - time_t currentTime = time(0); - if(currentTime != timeCounter) { - timeCounter = currentTime; - mainWindow.setStatusText({ "FPS: ", frameCounter }); - frameCounter = 0; - } -} - -void Interface::audio_sample(int16_t center, int16_t lchannel, int16_t rchannel) { - dspaudio.sample(lchannel, rchannel); - while(dspaudio.pending()) { - signed lsample, rsample; - dspaudio.read(lsample, rsample); - audio.sample(lsample, rsample); - } -} - -void Interface::input_poll() { - input.poll(inputState); -} - -bool Interface::input_poll(unsigned id) { - switch((GameBoy::Input)id) { - case GameBoy::Input::Up: return inputState[keyboard(0)[Keyboard::Up]]; - case GameBoy::Input::Down: return inputState[keyboard(0)[Keyboard::Down]]; - case GameBoy::Input::Left: return inputState[keyboard(0)[Keyboard::Left]]; - case GameBoy::Input::Right: return inputState[keyboard(0)[Keyboard::Right]]; - case GameBoy::Input::B: return inputState[keyboard(0)[Keyboard::Z]]; - case GameBoy::Input::A: return inputState[keyboard(0)[Keyboard::X]]; - case GameBoy::Input::Select: return inputState[keyboard(0)[Keyboard::Apostrophe]]; - case GameBoy::Input::Start: return inputState[keyboard(0)[Keyboard::Return]]; - } - - return false; -} - -void Interface::message(const string &text) { - MessageWindow::information(mainWindow, text); -} diff --git a/bsnes/ui-gameboy/interface.hpp b/bsnes/ui-gameboy/interface.hpp deleted file mode 100755 index efeeca5f..00000000 --- a/bsnes/ui-gameboy/interface.hpp +++ /dev/null @@ -1,12 +0,0 @@ -struct Interface : public GameBoy::Interface { - int16_t inputState[Scancode::Limit]; - - void video_refresh(const uint8_t *data); - void audio_sample(int16_t center, int16_t left, int16_t right); - void input_poll(); - bool input_poll(unsigned id); - - void message(const string &text); -}; - -extern Interface interface; diff --git a/bsnes/ui-gameboy/main.cpp b/bsnes/ui-gameboy/main.cpp deleted file mode 100755 index 9a1f27b9..00000000 --- a/bsnes/ui-gameboy/main.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "base.hpp" -nall::DSP dspaudio; -Application application; - -#include "interface.cpp" - -#include "general/main-window.cpp" - -void Application::main(int argc, char **argv) { - quit = false; - - #if defined(PLATFORM_WIN) - proportionalFont = "Tahoma, 8"; - proportionalFontBold = "Tahoma, 8, Bold"; - monospaceFont = "Lucida Console, 8"; - #else - proportionalFont = "Sans, 8"; - proportionalFontBold = "Sans, 8, Bold"; - monospaceFont = "Liberation Mono, 8"; - #endif - - mainWindow.create(); - mainWindow.setVisible(); - OS::processEvents(); - - #if defined(PLATFORM_WIN) - video.driver("Direct3D"); - #else - video.driver("OpenGL"); - #endif - video.set(Video::Handle, (uintptr_t)mainWindow.viewport.handle()); - video.set(Video::Synchronize, false); - video.set(Video::Filter, (unsigned)0); - video.init(); - - #if defined(PLATFORM_WIN) - audio.driver("XAudio2"); - #else - audio.driver("ALSA"); - #endif - audio.set(Audio::Handle, (uintptr_t)mainWindow.viewport.handle()); - audio.set(Audio::Synchronize, true); - audio.set(Audio::Latency, 80u); - audio.set(Audio::Frequency, 44100u); - audio.init(); - - dspaudio.setPrecision(16); - dspaudio.setVolume(1.0); - dspaudio.setBalance(0.0); - dspaudio.setFrequency(4194304.0); - dspaudio.setResampler(DSP::Resampler::Average); - dspaudio.setResamplerFrequency(44100.0); - - #if defined(PLATFORM_WIN) - input.driver("RawInput"); - #else - input.driver("SDL"); - #endif - input.set(Input::Handle, (uintptr_t)mainWindow.viewport.handle()); - input.init(); - - GameBoy::system.init(&interface); - - while(quit == false) { - OS::processEvents(); - - if(GameBoy::cartridge.loaded()) { - do { - GameBoy::system.run(); - } while(GameBoy::scheduler.exit_reason() != GameBoy::Scheduler::ExitReason::FrameEvent); - } - } -} - -int main(int argc, char **argv) { - application.main(argc, argv); - return 0; -} diff --git a/bsnes/ui-gameboy/utility/utility.cpp b/bsnes/ui-gameboy/utility/utility.cpp deleted file mode 100755 index 183ffa73..00000000 --- a/bsnes/ui-gameboy/utility/utility.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "../base.hpp" -Utility utility; - -void Utility::loadCartridge(const char *filename) { - file fp; - if(fp.open(filename, file::mode::read)) { - unsigned size = fp.size(); - uint8_t *data = new uint8_t[size]; - fp.read(data, size); - fp.close(); - - cartridge.basename = nall::basename(filename); - - GameBoyCartridge info(data, size); - GameBoy::cartridge.load(info.xml, data, size); - delete[] data; - GameBoy::system.power(); - } -} - -bool Utility::saveState(unsigned slot) { - GameBoy::system.runtosave(); - serializer s = GameBoy::system.serialize(); - - file fp; - if(fp.open(string(cartridge.basename, "-", slot, ".bst"), file::mode::write)) { - fp.write(s.data(), s.size()); - fp.close(); - return true; - } - - return false; -} - -bool Utility::loadState(unsigned slot) { - file fp; - if(fp.open(string(cartridge.basename, "-", slot, ".bst"), file::mode::read)) { - unsigned size = fp.size(); - uint8_t *data = new uint8_t[size]; - fp.read(data, size); - fp.close(); - serializer s(data, size); - GameBoy::system.power(); - return GameBoy::system.unserialize(s); - } - - return false; -} diff --git a/bsnes/ui-gameboy/utility/utility.hpp b/bsnes/ui-gameboy/utility/utility.hpp deleted file mode 100755 index f8f39a31..00000000 --- a/bsnes/ui-gameboy/utility/utility.hpp +++ /dev/null @@ -1,11 +0,0 @@ -struct Utility { - struct Cartridge { - string basename; - } cartridge; - - void loadCartridge(const char *filename); - bool saveState(unsigned slot); - bool loadState(unsigned slot); -}; - -extern Utility utility; diff --git a/bsnes/ui/interface/nes.cpp b/bsnes/ui/interface/nes.cpp index 7f073a78..43d59add 100755 --- a/bsnes/ui/interface/nes.cpp +++ b/bsnes/ui/interface/nes.cpp @@ -26,17 +26,17 @@ void InterfaceNES::setCheatCodes(const lstring &list) { // -void InterfaceNES::video_refresh(const uint32_t *data) { +void InterfaceNES::video_refresh(const uint16_t *data) { interface->video_refresh(); uint32_t *output; unsigned outpitch; if(video.lock(output, outpitch, 256, 240)) { for(unsigned y = 0; y < 240; y++) { - const uint32_t *sp = data + y * 256; + const uint16_t *sp = data + y * 256; uint32_t *dp = output + y * (outpitch >> 2); for(unsigned x = 0; x < 256; x++) { - *dp++ = *sp++; + *dp++ = palette[*sp++]; } } @@ -70,3 +70,38 @@ int16_t InterfaceNES::input_poll(bool port, unsigned device, unsigned id) { return 0; } + +InterfaceNES::InterfaceNES() { + palette = { + 0x7c7c7c, 0x0000fc, 0x0000bc, 0x4428bc, + 0x940084, 0xa80020, 0xa81000, 0x881400, + 0x503000, 0x007800, 0x006800, 0x005800, + 0x004058, 0x000000, 0x000000, 0x000000, + 0xbcbcbc, 0x0078f8, 0x0058f8, 0x6844fc, + 0xd800cc, 0xe40058, 0xf83800, 0xe45c10, + 0xac7c00, 0x00b800, 0x00a800, 0x00a844, + 0x008888, 0x000000, 0x000000, 0x000000, + 0xf8f8f8, 0x3cbcfc, 0x6888fc, 0x9878f8, + 0xf878f8, 0xf85898, 0xf87858, 0xfca044, + 0xf8b800, 0xb8f818, 0x58d854, 0x58f898, + 0x00e8d8, 0x787878, 0x000000, 0x000000, + 0xfcfcfc, 0xa4e4fc, 0xb8b8b8, 0xd8d8f8, + 0xf8b8f8, 0xf8a4c0, 0xf0d0b0, 0xfce0a8, + 0xf8d878, 0xd8f878, 0xb8f8b8, 0xb8f8d8, + 0x00fcfc, 0xf8d8f8, 0x000000, 0x000000, + }; + + for(unsigned e = 1; e < 8; e++) { + static const double rfactor[8] = { 1.000, 1.239, 0.794, 1.019, 0.905, 1.023, 0.741, 0.750 }; + static const double gfactor[8] = { 1.000, 0.915, 1.086, 0.980, 1.026, 0.908, 0.987, 0.750 }; + static const double bfactor[8] = { 1.000, 0.743, 0.882, 0.653, 1.277, 0.979, 0.101, 0.750 }; + for(unsigned n = 0; n < 64; n++) { + unsigned c = palette[n]; + uint8_t r = c >> 16, g = c >> 8, b = c >> 0; + r = uclamp<8>((unsigned)(r * rfactor[e])); + g = uclamp<8>((unsigned)(g * gfactor[e])); + b = uclamp<8>((unsigned)(b * bfactor[e])); + palette[e * 64 + n] = (r << 16) | (g << 8) | (b << 0); + } + } +} diff --git a/bsnes/ui/interface/nes.hpp b/bsnes/ui/interface/nes.hpp index 72e1e980..e3db78c6 100755 --- a/bsnes/ui/interface/nes.hpp +++ b/bsnes/ui/interface/nes.hpp @@ -4,7 +4,12 @@ struct InterfaceNES : NES::Interface { void setCheatCodes(const lstring &list); - void video_refresh(const uint32_t *data); + void video_refresh(const uint16_t *data); void audio_sample(int16_t sample); int16_t input_poll(bool port, unsigned device, unsigned id); + + InterfaceNES(); + +private: + unsigned palette[512]; };