diff --git a/bsnes/Makefile b/bsnes/Makefile index 0ae818e5..4af87086 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -1,7 +1,7 @@ include nall/Makefile snes := snes gameboy := gameboy -profile := compatibility +profile := accuracy ui := ui # debugger diff --git a/bsnes/nall/filemap.hpp b/bsnes/nall/filemap.hpp index 52acb2fa..5e8cc059 100755 --- a/bsnes/nall/filemap.hpp +++ b/bsnes/nall/filemap.hpp @@ -21,7 +21,7 @@ namespace nall { public: enum class mode : unsigned { read, write, readwrite, writeread }; - bool opened() const { return p_opened(); } + bool open() const { return p_open(); } bool open(const char *filename, mode mode_) { return p_open(filename, mode_); } void close() { return p_close(); } unsigned size() const { return p_size; } @@ -42,7 +42,7 @@ namespace nall { HANDLE p_filehandle, p_maphandle; - bool p_opened() const { + bool p_open() const { return p_handle; } @@ -128,7 +128,7 @@ namespace nall { int p_fd; - bool p_opened() const { + bool p_open() const { return p_handle; } diff --git a/bsnes/phoenix/gtk/widget/canvas.cpp b/bsnes/phoenix/gtk/widget/canvas.cpp new file mode 100755 index 00000000..2a0d479b --- /dev/null +++ b/bsnes/phoenix/gtk/widget/canvas.cpp @@ -0,0 +1,59 @@ +static void Canvas_expose(pCanvas *self) { + self->redraw(); +} + +uint32_t* pCanvas::buffer() { + return bufferRGB; +} + +void pCanvas::setGeometry(const Geometry &geometry) { + delete[] bufferRGB; + delete[] bufferBGR; + + bufferRGB = new uint32_t[geometry.width * geometry.height](); + bufferBGR = new uint32_t[geometry.width * geometry.height](); + + pWidget::setGeometry(geometry); + update(); +} + +void pCanvas::update() { + if(gtk_widget_get_realized(gtkWidget) == false) return; + GdkRectangle rect; + rect.x = 0; + rect.y = 0; + rect.width = gtkWidget->allocation.width; + rect.height = gtkWidget->allocation.height; + gdk_window_invalidate_rect(gtkWidget->window, &rect, true); +} + +void pCanvas::constructor() { + bufferRGB = new uint32_t[256 * 256](); + bufferBGR = new uint32_t[256 * 256](); + + gtkWidget = gtk_drawing_area_new(); + GdkColor color; + color.pixel = color.red = color.green = color.blue = 0; + gtk_widget_modify_bg(gtkWidget, GTK_STATE_NORMAL, &color); + gtk_widget_set_double_buffered(gtkWidget, false); + gtk_widget_add_events(gtkWidget, GDK_EXPOSURE_MASK); + g_signal_connect_swapped(G_OBJECT(gtkWidget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this); +} + +void pCanvas::redraw() { + if(gtk_widget_get_realized(gtkWidget) == false) return; + uint32_t *rgb = bufferRGB, *bgr = bufferBGR; + for(unsigned y = gtkWidget->allocation.height; y; y--) { + for(unsigned x = gtkWidget->allocation.width; x; x--) { + uint32_t pixel = *rgb++; + *bgr++ = ((pixel << 16) & 0xff0000) | (pixel & 0x00ff00) | ((pixel >> 16) & 0x0000ff); + } + } + + gdk_draw_rgb_32_image( + gtkWidget->window, + gtkWidget->style->fg_gc[GTK_WIDGET_STATE(gtkWidget)], + 0, 0, gtkWidget->allocation.width, gtkWidget->allocation.height, + GDK_RGB_DITHER_NONE, (guchar*)bufferBGR, sizeof(uint32_t) * gtkWidget->allocation.width + ); +} diff --git a/bsnes/phoenix/qt/widget/canvas.cpp b/bsnes/phoenix/qt/widget/canvas.cpp new file mode 100755 index 00000000..05c661bc --- /dev/null +++ b/bsnes/phoenix/qt/widget/canvas.cpp @@ -0,0 +1,27 @@ +uint32_t* pCanvas::buffer() { + return (uint32_t*)qtImage->bits(); +} + +void pCanvas::setGeometry(const Geometry &geometry) { + qtImage = new QImage(geometry.width, geometry.height, QImage::Format_RGB32); + qtImage->fill(0); + update(); + pWidget::setGeometry(geometry); +} + +void pCanvas::update() { + qtCanvas->update(); +} + +void pCanvas::constructor() { + qtWidget = qtCanvas = new QtCanvas(*this); + qtImage = new QImage(256, 256, QImage::Format_RGB32); +} + +void pCanvas::QtCanvas::paintEvent(QPaintEvent *event) { + QPainter painter(self.qtCanvas); + painter.drawImage(0, 0, *self.qtImage); +} + +pCanvas::QtCanvas::QtCanvas(pCanvas &self) : self(self) { +} diff --git a/bsnes/phoenix/windows/widget/button.cpp b/bsnes/phoenix/windows/widget/button.cpp index b9615dc0..46696aa3 100755 --- a/bsnes/phoenix/windows/widget/button.cpp +++ b/bsnes/phoenix/windows/widget/button.cpp @@ -1,7 +1,7 @@ Geometry pButton::minimumGeometry() { Font &font = this->font(); Geometry geometry = font.geometry(button.state.text); - return { 0, 0, geometry.width + 20, font.p.height() + 12 }; + return { 0, 0, geometry.width + 20, font.p.height() + 10 }; } void pButton::setText(const string &text) { diff --git a/bsnes/phoenix/windows/widget/canvas.cpp b/bsnes/phoenix/windows/widget/canvas.cpp new file mode 100755 index 00000000..e5618666 --- /dev/null +++ b/bsnes/phoenix/windows/widget/canvas.cpp @@ -0,0 +1,54 @@ +static LRESULT CALLBACK Canvas_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + if(msg == WM_PAINT) { + Object *object = (Object*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + if(object && dynamic_cast(object)) { + Canvas &canvas = (Canvas&)*object; + canvas.update(); + } + } + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +uint32_t* pCanvas::buffer() { + return bufferRGB; +} + +void pCanvas::setGeometry(const Geometry &geometry) { + delete[] bufferRGB; + bufferRGB = new uint32_t[geometry.width * geometry.height](); + pWidget::setGeometry(geometry); + update(); +} + +void pCanvas::update() { + RECT rc; + GetClientRect(hwnd, &rc); + unsigned width = rc.right, height = rc.bottom; + + BITMAPINFO bmi; + memset(&bmi, 0, sizeof(BITMAPINFO)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biWidth = width; + bmi.bmiHeader.biHeight = -height; //GDI stores bitmaps upside now; negative height flips bitmap + bmi.bmiHeader.biSizeImage = sizeof(uint32_t) * width * height; + + PAINTSTRUCT ps; + BeginPaint(hwnd, &ps); + SetDIBitsToDevice(ps.hdc, 0, 0, width, height, 0, 0, 0, height, (void*)bufferRGB, &bmi, DIB_RGB_COLORS); + EndPaint(hwnd, &ps); + InvalidateRect(hwnd, 0, false); +} + +void pCanvas::constructor() { + bufferRGB = new uint32_t[256 * 256](); + setParent(Window::None); +} + +void pCanvas::setParent(Window &parent) { + if(hwnd) DestroyWindow(hwnd); + hwnd = CreateWindow(L"phoenix_canvas", L"", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&canvas); +} diff --git a/bsnes/phoenix/windows/widget/label.cpp b/bsnes/phoenix/windows/widget/label.cpp index 1c13b70c..dc40ed61 100755 --- a/bsnes/phoenix/windows/widget/label.cpp +++ b/bsnes/phoenix/windows/widget/label.cpp @@ -1,7 +1,7 @@ Geometry pLabel::minimumGeometry() { Font &font = this->font(); Geometry geometry = font.geometry(label.state.text); - return { 0, 0, geometry.width, font.p.height() }; + return { 0, 0, geometry.width, geometry.height }; } void pLabel::setText(const string &text) { diff --git a/bsnes/phoenix/windows/widget/line-edit.cpp b/bsnes/phoenix/windows/widget/line-edit.cpp index ded999ab..de54470d 100755 --- a/bsnes/phoenix/windows/widget/line-edit.cpp +++ b/bsnes/phoenix/windows/widget/line-edit.cpp @@ -1,7 +1,7 @@ Geometry pLineEdit::minimumGeometry() { Font &font = this->font(); Geometry geometry = font.geometry(lineEdit.state.text); - return { 0, 0, geometry.width + 12, font.p.height() + 8 }; + return { 0, 0, geometry.width + 12, font.p.height() + 10 }; } void pLineEdit::setEditable(bool editable) { diff --git a/bsnes/phoenix/windows/widget/progress-bar.cpp b/bsnes/phoenix/windows/widget/progress-bar.cpp index 495cb440..46e65d18 100755 --- a/bsnes/phoenix/windows/widget/progress-bar.cpp +++ b/bsnes/phoenix/windows/widget/progress-bar.cpp @@ -1,5 +1,5 @@ Geometry pProgressBar::minimumGeometry() { - return { 0, 0, 0, 25 }; + return { 0, 0, 0, 23 }; } void pProgressBar::setPosition(unsigned position) { diff --git a/bsnes/snes/alt/ppu-compatibility/render/line.cpp b/bsnes/snes/alt/ppu-compatibility/render/line.cpp index 5a0ff90c..d63884a9 100755 --- a/bsnes/snes/alt/ppu-compatibility/render/line.cpp +++ b/bsnes/snes/alt/ppu-compatibility/render/line.cpp @@ -96,13 +96,16 @@ inline void PPU::render_line_output() { } } else { for(unsigned x = 0, prev = 0; x < 256; x++) { + //blending is disabled below, as this should be done via video filtering + //blending code is left for reference purposes + curr = luma[get_pixel_swap(x)]; - *ptr++ = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1; - prev = curr; + *ptr++ = curr; //(prev + curr - ((prev ^ curr) & 0x0421)) >> 1; + //prev = curr; curr = luma[get_pixel_normal(x)]; - *ptr++ = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1; - prev = curr; + *ptr++ = curr; //(prev + curr - ((prev ^ curr) & 0x0421)) >> 1; + //prev = curr; } } } diff --git a/bsnes/snes/chip/necdsp/necdsp.cpp b/bsnes/snes/chip/necdsp/necdsp.cpp index 13907684..0a07d1dc 100755 --- a/bsnes/snes/chip/necdsp/necdsp.cpp +++ b/bsnes/snes/chip/necdsp/necdsp.cpp @@ -247,7 +247,7 @@ void NECDSP::init() { void NECDSP::load() { if(revision == Revision::uPD96050) { - cartridge.nvram.append({ "nec", (uint8_t*)dataRAM, 4096 }); + cartridge.nvram.append({ ".nec", (uint8_t*)dataRAM, 4096 }); } } diff --git a/bsnes/snes/chip/spc7110/spc7110.cpp b/bsnes/snes/chip/spc7110/spc7110.cpp index 1fc061ef..835ddbb6 100755 --- a/bsnes/snes/chip/spc7110/spc7110.cpp +++ b/bsnes/snes/chip/spc7110/spc7110.cpp @@ -15,7 +15,7 @@ void SPC7110::init() { void SPC7110::load() { for(unsigned n = 0; n < 20; n++) rtc[n] = 0xff; - if(cartridge.has_spc7110rtc()) cartridge.nvram.append({ "rtc", rtc, 20 }); + if(cartridge.has_spc7110rtc()) cartridge.nvram.append({ ".rtc", rtc, 20 }); } void SPC7110::unload() { diff --git a/bsnes/snes/chip/srtc/srtc.cpp b/bsnes/snes/chip/srtc/srtc.cpp index 39496d15..1dd8f86e 100755 --- a/bsnes/snes/chip/srtc/srtc.cpp +++ b/bsnes/snes/chip/srtc/srtc.cpp @@ -14,7 +14,7 @@ void SRTC::init() { void SRTC::load() { for(unsigned n = 0; n < 20; n++) rtc[n] = 0xff; - cartridge.nvram.append({ "rtc", rtc, 20 }); + cartridge.nvram.append({ ".rtc", rtc, 20 }); } void SRTC::unload() { diff --git a/bsnes/snes/ppu/background/background.cpp b/bsnes/snes/ppu/background/background.cpp index 77f13bb3..9587d70d 100755 --- a/bsnes/snes/ppu/background/background.cpp +++ b/bsnes/snes/ppu/background/background.cpp @@ -211,18 +211,18 @@ unsigned PPU::Background::get_tile_color() { } void PPU::Background::reset() { - regs.tiledata_addr = 0; - regs.screen_addr = 0; - regs.screen_size = 0; - regs.mosaic = 0; - regs.tile_size = 0; + regs.tiledata_addr = random(0x0000); + regs.screen_addr = random(0x0000); + regs.screen_size = random(0); + regs.mosaic = random(0); + regs.tile_size = random(0); regs.mode = 0; regs.priority0 = 0; regs.priority1 = 0; - regs.main_enable = 0; - regs.sub_enable = 0; - regs.hoffset = 0; - regs.voffset = 0; + regs.main_enable = random(0); + regs.sub_enable = random(0); + regs.hoffset = random(0x0000); + regs.voffset = random(0x0000); output.main.palette = 0; output.main.priority = 0; diff --git a/bsnes/snes/ppu/background/background.hpp b/bsnes/snes/ppu/background/background.hpp index 8e0c4a70..5c43de75 100755 --- a/bsnes/snes/ppu/background/background.hpp +++ b/bsnes/snes/ppu/background/background.hpp @@ -8,10 +8,10 @@ class Background { struct Screen { enum { Main, Sub }; }; struct Regs { - unsigned tiledata_addr; - unsigned screen_addr; - unsigned screen_size; - unsigned mosaic; + uint16 tiledata_addr; + uint16 screen_addr; + uint2 screen_size; + uint4 mosaic; bool tile_size; unsigned mode; @@ -21,8 +21,8 @@ class Background { bool main_enable; bool sub_enable; - unsigned hoffset; - unsigned voffset; + uint16 hoffset; + uint16 voffset; } regs; struct Output { diff --git a/bsnes/snes/ppu/mmio/mmio.cpp b/bsnes/snes/ppu/mmio/mmio.cpp index 8119ef00..302f74f8 100755 --- a/bsnes/snes/ppu/mmio/mmio.cpp +++ b/bsnes/snes/ppu/mmio/mmio.cpp @@ -681,14 +681,14 @@ uint8 PPU::mmio_r213f() { } void PPU::mmio_reset() { - regs.ppu1_mdr = 0xff; - regs.ppu2_mdr = 0xff; + regs.ppu1_mdr = random(0xff); + regs.ppu2_mdr = random(0xff); - regs.vram_readbuffer = 0x0000; - regs.oam_latchdata = 0x00; - regs.cgram_latchdata = 0x00; - regs.bgofs_latchdata = 0x00; - regs.mode7_latchdata = 0x00; + regs.vram_readbuffer = random(0x0000); + regs.oam_latchdata = random(0x00); + regs.cgram_latchdata = random(0x00); + regs.bgofs_latchdata = random(0x00); + regs.mode7_latchdata = random(0x00); regs.counters_latched = false; regs.latch_hcounter = 0; regs.latch_vcounter = 0; @@ -702,58 +702,58 @@ void PPU::mmio_reset() { //$2102 OAMADDL //$2103 OAMADDH - regs.oam_baseaddr = 0x0000; - regs.oam_addr = 0x0000; - regs.oam_priority = false; + regs.oam_baseaddr = random(0x0000); + regs.oam_addr = random(0x0000); + regs.oam_priority = random(false); //$2105 BGMODE regs.bg3_priority = false; regs.bgmode = 0; //$210d BG1HOFS - regs.mode7_hoffset = 0x0000; + regs.mode7_hoffset = random(0x0000); //$210e BG1VOFS - regs.mode7_voffset = 0x0000; + regs.mode7_voffset = random(0x0000); //$2115 VMAIN - regs.vram_incmode = 1; - regs.vram_mapping = 0; + regs.vram_incmode = random(1); + regs.vram_mapping = random(0); regs.vram_incsize = 1; //$2116 VMADDL //$2117 VMADDH - regs.vram_addr = 0x0000; + regs.vram_addr = random(0x0000); //$211a M7SEL - regs.mode7_repeat = 0; - regs.mode7_vflip = false; - regs.mode7_hflip = false; + regs.mode7_repeat = random(0); + regs.mode7_vflip = random(false); + regs.mode7_hflip = random(false); //$211b M7A - regs.m7a = 0x0000; + regs.m7a = random(0x0000); //$211c M7B - regs.m7b = 0x0000; + regs.m7b = random(0x0000); //$211d M7C - regs.m7c = 0x0000; + regs.m7c = random(0x0000); //$211e M7D - regs.m7d = 0x0000; + regs.m7d = random(0x0000); //$211f M7X - regs.m7x = 0x0000; + regs.m7x = random(0x0000); //$2120 M7Y - regs.m7y = 0x0000; + regs.m7y = random(0x0000); //$2121 CGADD - regs.cgram_addr = 0x0000; + regs.cgram_addr = random(0x0000); //$2133 SETINI - regs.mode7_extbg = false; - regs.pseudo_hires = false; + regs.mode7_extbg = random(false); + regs.pseudo_hires = random(false); regs.overscan = false; regs.interlace = false; diff --git a/bsnes/snes/ppu/mmio/mmio.hpp b/bsnes/snes/ppu/mmio/mmio.hpp index 7868c42f..0c105624 100755 --- a/bsnes/snes/ppu/mmio/mmio.hpp +++ b/bsnes/snes/ppu/mmio/mmio.hpp @@ -22,7 +22,7 @@ struct { //$2100 INIDISP bool display_disable; - unsigned display_brightness; + uint4 display_brightness; //$2102 OAMADDL //$2103 OAMADDH @@ -42,7 +42,7 @@ struct { //$2115 VMAIN bool vram_incmode; - uint8 vram_mapping; + uint2 vram_mapping; uint8 vram_incsize; //$2116 VMADDL @@ -50,7 +50,7 @@ struct { uint16 vram_addr; //$211a M7SEL - uint8 mode7_repeat; + uint2 mode7_repeat; bool mode7_vflip; bool mode7_hflip; diff --git a/bsnes/snes/ppu/screen/screen.cpp b/bsnes/snes/ppu/screen/screen.cpp index ef21ca99..8a9f3589 100755 --- a/bsnes/snes/ppu/screen/screen.cpp +++ b/bsnes/snes/ppu/screen/screen.cpp @@ -6,6 +6,8 @@ void PPU::Screen::scanline() { } void PPU::Screen::run() { + if(ppu.vcounter() == 0) return; + uint16 color; if(self.regs.pseudo_hires == false && self.regs.bgmode != 5 && self.regs.bgmode != 6) { color = get_pixel(0); @@ -186,19 +188,19 @@ uint16 PPU::Screen::get_direct_color(unsigned palette, unsigned tile) { } void PPU::Screen::reset() { - regs.addsub_mode = 0; - regs.direct_color = 0; - regs.color_mode = 0; - regs.color_halve = 0; - regs.bg1_color_enable = 0; - regs.bg2_color_enable = 0; - regs.bg3_color_enable = 0; - regs.bg4_color_enable = 0; - regs.oam_color_enable = 0; - regs.back_color_enable = 0; - regs.color_r = 0; - regs.color_g = 0; - regs.color_b = 0; + regs.addsub_mode = random(false); + regs.direct_color = random(false); + regs.color_mode = random(false); + regs.color_halve = random(false); + regs.bg1_color_enable = random(false); + regs.bg2_color_enable = random(false); + regs.bg3_color_enable = random(false); + regs.bg4_color_enable = random(false); + regs.oam_color_enable = random(false); + regs.back_color_enable = random(false); + regs.color_r = random(0); + regs.color_g = random(0); + regs.color_b = random(0); } PPU::Screen::Screen(PPU &self) : self(self) { diff --git a/bsnes/snes/ppu/screen/screen.hpp b/bsnes/snes/ppu/screen/screen.hpp index 1de619fe..4c3a2617 100755 --- a/bsnes/snes/ppu/screen/screen.hpp +++ b/bsnes/snes/ppu/screen/screen.hpp @@ -14,9 +14,9 @@ class Screen { bool oam_color_enable; bool back_color_enable; - uint8 color_b; - uint8 color_g; - uint8 color_r; + uint5 color_b; + uint5 color_g; + uint5 color_r; } regs; void scanline(); diff --git a/bsnes/snes/ppu/sprite/list.cpp b/bsnes/snes/ppu/sprite/list.cpp index 4705663a..dda35883 100755 --- a/bsnes/snes/ppu/sprite/list.cpp +++ b/bsnes/snes/ppu/sprite/list.cpp @@ -32,6 +32,10 @@ void PPU::Sprite::update(unsigned addr, uint8 data) { } } +void PPU::Sprite::synchronize() { + for(unsigned n = 0; n < 544; n++) update(n, ppu.oam[n]); +} + unsigned PPU::Sprite::SpriteItem::width() const { if(size == 0) { static unsigned width[] = { 8, 8, 8, 16, 16, 32, 16, 16 }; diff --git a/bsnes/snes/ppu/sprite/sprite.cpp b/bsnes/snes/ppu/sprite/sprite.cpp index 93a18884..5bc60b3e 100755 --- a/bsnes/snes/ppu/sprite/sprite.cpp +++ b/bsnes/snes/ppu/sprite/sprite.cpp @@ -171,6 +171,7 @@ void PPU::Sprite::reset() { list[i].palette = 0; list[i].size = 0; } + synchronize(); t.x = 0; t.y = 0; @@ -193,13 +194,13 @@ void PPU::Sprite::reset() { } } - regs.main_enable = 0; - regs.sub_enable = 0; - regs.interlace = 0; + regs.main_enable = random(false); + regs.sub_enable = random(false); + regs.interlace = random(false); - regs.base_size = 0; - regs.nameselect = 0; - regs.tiledata_addr = 0; + regs.base_size = random(0); + regs.nameselect = random(0); + regs.tiledata_addr = random(0x0000); regs.first_sprite = 0; regs.priority0 = 0; @@ -207,8 +208,8 @@ void PPU::Sprite::reset() { regs.priority2 = 0; regs.priority3 = 0; - regs.time_over = 0; - regs.range_over = 0; + regs.time_over = false; + regs.range_over = false; output.main.palette = 0; output.main.priority = 0; diff --git a/bsnes/snes/ppu/sprite/sprite.hpp b/bsnes/snes/ppu/sprite/sprite.hpp index b045b318..641ac13c 100755 --- a/bsnes/snes/ppu/sprite/sprite.hpp +++ b/bsnes/snes/ppu/sprite/sprite.hpp @@ -38,8 +38,8 @@ class Sprite { bool sub_enable; bool interlace; - uint8 base_size; - uint8 nameselect; + uint3 base_size; + uint2 nameselect; uint16 tiledata_addr; uint8 first_sprite; @@ -61,6 +61,7 @@ class Sprite { //list.cpp void update(unsigned addr, uint8 data); + void synchronize(); //sprite.cpp void address_reset(); diff --git a/bsnes/snes/ppu/window/window.cpp b/bsnes/snes/ppu/window/window.cpp index 3b7f9155..dec05876 100755 --- a/bsnes/snes/ppu/window/window.cpp +++ b/bsnes/snes/ppu/window/window.cpp @@ -108,52 +108,52 @@ void PPU::Window::test( } void PPU::Window::reset() { - regs.bg1_one_enable = false; - regs.bg1_one_invert = false; - regs.bg1_two_enable = false; - regs.bg1_two_invert = false; - regs.bg2_one_enable = false; - regs.bg2_one_invert = false; - regs.bg2_two_enable = false; - regs.bg2_two_invert = false; - regs.bg3_one_enable = false; - regs.bg3_one_invert = false; - regs.bg3_two_enable = false; - regs.bg3_two_invert = false; - regs.bg4_one_enable = false; - regs.bg4_one_invert = false; - regs.bg4_two_enable = false; - regs.bg4_two_invert = false; - regs.oam_one_enable = false; - regs.oam_one_invert = false; - regs.oam_two_enable = false; - regs.oam_two_invert = false; - regs.col_one_enable = false; - regs.col_one_invert = false; - regs.col_two_enable = false; - regs.col_two_invert = false; - regs.one_left = 0; - regs.one_right = 0; - regs.two_left = 0; - regs.two_right = 0; - regs.bg1_mask = 0; - regs.bg2_mask = 0; - regs.bg3_mask = 0; - regs.bg4_mask = 0; - regs.oam_mask = 0; - regs.col_mask = 0; - regs.bg1_main_enable = 0; - regs.bg1_sub_enable = 0; - regs.bg2_main_enable = 0; - regs.bg2_sub_enable = 0; - regs.bg3_main_enable = 0; - regs.bg3_sub_enable = 0; - regs.bg4_main_enable = 0; - regs.bg4_sub_enable = 0; - regs.oam_main_enable = 0; - regs.oam_sub_enable = 0; - regs.col_main_mask = 0; - regs.col_sub_mask = 0; + regs.bg1_one_enable = random(false); + regs.bg1_one_invert = random(false); + regs.bg1_two_enable = random(false); + regs.bg1_two_invert = random(false); + regs.bg2_one_enable = random(false); + regs.bg2_one_invert = random(false); + regs.bg2_two_enable = random(false); + regs.bg2_two_invert = random(false); + regs.bg3_one_enable = random(false); + regs.bg3_one_invert = random(false); + regs.bg3_two_enable = random(false); + regs.bg3_two_invert = random(false); + regs.bg4_one_enable = random(false); + regs.bg4_one_invert = random(false); + regs.bg4_two_enable = random(false); + regs.bg4_two_invert = random(false); + regs.oam_one_enable = random(false); + regs.oam_one_invert = random(false); + regs.oam_two_enable = random(false); + regs.oam_two_invert = random(false); + regs.col_one_enable = random(false); + regs.col_one_invert = random(false); + regs.col_two_enable = random(false); + regs.col_two_invert = random(false); + regs.one_left = random(0x00); + regs.one_right = random(0x00); + regs.two_left = random(0x00); + regs.two_right = random(0x00); + regs.bg1_mask = random(0); + regs.bg2_mask = random(0); + regs.bg3_mask = random(0); + regs.bg4_mask = random(0); + regs.oam_mask = random(0); + regs.col_mask = random(0); + regs.bg1_main_enable = random(false); + regs.bg1_sub_enable = random(false); + regs.bg2_main_enable = random(false); + regs.bg2_sub_enable = random(false); + regs.bg3_main_enable = random(false); + regs.bg3_sub_enable = random(false); + regs.bg4_main_enable = random(false); + regs.bg4_sub_enable = random(false); + regs.oam_main_enable = random(false); + regs.oam_sub_enable = random(false); + regs.col_main_mask = random(0); + regs.col_sub_mask = random(0); output.main.color_enable = 0; output.sub.color_enable = 0; diff --git a/bsnes/snes/ppu/window/window.hpp b/bsnes/snes/ppu/window/window.hpp index 498a2a26..a4bad10e 100755 --- a/bsnes/snes/ppu/window/window.hpp +++ b/bsnes/snes/ppu/window/window.hpp @@ -35,12 +35,12 @@ class Window { uint8 two_left; uint8 two_right; - uint8 bg1_mask; - uint8 bg2_mask; - uint8 bg3_mask; - uint8 bg4_mask; - uint8 oam_mask; - uint8 col_mask; + uint2 bg1_mask; + uint2 bg2_mask; + uint2 bg3_mask; + uint2 bg4_mask; + uint2 oam_mask; + uint2 col_mask; bool bg1_main_enable; bool bg1_sub_enable; @@ -53,8 +53,8 @@ class Window { bool oam_main_enable; bool oam_sub_enable; - uint8 col_main_mask; - uint8 col_sub_mask; + uint2 col_main_mask; + uint2 col_sub_mask; } regs; struct Output { diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 383acd82..1f9a0b19 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "077.04"; + static const char Version[] = "077.05"; static const unsigned SerializerVersion = 19; } } diff --git a/bsnes/snes/system/system.cpp b/bsnes/snes/system/system.cpp index e22e5514..56316e55 100755 --- a/bsnes/snes/system/system.cpp +++ b/bsnes/snes/system/system.cpp @@ -148,7 +148,7 @@ void System::unload() { } void System::power() { - random.seed(0x62797575); + random.seed((unsigned)time(0)); region = config.region; expansion = config.expansion_port; diff --git a/bsnes/snes/video/video.cpp b/bsnes/snes/video/video.cpp index 347fde65..1fd6879f 100755 --- a/bsnes/snes/video/video.cpp +++ b/bsnes/snes/video/video.cpp @@ -55,11 +55,8 @@ void Video::update() { uint16_t *data = (uint16_t*)ppu.output; if(ppu.interlace() && ppu.field()) data += 512; - unsigned width = 256; - unsigned height = !ppu.overscan() ? 224 : 239; if(frame_hires) { - width <<= 1; //normalize line widths for(unsigned y = 0; y < 240; y++) { if(line_width[y] == 512) continue; @@ -70,11 +67,7 @@ void Video::update() { } } - if(frame_interlace) { - height <<= 1; - } - - system.interface->video_refresh(ppu.output + 1024, width, height); + system.interface->video_refresh(ppu.output, 256 << frame_hires, 240 << frame_interlace); frame_hires = false; frame_interlace = false; diff --git a/bsnes/ui/cartridge/cartridge.cpp b/bsnes/ui/cartridge/cartridge.cpp index 9d117a03..13990302 100755 --- a/bsnes/ui/cartridge/cartridge.cpp +++ b/bsnes/ui/cartridge/cartridge.cpp @@ -111,7 +111,7 @@ bool Cartridge::loadCartridge(SNES::MappedRAM &memory, string &XML, const char * fp.close(); filemap patch(string(nall::basename(filename), ".ups"), filemap::mode::read); - if(patch.opened()) { + if(patch.open()) { unsigned targetSize; ups patcher; if(patcher.apply(patch.data(), patch.size(), data, size, (uint8_t*)0, targetSize) == ups::result::target_too_small) { diff --git a/bsnes/ui/input/hotkeys.hpp b/bsnes/ui/input/hotkeys.hpp new file mode 100755 index 00000000..269e19ad --- /dev/null +++ b/bsnes/ui/input/hotkeys.hpp @@ -0,0 +1,16 @@ +struct HotkeysGeneral : Controller { + DigitalInput stateSave; + DigitalInput stateLoad; + DigitalInput stateDecrement; + DigitalInput stateIncrement; + DigitalInput fullscreenToggle; + DigitalInput mouseCaptureToggle; + DigitalInput pauseToggle; + DigitalInput fastForward; + DigitalInput power; + DigitalInput reset; + void create(const char *deviceName, const char *configName); +} hotkeysGeneral; + +struct Hotkeys : ControllerPort { +} hotkeys; diff --git a/bsnes/ui/interface.cpp b/bsnes/ui/interface.cpp index 2faaaf5c..15d14c92 100755 --- a/bsnes/ui/interface.cpp +++ b/bsnes/ui/interface.cpp @@ -79,30 +79,30 @@ void Filter::render(uint32_t *output, unsigned outpitch, const uint16_t *input, } void Interface::video_refresh(const uint16_t *data, unsigned width, unsigned height) { - bool interlace = (height >= 240); - bool overscan = (height == 239 || height == 478); + bool interlace = SNES::ppu.interlace(); + bool overscan = SNES::ppu.overscan(); unsigned inpitch = interlace ? 1024 : 2048; - uint32_t *buffer; - unsigned outpitch; + //always ignore blank scanline 0 + data += 1024; + height -= 1 << interlace; - if(config.video.region == 0 && (height == 239 || height == 478)) { - //NTSC overscan compensation (center image, remove 15 lines) - data += 7 * 1024; - if(height == 239) height = 224; - if(height == 478) height = 448; + if(config.video.region == 0) { + //NTSC overscan compensation + height -= 15 << interlace; + if(overscan == true ) data += 7 * 1024; } - if(config.video.region == 1 && (height == 224 || height == 448)) { - //PAL underscan compensation (center image, add 15 lines) - data -= 7 * 1024; - if(height == 224) height = 239; - if(height == 448) height = 478; + if(config.video.region == 1) { + //PAL underscan compensation + if(overscan == false) data -= 7 * 1024; } unsigned outwidth = width, outheight = height; filter.size(outwidth, outheight); + uint32_t *buffer; + unsigned outpitch; if(video.lock(buffer, outpitch, outwidth, outheight)) { filter.render(buffer, outpitch, data, inpitch, width, height); video.unlock();