mirror of https://github.com/bsnes-emu/bsnes.git
Update to v077r05 release.
byuu says: Changelog: - fixed .nec and both .rtc file extensions (thanks krom) - randomized most S-PPU registers, should trip up some broken homebrew that does not initialize all registers - randomization is now seeded with time(0) rather than 'byuu' - SNES::interface.video_refresh() now always receives {256,512}x{240,480} - PPU/accuracy scanline 0 does not render the screen back color anymore, fixes strange coloring look on first scanline in PAL TV mode in non-overscan games - disabled hires blending in PPU/compatibility; all three cores act the same now
This commit is contained in:
parent
721e0b1762
commit
378b78dad7
|
@ -1,7 +1,7 @@
|
|||
include nall/Makefile
|
||||
snes := snes
|
||||
gameboy := gameboy
|
||||
profile := compatibility
|
||||
profile := accuracy
|
||||
ui := ui
|
||||
|
||||
# debugger
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
|
@ -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) {
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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<Canvas*>(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);
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Geometry pProgressBar::minimumGeometry() {
|
||||
return { 0, 0, 0, 25 };
|
||||
return { 0, 0, 0, 23 };
|
||||
}
|
||||
|
||||
void pProgressBar::setPosition(unsigned position) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue