diff --git a/higan/GNUmakefile b/higan/GNUmakefile index 50843699..92d2b92c 100644 --- a/higan/GNUmakefile +++ b/higan/GNUmakefile @@ -1,9 +1,10 @@ build := performance +openmp := true include ../nall/GNUmakefile binary := application -target := higan -profile := accurate +target := bsnes +profile := fast objects := libco emulator audio video resource flags += -I. -I.. @@ -24,8 +25,6 @@ else ifeq ($(platform),macos) link += -dynamiclib endif else ifneq ($(filter $(platform),linux bsd),) - flags += -fopenmp - link += -fopenmp ifeq ($(binary),application) flags += -march=native link += -Wl,-export-dynamic diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 5b4f372d..f0388436 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "106.32"; + static const string Version = "106.33"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org/"; diff --git a/higan/sfc/dsp/dsp.cpp b/higan/sfc/dsp/dsp.cpp index 215ed206..96c67713 100644 --- a/higan/sfc/dsp/dsp.cpp +++ b/higan/sfc/dsp/dsp.cpp @@ -192,8 +192,18 @@ auto DSP::main() -> void { } auto DSP::tick() -> void { + #if defined(PROFILE_ACCURATE) step(3 * 8); synchronize(smp); + #endif +} + +auto DSP::sample(int16 left, int16 right) -> void { + stream->sample(left / 32768.0, right / 32768.0); + #if defined(PROFILE_FAST) + step(32 * 3 * 8); + synchronize(smp); + #endif } /* register interface for S-SMP $00f2,$00f3 */ diff --git a/higan/sfc/dsp/dsp.hpp b/higan/sfc/dsp/dsp.hpp index ec3d2350..1c827f14 100644 --- a/higan/sfc/dsp/dsp.hpp +++ b/higan/sfc/dsp/dsp.hpp @@ -171,6 +171,7 @@ private: //dsp.cpp static auto Enter() -> void; auto tick() -> void; + auto sample(int16 left, int16 right) -> void; }; extern DSP dsp; diff --git a/higan/sfc/dsp/echo.cpp b/higan/sfc/dsp/echo.cpp index 7a1805e0..fb84c0dc 100644 --- a/higan/sfc/dsp/echo.cpp +++ b/higan/sfc/dsp/echo.cpp @@ -103,7 +103,7 @@ auto DSP::echo27() -> void { } //output sample to DAC - stream->sample(outl / 32768.0, outr / 32768.0); + sample(outl, outr); } auto DSP::echo28() -> void { diff --git a/higan/sfc/ppu-fast/background.cpp b/higan/sfc/ppu-fast/background.cpp index 25908e63..46bd08c0 100644 --- a/higan/sfc/ppu-fast/background.cpp +++ b/higan/sfc/ppu-fast/background.cpp @@ -12,10 +12,10 @@ auto PPU::Line::renderBackground(PPU::IO::Background& self, uint source) -> void bool hires = io.bgMode == 5 || io.bgMode == 6; bool offsetPerTileMode = io.bgMode == 2 || io.bgMode == 4 || io.bgMode == 6; bool directColorMode = io.col.directColor && source == Source::BG1 && (io.bgMode == 3 || io.bgMode == 4); - int width = !hires ? 256 : 512; + int width = 256 << hires; - uint tileHeight = self.tileSize ? 4 : 3; - uint tileWidth = hires ? 4 : tileHeight; + uint tileHeight = 3 + self.tileSize; + uint tileWidth = !hires ? tileHeight : 4; uint tileMask = 0x0fff >> self.tileMode; uint tiledataIndex = self.tiledataAddress >> 3 + self.tileMode; @@ -24,13 +24,13 @@ auto PPU::Line::renderBackground(PPU::IO::Background& self, uint source) -> void uint hscroll = self.hoffset; uint vscroll = self.voffset; - uint hmask = (width << (tileHeight == 4) << self.screenSize.bit(0)) - 1; - uint vmask = (width << (tileHeight == 4) << self.screenSize.bit(1)) - 1; + uint hmask = (width << self.tileSize << self.screenSize.bit(0)) - 1; + uint vmask = (width << self.tileSize << self.screenSize.bit(1)) - 1; - uint y = this->y; //todo: vmosaic + uint y = this->y - this->y % (1 + io.mosaicSize); if(hires) { hscroll <<= 1; - if(io.interlace) y = y << 1 | ppu.PPUcounter::field(); + if(io.interlace) y = y << 1 | ppu.field(); } uint mosaicCounter = 1; @@ -43,25 +43,25 @@ auto PPU::Line::renderBackground(PPU::IO::Background& self, uint source) -> void uint hoffset = x + hscroll; uint voffset = y + vscroll; if(offsetPerTileMode) { - uint validBit = source == Source::BG1 ? 0x2000 : source == Source::BG2 ? 0x4000 : 0x0000; + uint validBit = 0x2000 << source; uint offsetX = x + (hscroll & 7); if(offsetX >= 8) { //first column is exempt - uint hvalue = getTile(io.bg3, (offsetX - 8) + (io.bg3.hoffset & ~7), io.bg3.voffset + 0); + uint hlookup = getTile(io.bg3, (offsetX - 8) + (io.bg3.hoffset & ~7), io.bg3.voffset + 0); if(io.bgMode == 4) { - if(hvalue & validBit) { - if(!(hvalue & 0x8000)) { - hoffset = offsetX + (hvalue & ~7); + if(hlookup & validBit) { + if(!(hlookup & 0x8000)) { + hoffset = offsetX + (hlookup & ~7); } else { - voffset = y + hvalue; + voffset = y + hlookup; } } } else { - uint vvalue = getTile(io.bg3, (offsetX - 8) + (io.bg3.hoffset & ~7), io.bg3.voffset + 8); - if(hvalue & validBit) { - hoffset = offsetX + (hvalue & ~7); + uint vlookup = getTile(io.bg3, (offsetX - 8) + (io.bg3.hoffset & ~7), io.bg3.voffset + 8); + if(hlookup & validBit) { + hoffset = offsetX + (hlookup & ~7); } - if(vvalue & validBit) { - voffset = y + vvalue; + if(vlookup & validBit) { + voffset = y + vlookup; } } } @@ -74,11 +74,11 @@ auto PPU::Line::renderBackground(PPU::IO::Background& self, uint source) -> void uint mirrorX = tileNumber & 0x4000 ? 7 : 0; uint tilePriority = tileNumber & 0x2000 ? self.priority[1] : self.priority[0]; uint paletteNumber = tileNumber >> 10 & 7; - uint paletteIndex = (paletteBase + (paletteNumber << paletteShift)) & 0xff; + uint paletteIndex = paletteBase + (paletteNumber << paletteShift) & 0xff; if(tileWidth == 4 && (hoffset & 8) - 1 != mirrorX) tileNumber += 1; if(tileHeight == 4 && (voffset & 8) - 1 != mirrorY) tileNumber += 16; - tileNumber = ((tileNumber & 0x03ff) + tiledataIndex) & tileMask; + tileNumber = (tileNumber & 0x03ff) + tiledataIndex & tileMask; auto tiledata = ppu.tilecache[self.tileMode] + (tileNumber << 6); tiledata += ((voffset & 7) ^ mirrorY) << 3; @@ -114,18 +114,15 @@ auto PPU::Line::renderBackground(PPU::IO::Background& self, uint source) -> void auto PPU::Line::getTile(PPU::IO::Background& self, uint hoffset, uint voffset) -> uint { bool hires = io.bgMode == 5 || io.bgMode == 6; - uint width = !hires ? 256 : 512; - uint tileHeight = self.tileSize ? 4 : 3; - uint tileWidth = hires ? 4 : tileHeight; - uint hmask = (width << (tileHeight == 4) << self.screenSize.bit(0)) - 1; - uint vmask = (width << (tileHeight == 4) << self.screenSize.bit(1)) - 1; + uint tileHeight = 3 + self.tileSize; + uint tileWidth = !hires ? tileHeight : 4; uint screenX = self.screenSize.bit(0) ? 32 << 5 : 0; - uint screenY = self.screenSize.bit(1) ? screenX + (32 << 5) : 0; - uint tileX = (hoffset & hmask) >> tileWidth; - uint tileY = (voffset & vmask) >> tileHeight; - uint tilePosition = (tileY & 0x1f) << 5 | (tileX & 0x1f); - if(tileX & 0x20) tilePosition += screenX; - if(tileY & 0x20) tilePosition += screenY; - uint15 tiledataAddress = self.screenAddress + tilePosition; - return ppu.vram[tiledataAddress]; + uint screenY = self.screenSize.bit(1) ? 32 << 5 + self.screenSize.bit(0) : 0; + uint tileX = hoffset >> tileWidth; + uint tileY = voffset >> tileHeight; + uint offset = (tileY & 0x1f) << 5 | (tileX & 0x1f); + if(tileX & 0x20) offset += screenX; + if(tileY & 0x20) offset += screenY; + uint15 address = self.screenAddress + offset; + return ppu.vram[address]; } diff --git a/higan/sfc/ppu-fast/line.cpp b/higan/sfc/ppu-fast/line.cpp index 028923cc..33a6af81 100644 --- a/higan/sfc/ppu-fast/line.cpp +++ b/higan/sfc/ppu-fast/line.cpp @@ -16,27 +16,26 @@ auto PPU::Line::render() -> void { renderBackground(io.bg4, Source::BG4); renderObject(io.obj); + auto output = !ppu.interlace() || !ppu.field() ? outputLo : outputHi; + auto width = !ppu.hires() ? 256 : 512; + auto luma = io.displayBrightness << 15; + if(io.displayDisable) { - for(uint x : range(512)) { - outputLo[x] = 0; - outputHi[x] = 0; - } + for(uint x : range(width)) output[x] = 0; return; } renderWindow(io.col.window, io.col.window.aboveMask, windowAbove); renderWindow(io.col.window, io.col.window.belowMask, windowBelow); - if(!hires) for(uint x : range(256)) { - outputLo[x << 1 | 0] = - outputHi[x << 1 | 0] = - outputLo[x << 1 | 1] = - outputHi[x << 1 | 1] = io.displayBrightness << 15 | pixel(x, above[x], below[x]); + if(width == 256) for(uint x : range(width)) { + output[x] = luma | pixel(x, above[x], below[x]); + } else if(!hires) for(uint x : range(256)) { + output[x << 1 | 0] = + output[x << 1 | 1] = luma | pixel(x, above[x], below[x]); } else for(uint x : range(256)) { - outputLo[x << 1 | 0] = - outputHi[x << 1 | 0] = io.displayBrightness << 15 | pixel(x, below[x], above[x]); - outputLo[x << 1 | 1] = - outputHi[x << 1 | 1] = io.displayBrightness << 15 | pixel(x, above[x], below[x]); + output[x << 1 | 0] = luma | pixel(x, below[x], above[x]); + output[x << 1 | 1] = luma | pixel(x, above[x], below[x]); } } diff --git a/higan/sfc/ppu-fast/mode7.cpp b/higan/sfc/ppu-fast/mode7.cpp index 38bc5b3a..06c7c6bd 100644 --- a/higan/sfc/ppu-fast/mode7.cpp +++ b/higan/sfc/ppu-fast/mode7.cpp @@ -1,5 +1,7 @@ auto PPU::Line::renderMode7(PPU::IO::Background& self, uint source) -> void { - int y = !io.mode7.vflip ? (int)this->y : 255 - y; + int Y = this->y - this->y % (1 + io.mosaicSize); + int y = !io.mode7.vflip ? Y : 255 - Y; + int a = (int16)io.mode7.a; int b = (int16)io.mode7.b; int c = (int16)io.mode7.c; @@ -23,7 +25,8 @@ auto PPU::Line::renderMode7(PPU::IO::Background& self, uint source) -> void { renderWindow(self.window, self.window.aboveEnable, windowAbove); renderWindow(self.window, self.window.belowEnable, windowBelow); - for(int x : range(256)) { + for(int X : range(256)) { + int x = !io.mode7.hflip ? X : 255 - X; int pixelX = originX + a * x >> 8; int pixelY = originY + c * x >> 8; int tileX = pixelX >> 3 & 127; @@ -51,7 +54,7 @@ auto PPU::Line::renderMode7(PPU::IO::Background& self, uint source) -> void { if(io.col.directColor) { mosaicColor = directColor(0, palette); } else { - mosaicColor = ppu.cgram[palette]; + mosaicColor = cgram[palette]; } } if(!mosaicPalette) continue; diff --git a/higan/sfc/ppu-fast/object.cpp b/higan/sfc/ppu-fast/object.cpp index 1061292d..a27547e7 100644 --- a/higan/sfc/ppu-fast/object.cpp +++ b/higan/sfc/ppu-fast/object.cpp @@ -91,8 +91,8 @@ auto PPU::Line::renderObject(PPU::IO::Object& self) -> void { } } - self.rangeOver |= itemCount > 32; - self.timeOver |= tileCount > 34; + ppu.io.obj.rangeOver |= itemCount > 32; + ppu.io.obj.timeOver |= tileCount > 34; for(uint n : range(34)) { const auto& tile = tiles[n]; @@ -107,7 +107,7 @@ auto PPU::Line::renderObject(PPU::IO::Object& self) -> void { if(uint color = tiledata[x ^ mirrorX]) { uint source = tile.palette < 192 ? Source::OBJ1 : Source::OBJ2; uint priority = self.priority[tile.priority]; - color = ppu.cgram[tile.palette + color]; + color = cgram[tile.palette + color]; if(self.aboveEnable && !windowAbove[x]) plotAbove(tileX, source, priority, color); if(self.belowEnable && !windowBelow[x]) plotBelow(tileX, source, priority, color); } diff --git a/higan/sfc/ppu-fast/ppu.cpp b/higan/sfc/ppu-fast/ppu.cpp index 0f9b66fb..84b4e29c 100644 --- a/higan/sfc/ppu-fast/ppu.cpp +++ b/higan/sfc/ppu-fast/ppu.cpp @@ -63,7 +63,15 @@ auto PPU::main() -> void { auto PPU::scanline() -> void { if(vcounter() == 0) { - frame(); + frame.interlace = io.interlace; + frame.overscan = io.overscan; + frame.hires = false; + io.obj.timeOver = false; + io.obj.rangeOver = false; + } + + if(vcounter() > 0 && vcounter() < vdisp()) { + frame.hires |= io.pseudoHires || io.bgMode == 5 || io.bgMode == 6; } if(vcounter() == vdisp() && !io.displayDisable) { @@ -80,17 +88,12 @@ auto PPU::scanline() -> void { } } -auto PPU::frame() -> void { - io.obj.timeOver = false; - io.obj.rangeOver = false; -} - auto PPU::refresh() -> void { auto output = this->output; if(!overscan()) output -= 14 * 512; - auto pitch = 512; - auto width = 512; - auto height = 480; + auto pitch = 512 << !interlace(); + auto width = 256 << hires(); + auto height = 240 << interlace(); Emulator::video.refresh(output, pitch * sizeof(uint32), width, height); } diff --git a/higan/sfc/ppu-fast/ppu.hpp b/higan/sfc/ppu-fast/ppu.hpp index bfe1c99c..bef8fa2c 100644 --- a/higan/sfc/ppu-fast/ppu.hpp +++ b/higan/sfc/ppu-fast/ppu.hpp @@ -3,10 +3,12 @@ //limitations: //* mid-scanline effects not support //* mid-frame OAM changes not supported +//* range-time over flags not reported in real-time struct PPU : Thread, PPUcounter { - alwaysinline auto interlace() const -> bool { return false; } - alwaysinline auto overscan() const -> bool { return false; } + alwaysinline auto interlace() const -> bool { return frame.interlace; } + alwaysinline auto overscan() const -> bool { return frame.overscan; } + alwaysinline auto hires() const -> bool { return frame.hires; } alwaysinline auto vdisp() const -> uint { return !io.overscan ? 225 : 240; } //ppu.cpp @@ -17,7 +19,6 @@ struct PPU : Thread, PPUcounter { alwaysinline auto step(uint clocks) -> void; auto main() -> void; auto scanline() -> void; - auto frame() -> void; auto refresh() -> void; auto load(Markup::Node) -> bool; auto power(bool reset) -> void; @@ -171,6 +172,12 @@ public: } col; } io; + struct Frame { + uint1 interlace; + uint1 overscan; + uint1 hires; + } frame; + //object.cpp auto oamAddressReset() -> void; auto oamSetFirstObject() -> void; diff --git a/higan/sfc/ppu/background.cpp b/higan/sfc/ppu/background.cpp index 246541f5..40893bf1 100644 --- a/higan/sfc/ppu/background.cpp +++ b/higan/sfc/ppu/background.cpp @@ -52,23 +52,18 @@ auto PPU::Background::begin() -> void { } auto PPU::Background::getTile() -> void { - uint colorDepth = io.mode == Mode::BPP2 ? 0 : io.mode == Mode::BPP4 ? 1 : 2; uint paletteOffset = ppu.io.bgMode == 0 ? id << 5 : 0; - uint paletteSize = 2 << colorDepth; - uint tileMask = ppu.vram.mask >> 3 + colorDepth; - uint tiledataIndex = io.tiledataAddress >> 3 + colorDepth; + uint paletteSize = 2 << io.mode; + uint tileMask = ppu.vram.mask >> 3 + io.mode; + uint tiledataIndex = io.tiledataAddress >> 3 + io.mode; - uint tileHeight = io.tileSize == TileSize::Size8x8 ? 3 : 4; + uint tileHeight = 3 + io.tileSize; uint tileWidth = !hires() ? tileHeight : 4; uint width = 256 << hires(); - uint hmask = tileHeight == 3 ? width : width << 1; - uint vmask = hmask; - if(io.screenSize & 1) hmask <<= 1; - if(io.screenSize & 2) vmask <<= 1; - hmask--; - vmask--; + uint hmask = (width << io.tileSize << io.screenSize.bit(0)) - 1; + uint vmask = (width << io.tileSize << io.screenSize.bit(1)) - 1; uint px = x << hires(); uint py = mosaic.enable ? (uint)mosaic.voffset : y; @@ -87,21 +82,21 @@ auto PPU::Background::getTile() -> void { uint16 offsetX = px + (hscroll & 7); if(offsetX >= 8) { - uint hval = ppu.bg3.getTile((offsetX - 8) + (ppu.bg3.hoffset() & ~7), ppu.bg3.voffset() + 0); - uint vval = ppu.bg3.getTile((offsetX - 8) + (ppu.bg3.hoffset() & ~7), ppu.bg3.voffset() + 8); - uint validMask = id == ID::BG1 ? 0x2000 : 0x4000; + auto hlookup = ppu.bg3.getTile((offsetX - 8) + (ppu.bg3.hoffset() & ~7), ppu.bg3.voffset() + 0); + auto vlookup = ppu.bg3.getTile((offsetX - 8) + (ppu.bg3.hoffset() & ~7), ppu.bg3.voffset() + 8); + uint valid = 13 + id; if(ppu.io.bgMode == 4) { - if(hval & validMask) { - if((hval & 0x8000) == 0) { - hoffset = offsetX + (hval & ~7); + if(hlookup.bit(valid)) { + if(!hlookup.bit(15)) { + hoffset = offsetX + (hlookup & ~7); } else { - voffset = py + hval; + voffset = py + hlookup; } } } else { - if(hval & validMask) hoffset = offsetX + (hval & ~7); - if(vval & validMask) voffset = py + vval; + if(hlookup.bit(valid)) hoffset = offsetX + (hlookup & ~7); + if(vlookup.bit(valid)) voffset = py + vlookup; } } } @@ -109,16 +104,15 @@ auto PPU::Background::getTile() -> void { hoffset &= hmask; voffset &= vmask; - uint screenX = io.screenSize & 1 ? 32 << 5 : 0; - uint screenY = io.screenSize & 2 ? 32 << 5 : 0; - if(io.screenSize == 3) screenY <<= 1; + uint screenX = io.screenSize.bit(0) ? 32 << 5 : 0; + uint screenY = io.screenSize.bit(1) ? 32 << 5 + io.screenSize.bit(0) : 0; - uint tx = hoffset >> tileWidth; - uint ty = voffset >> tileHeight; + uint tileX = hoffset >> tileWidth; + uint tileY = voffset >> tileHeight; - uint16 offset = (ty & 0x1f) << 5 | (tx & 0x1f); - if(tx & 0x20) offset += screenX; - if(ty & 0x20) offset += screenY; + uint16 offset = (tileY & 0x1f) << 5 | (tileX & 0x1f); + if(tileX & 0x20) offset += screenX; + if(tileY & 0x20) offset += screenY; uint16 address = io.screenAddress + offset; tile = ppu.vram[address]; @@ -133,7 +127,7 @@ auto PPU::Background::getTile() -> void { uint16 character = tile.bits(0,9) + tiledataIndex & tileMask; if(mirrorY) voffset ^= 7; - offset = (character << 3 + colorDepth) + (voffset & 7); + offset = (character << 3 + io.mode) + (voffset & 7); switch(io.mode) { case Mode::BPP8: @@ -243,28 +237,16 @@ auto PPU::Background::power() -> void { for(auto& word : data) word = 0; } -auto PPU::Background::getTile(uint x, uint y) -> uint { - uint tileHeight = io.tileSize == TileSize::Size8x8 ? 3 : 4; +auto PPU::Background::getTile(uint x, uint y) -> uint16 { + uint tileHeight = 3 + io.tileSize; uint tileWidth = !hires() ? tileHeight : 4; - uint width = !hires() ? 256 : 512; - uint maskX = tileHeight == 3 ? width : width << 1; - uint maskY = maskX; - if(io.screenSize & 1) maskX <<= 1; - if(io.screenSize & 2) maskY <<= 1; - maskX--; - maskY--; - - uint screenX = io.screenSize & 1 ? 32 << 5 : 0; - uint screenY = io.screenSize & 2 ? 32 << 5 : 0; - if(io.screenSize == 3) screenY <<= 1; - - x = (x & maskX) >> tileWidth; - y = (y & maskY) >> tileHeight; - - uint16 offset = (y & 0x1f) << 5 | (x & 0x1f); - if(x & 0x20) offset += screenX; - if(y & 0x20) offset += screenY; - + uint screenX = io.screenSize.bit(0) ? 32 << 5 : 0; + uint screenY = io.screenSize.bit(1) ? 32 << 5 + io.screenSize.bit(0) : 0; + uint tileX = x >> tileWidth; + uint tileY = y >> tileHeight; + uint16 offset = (tileY & 0x1f) << 5 | (tileX & 0x1f); + if(tileX & 0x20) offset += screenX; + if(tileY & 0x20) offset += screenY; uint16 address = io.screenAddress + offset; return ppu.vram[address]; } diff --git a/higan/sfc/ppu/background.hpp b/higan/sfc/ppu/background.hpp index 2a3acb3d..a6e59f58 100644 --- a/higan/sfc/ppu/background.hpp +++ b/higan/sfc/ppu/background.hpp @@ -13,7 +13,7 @@ struct Background { auto getTile() -> void; auto getTileColor() -> uint; - auto getTile(uint x, uint y) -> uint; + auto getTile(uint x, uint y) -> uint16; alwaysinline auto clip(int n) -> int; auto beginMode7() -> void; auto runMode7() -> void; diff --git a/hiro/GNUmakefile b/hiro/GNUmakefile index 7cd861d2..14fa55e2 100644 --- a/hiro/GNUmakefile +++ b/hiro/GNUmakefile @@ -26,7 +26,7 @@ ifeq ($(platform),macos) ifeq ($(hiro),cocoa) hiroflags = $(objcppflags) $(flags) -w -DHIRO_COCOA - hirolink = -framework Cocoa -framework Carbon + hirolink = -framework Cocoa -framework Carbon -framework Security endif endif diff --git a/hiro/cocoa/window.cpp b/hiro/cocoa/window.cpp index 93fd41e8..7ff104cc 100644 --- a/hiro/cocoa/window.cpp +++ b/hiro/cocoa/window.cpp @@ -38,11 +38,11 @@ [item setTarget:self]; [rootMenu addItem:item]; - string result = nall::execute("defaults", "read", "/Library/Preferences/com.apple.security", "GKAutoRearm").output.strip(); - if(result != "0") { - disableGatekeeperAutoRearm = [[[NSMenuItem alloc] initWithTitle:@"Disable Gatekeeper Auto-Rearm" action:@selector(menuDisableGatekeeperAutoRearm) keyEquivalent:@""] autorelease]; - [disableGatekeeperAutoRearm setTarget:self]; - [rootMenu addItem:disableGatekeeperAutoRearm]; + string result = nall::execute("spctl", "--status").output.strip(); + if(result != "assessments disabled") { + disableGatekeeper = [[[NSMenuItem alloc] initWithTitle:@"Disable Gatekeeper" action:@selector(menuDisableGatekeeper) keyEquivalent:@""] autorelease]; + [disableGatekeeper setTarget:self]; + [rootMenu addItem:disableGatekeeper]; } [rootMenu addItem:[NSMenuItem separatorItem]]; @@ -139,18 +139,44 @@ hiro::Application::Cocoa::doPreferences(); } --(void) menuDisableGatekeeperAutoRearm { +//to hell with gatekeepers +-(void) menuDisableGatekeeper { NSAlert* alert = [[[NSAlert alloc] init] autorelease]; - [alert setMessageText:@"Disable Gatekeeper Auto-Rearm"]; + [alert setMessageText:@"Disable Gatekeeper"]; - nall::execute("sudo", "defaults", "write", "/Library/Preferences/com.apple.security", "GKAutoRearm", "-bool", "NO"); - if(nall::execute("defaults", "read", "/Library/Preferences/com.apple.security", "GKAutoRearm").output.strip() == "0") { + AuthorizationRef authorization; + OSStatus status = AuthorizationCreate(nullptr, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorization); + if(status == errAuthorizationSuccess) { + AuthorizationItem items = {kAuthorizationRightExecute, 0, nullptr, 0}; + AuthorizationRights rights = {1, &items}; + status = AuthorizationCopyRights(authorization, &rights, nullptr, + kAuthorizationFlagDefaults + | kAuthorizationFlagInteractionAllowed + | kAuthorizationFlagPreAuthorize + | kAuthorizationFlagExtendRights, nullptr); + if(status == errAuthorizationSuccess) { + { char program[] = "/usr/sbin/spctl"; + char arguments[] = {"--master-disable", nullptr}; + FILE* pipe = nullptr; + AuthorizationExecuteWithPrivileges(authorization, program, kAuthorizationFlagDefaults, arguments, &pipe); + } + { char program[] = "/usr/bin/defaults"; + char arguments[] = {"write /Library/Preferences/com.apple.security GKAutoRearm -bool NO"}; + FILE* pipe = nullptr; + AuthorizationExecuteWithPrivileges(authorization, program, kAuthorizationFlagDefaults, arguments, &pipe); + } + } + AuthorizationFree(authorization, kAuthorizationFlagDefaults); + } + + string result = nall::execute("spctl", "--status").output.strip(); + if(result == "assessments disabled") { [alert setAlertStyle:NSInformationalAlertStyle]; - [alert setInformativeText:@"Gatekeeper's automatic 30-day rearm behavior has been disabled successfully."]; - [disableGatekeeperAutoRearm setHidden:YES]; + [alert setInformativeText:@"Gatekeeper has been successfully disabled."]; + [disableGatekeeper setHidden:YES]; } else { [alert setAlertStyle:NSWarningAlertStyle]; - [alert setInformativeText:@"Error: failed to disable Gatekeeper's automatic rearm behavior."]; + [alert setInformativeText:@"Error: failed to disable Gatekeeper."]; } [alert addButtonWithTitle:@"Ok"]; diff --git a/nall/GNUmakefile b/nall/GNUmakefile index 4f9c9c3e..db9ffc9d 100644 --- a/nall/GNUmakefile +++ b/nall/GNUmakefile @@ -12,34 +12,31 @@ MAKEFLAGS := Rr # platform detection ifeq ($(platform),) - uname := $(shell uname -s) + uname := $(shell uname) ifeq ($(uname),) platform := windows - rm = del /q $(subst /,\,$1) - rmdir = del /s /q $(subst /,\,$1) && if exist $(subst /,\,$1) (rmdir /s /q $(subst /,\,$1)) else ifneq ($(findstring Windows,$(uname)),) platform := windows - rm = del /q $(subst /,\,$1) - rmdir = del /s /q $(subst /,\,$1) && if exist $(subst /,\,$1) (rmdir /s /q $(subst /,\,$1)) - else ifneq ($(findstring _NT,$(uname)),) + else ifneq ($(findstring NT,$(uname)),) platform := windows - rm = del /q $(subst /,\,$1) - rmdir = del /s /q $(subst /,\,$1) && if exist $(subst /,\,$1) (rmdir /s /q $(subst /,\,$1)) else ifneq ($(findstring Darwin,$(uname)),) platform := macos - rm = rm -f $1 - rmdir = rm -rf $1 else ifneq ($(findstring Linux,$(uname)),) platform := linux - rm = rm -f $1 - rmdir = rm -rf $1 else ifneq ($(findstring BSD,$(uname)),) platform := bsd - rm = rm -f $1 - rmdir = rm -rf $1 else $(error unknown platform, please specify manually.) endif + + # common commands + ifeq ($(uname),) + rm = del /q $(subst /,\,$1) + rmdir = del /s /q $(subst /,\,$1) && if exist $(subst /,\,$1) (rmdir /s /q $(subst /,\,$1)) + else + rm = rm -f $1 + rmdir = rm -rf $1 + endif endif cflags := -x c -std=c11 @@ -78,6 +75,15 @@ else ifeq ($(build),performance) flags += -O3 -DBUILD_PERFORMANCE endif +# openmp support +ifeq ($(openmp),true) + # macOS Xcode does not ship with OpenMP support + ifneq ($(platform),macos) + flags += -fopenmp + link += -fopenmp + endif +endif + # clang settings ifeq ($(findstring clang++,$(compiler)),clang++) flags += -fno-strict-aliasing -fwrapv