From 04986d2bf707f4fbc24dc5d5c707eda30bc8e52f Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 28 Jan 2014 21:04:58 +1100 Subject: [PATCH] Update to v094r01 release. byuu says: Changelog: - port: various compilation fixes for OS X [kode54] - nall: added programpath() function to return path to process binary [todo: need to have ethos use this function] - ruby: XAudio2 will select default game sound device instead of first sound device - ruby: DirectInput device IDs are no longer ambiguous when VID+PID are identical - ruby: OpenGL won't try and terminate if it hasn't been initialized - gb: D-pad up+down/left+right not masked in SGB mode - sfc: rewrote ICD2 video rendering to output in real-time, work with cycle-based Game Boy renderer - sfc: rewrote Bus::reduce(), reduces game loading time by about 500ms - ethos: store save states in {game}/higan/* instead of {game}/bsnes/* - loki: added target-loki/ (blank stub for now) - Makefile: purge out/* on make clean --- Makefile | 4 +- emulator/emulator.hpp | 2 +- gb/cpu/mmio.cpp | 9 ++-- gb/interface/interface.cpp | 4 ++ gb/interface/interface.hpp | 2 + gb/ppu/dmg.cpp | 1 + gb/ppu/ppu.cpp | 3 +- nall/intrinsics.hpp | 7 +++ nall/platform.hpp | 2 +- nall/string/base.hpp | 1 + nall/string/platform.hpp | 14 ++++++ nall/windows/guid.hpp | 2 +- ruby/audio/xaudio2.cpp | 21 ++++++--- ruby/input/carbon.cpp | 7 ++- ruby/input/joypad/directinput.cpp | 17 ++++--- ruby/video/cgl.cpp | 17 ++----- ruby/video/opengl/main.hpp | 4 +- ruby/video/opengl/opengl.hpp | 1 + sfc/chip/icd2/icd2.cpp | 11 +++-- sfc/chip/icd2/icd2.hpp | 4 +- sfc/chip/icd2/interface/interface.cpp | 15 +++++-- sfc/chip/icd2/interface/interface.hpp | 1 + sfc/chip/icd2/mmio/mmio.cpp | 31 +++---------- sfc/chip/icd2/mmio/mmio.hpp | 16 +++---- sfc/chip/icd2/serialization.cpp | 12 +++-- sfc/memory/memory-inline.hpp | 33 +++++++------- sfc/sfc.hpp | 2 +- target-ethos/Makefile | 5 +-- target-ethos/utility/utility.cpp | 10 ++--- target-loki/Makefile | 65 +++++++++++++++++++++++++++ target-loki/loki.cpp | 38 ++++++++++++++++ target-loki/loki.hpp | 29 ++++++++++++ 32 files changed, 272 insertions(+), 118 deletions(-) create mode 100644 target-loki/Makefile create mode 100644 target-loki/loki.cpp create mode 100644 target-loki/loki.hpp diff --git a/Makefile b/Makefile index c05cc820..f3025bea 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,8 @@ gb := gb gba := gba profile := accuracy -target := ethos +target := ethos +# target := loki # options += debugger # arch := x86 @@ -77,6 +78,7 @@ flags := $(flags) $(foreach o,$(call strupper,$(options)),-D$o) # targets clean: + -@$(call delete,out/*) -@$(call delete,obj/*.o) -@$(call delete,obj/*.a) -@$(call delete,obj/*.so) diff --git a/emulator/emulator.hpp b/emulator/emulator.hpp index a715e8be..44d9cf0e 100644 --- a/emulator/emulator.hpp +++ b/emulator/emulator.hpp @@ -3,7 +3,7 @@ namespace Emulator { static const char Name[] = "higan"; - static const char Version[] = "094"; + static const char Version[] = "094.01"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; static const char Website[] = "http://byuu.org/"; diff --git a/gb/cpu/mmio.cpp b/gb/cpu/mmio.cpp index 7c54d491..1eba8ad4 100644 --- a/gb/cpu/mmio.cpp +++ b/gb/cpu/mmio.cpp @@ -20,9 +20,12 @@ void CPU::mmio_joyp_poll() { dpad |= interface->inputPoll(0, 0, (unsigned)Input::Left) << 1; dpad |= interface->inputPoll(0, 0, (unsigned)Input::Right) << 0; - //D-pad pivot makes it impossible to press opposing directions at the same time - if(dpad & 4) dpad &= ~8; //disallow up+down - if(dpad & 2) dpad &= ~1; //disallow left+right + if(system.revision != System::Revision::SuperGameBoy) { + //D-pad pivot makes it impossible to press opposing directions at the same time + //however, Super Game Boy BIOS is able to set these bits together + if(dpad & 4) dpad &= ~8; //disallow up+down + if(dpad & 2) dpad &= ~1; //disallow left+right + } status.joyp = 0x0f; if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req; diff --git a/gb/interface/interface.cpp b/gb/interface/interface.cpp index 44b8c15a..fdddfc6e 100644 --- a/gb/interface/interface.cpp +++ b/gb/interface/interface.cpp @@ -8,6 +8,10 @@ void Interface::lcdScanline() { if(hook) hook->lcdScanline(); } +void Interface::lcdOutput(uint2 color) { + if(hook) hook->lcdOutput(color); +} + void Interface::joypWrite(bool p15, bool p14) { if(hook) hook->joypWrite(p15, p14); } diff --git a/gb/interface/interface.hpp b/gb/interface/interface.hpp index f9a5ca5f..822eb1f0 100644 --- a/gb/interface/interface.hpp +++ b/gb/interface/interface.hpp @@ -29,11 +29,13 @@ struct Interface : Emulator::Interface { //Super Game Boy bindings struct Hook { virtual void lcdScanline() {} + virtual void lcdOutput(uint2 color) {} virtual void joypWrite(bool p15, bool p14) {} }; Hook* hook = nullptr; void lcdScanline(); + void lcdOutput(uint2 color); void joypWrite(bool p15, bool p14); string title(); diff --git a/gb/ppu/dmg.cpp b/gb/ppu/dmg.cpp index 6b8905d6..2d9b39b2 100644 --- a/gb/ppu/dmg.cpp +++ b/gb/ppu/dmg.cpp @@ -79,6 +79,7 @@ void PPU::dmg_run() { uint32* output = screen + status.ly * 160 + px++; *output = color; + interface->lcdOutput(color); //Super Game Boy notification } void PPU::dmg_run_bg() { diff --git a/gb/ppu/ppu.cpp b/gb/ppu/ppu.cpp index 27ddc002..ecba6e82 100644 --- a/gb/ppu/ppu.cpp +++ b/gb/ppu/ppu.cpp @@ -25,6 +25,8 @@ void PPU::main() { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } + interface->lcdScanline(); //Super Game Boy notification + if(status.display_enable && status.ly < 144) { if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat); add_clocks(92); @@ -56,7 +58,6 @@ void PPU::scanline() { if(++status.ly == 154) frame(); if(status.ly < 144) { - interface->lcdScanline(); //Super Game Boy rendering notification system.cgb() ? cgb_scanline() : dmg_scanline(); } diff --git a/nall/intrinsics.hpp b/nall/intrinsics.hpp index 2d6a43ed..1088edb1 100644 --- a/nall/intrinsics.hpp +++ b/nall/intrinsics.hpp @@ -3,6 +3,13 @@ namespace nall { +#if defined(_WIN32) +#elif defined(__APPLE__) + #include +#else + #include +#endif + struct Intrinsics { enum class Compiler : unsigned { Clang, GCC, VisualCPP, Unknown }; enum class Platform : unsigned { Windows, MacOSX, X, Unknown }; //X = Linux, BSD, etc diff --git a/nall/platform.hpp b/nall/platform.hpp index 24576792..e7bb9c6d 100644 --- a/nall/platform.hpp +++ b/nall/platform.hpp @@ -41,7 +41,7 @@ namespace Math { #undef interface #define dllexport __declspec(dllexport) #else - #include + #include #include #include #define dllexport diff --git a/nall/string/base.hpp b/nall/string/base.hpp index 284c2312..7ba6f0fc 100644 --- a/nall/string/base.hpp +++ b/nall/string/base.hpp @@ -201,6 +201,7 @@ template inline string binary(uintmax_ //platform.hpp inline string activepath(); inline string realpath(const string& name); +inline string programpath(); inline string userpath(); inline string configpath(); inline string sharedpath(); diff --git a/nall/string/platform.hpp b/nall/string/platform.hpp index e71bd32f..d80060f3 100644 --- a/nall/string/platform.hpp +++ b/nall/string/platform.hpp @@ -22,6 +22,20 @@ string realpath(const string& name) { return result; } +string programpath() { + #if defined(PLATFORM_WINDOWS) + int argc = 0; + wchar_t** argv = CommandLineToArgvW(GetCommandLine(), &argc); + string argv0 = (const char*)utf8_t(argv[0]); + LocalFree(argv); + return realpath(argv0); + #else + Dl_info info; + dladdr((void*)&programpath, &info); + return realpath(info.dli_fname); + #endif +} + // /home/username/ // c:/users/username/ string userpath() { diff --git a/nall/windows/guid.hpp b/nall/windows/guid.hpp index adee891d..da664bcc 100644 --- a/nall/windows/guid.hpp +++ b/nall/windows/guid.hpp @@ -8,7 +8,7 @@ namespace nall { //generate unique GUID inline string guid() { - random_lfsr lfsr; + LinearFeedbackShiftRegisterGenerator lfsr; lfsr.seed(time(nullptr)); for(unsigned n = 0; n < 256; n++) lfsr(); diff --git a/ruby/audio/xaudio2.cpp b/ruby/audio/xaudio2.cpp index 19add187..9ee6ef54 100644 --- a/ruby/audio/xaudio2.cpp +++ b/ruby/audio/xaudio2.cpp @@ -1,8 +1,3 @@ -/* - audio.xaudio2 (2010-08-14) - author: OV2 -*/ - #include "xaudio2.hpp" #include @@ -132,7 +127,19 @@ public: return false; } - if(FAILED(hr = pXAudio2->CreateMasteringVoice( &pMasterVoice, 2, settings.frequency, 0, 0 , NULL))) { + unsigned deviceCount = 0; + pXAudio2->GetDeviceCount(&deviceCount); + if(deviceCount == 0) { term(); return false; } + + unsigned deviceID = 0; + for(unsigned deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { + XAUDIO2_DEVICE_DETAILS deviceDetails; + memset(&deviceDetails, 0, sizeof(XAUDIO2_DEVICE_DETAILS)); + pXAudio2->GetDeviceDetails(deviceIndex, &deviceDetails); + if(deviceDetails.Role & DefaultGameDevice) deviceID = deviceIndex; + } + + if(FAILED(hr = pXAudio2->CreateMasteringVoice(&pMasterVoice, 2, settings.frequency, 0, deviceID, NULL))) { return false; } @@ -145,7 +152,7 @@ public: wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.cbSize = 0; - if(FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx, XAUDIO2_VOICE_NOSRC , XAUDIO2_DEFAULT_FREQ_RATIO, this, NULL, NULL))) { + if(FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx, XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO, this, NULL, NULL))) { return false; } diff --git a/ruby/input/carbon.cpp b/ruby/input/carbon.cpp index 2ca5f55e..329f4a6e 100644 --- a/ruby/input/carbon.cpp +++ b/ruby/input/carbon.cpp @@ -35,18 +35,21 @@ struct pInputCarbon { group.input[inputID].value = value; } - void poll(vector& devices) { + vector poll() { + vector devices; + KeyMap keymap; GetKeys(keymap); uint8_t* buffer = (uint8_t*)keymap; unsigned inputID = 0; for(auto& key : keys) { - bool value = buffer[key.id >> 3] & (1 << (key.id & 7))); + bool value = buffer[key.id >> 3] & (1 << (key.id & 7)); assign(kb.hid, HID::Keyboard::GroupID::Button, inputID++, value); } devices.append(&kb.hid); + return devices; } bool rumble(uint64_t id, bool enable) { diff --git a/ruby/input/joypad/directinput.cpp b/ruby/input/joypad/directinput.cpp index d8837895..1ffbc555 100644 --- a/ruby/input/joypad/directinput.cpp +++ b/ruby/input/joypad/directinput.cpp @@ -107,13 +107,9 @@ struct InputJoypadDirectInput { Joypad jp; jp.vendorID = instance->guidProduct.Data1 >> 0; jp.productID = instance->guidProduct.Data1 >> 16; + jp.isXInputDevice = false; if(auto device = rawinput.find(jp.vendorID, jp.productID)) { - jp.pathID = crc32_calculate((const uint8_t*)device().path.data(), device().path.size()); - jp.hid.id = (uint64_t)jp.pathID << 32 | jp.vendorID << 16 | jp.productID << 0; jp.isXInputDevice = device().isXInputDevice; - } else { - //this should never occur - return DIENUM_CONTINUE; } //Microsoft has intentionally imposed artificial restrictions on XInput devices when used with DirectInput @@ -133,6 +129,17 @@ struct InputJoypadDirectInput { device->EnumObjects(DirectInput_EnumJoypadEffectsCallback, (void*)this, DIDFT_FFACTUATOR); jp.hid.rumble = effects > 0; + DIPROPGUIDANDPATH property; + memset(&property, 0, sizeof(DIPROPGUIDANDPATH)); + property.diph.dwSize = sizeof(DIPROPGUIDANDPATH); + property.diph.dwHeaderSize = sizeof(DIPROPHEADER); + property.diph.dwObj = 0; + property.diph.dwHow = DIPH_DEVICE; + device->GetProperty(DIPROP_GUIDANDPATH, &property.diph); + string devicePath = (const char*)utf8_t(property.wszPath); + jp.pathID = crc32_calculate((const uint8_t*)devicePath.data(), devicePath.size()); + jp.hid.id = (uint64_t)jp.pathID << 32 | jp.vendorID << 16 | jp.productID << 0; + if(jp.hid.rumble) { //disable auto-centering spring for rumble support DIPROPDWORD property; diff --git a/ruby/video/cgl.cpp b/ruby/video/cgl.cpp index dca80c07..b1f4fd1e 100644 --- a/ruby/video/cgl.cpp +++ b/ruby/video/cgl.cpp @@ -15,13 +15,12 @@ namespace ruby { namespace ruby { struct pVideoCGL : OpenGL { - RubyVideoCGL* view; + RubyVideoCGL* view = nullptr; struct { - NSView* handle; - - bool synchronize; - unsigned filter; + NSView* handle = nullptr; + bool synchronize = false; + unsigned filter = 0; string shader; } settings; @@ -157,14 +156,6 @@ struct pVideoCGL : OpenGL { } } - pVideoCGL() { - view = nil; - - settings.handle = nil; - settings.synchronize = false; - settings.filter = 0; - } - ~pVideoCGL() { term(); } diff --git a/ruby/video/opengl/main.hpp b/ruby/video/opengl/main.hpp index 1213645d..829fda6a 100644 --- a/ruby/video/opengl/main.hpp +++ b/ruby/video/opengl/main.hpp @@ -200,11 +200,13 @@ bool OpenGL::init() { glrLinkProgram(program); shader(nullptr); - return true; + return initialized = true; } void OpenGL::term() { + if(initialized == false) return; shader(nullptr); //release shader resources (eg frame[] history) OpenGLSurface::release(); if(buffer) { delete[] buffer; buffer = nullptr; } + initialized = false; } diff --git a/ruby/video/opengl/opengl.hpp b/ruby/video/opengl/opengl.hpp index 4bbc473b..aeedfc1d 100644 --- a/ruby/video/opengl/opengl.hpp +++ b/ruby/video/opengl/opengl.hpp @@ -79,6 +79,7 @@ struct OpenGL : OpenGLProgram { Setting(const string& name, const string& value) : name(name), value(value) {} }; set settings; + bool initialized = false; void shader(const char* pathname); void allocateHistory(unsigned size); diff --git a/sfc/chip/icd2/icd2.cpp b/sfc/chip/icd2/icd2.cpp index 02ba74ad..b16be86a 100644 --- a/sfc/chip/icd2/icd2.cpp +++ b/sfc/chip/icd2/icd2.cpp @@ -52,20 +52,19 @@ void ICD2::power() { void ICD2::reset() { create(ICD2::Enter, cpu.frequency / 5); - r6000_ly = 0x00; - r6000_row = 0x00; r6003 = 0x00; r6004 = 0xff; r6005 = 0xff; r6006 = 0xff; r6007 = 0xff; for(auto& r : r7000) r = 0x00; - r7800 = 0x0000; mlt_req = 0; - for(auto& n : lcd.buffer) n = 0; - for(auto& n : lcd.output) n = 0; - lcd.row = 0; + for(auto& n : output) n = 0xff; + read_bank = 0; + read_addr = 0; + write_bank = 0; + write_addr = 0; packetsize = 0; joyp_id = 3; diff --git a/sfc/chip/icd2/icd2.hpp b/sfc/chip/icd2/icd2.hpp index 377a175c..433d9d4d 100644 --- a/sfc/chip/icd2/icd2.hpp +++ b/sfc/chip/icd2/icd2.hpp @@ -16,8 +16,8 @@ struct ICD2 : Emulator::Interface::Bind, GameBoy::Interface::Hook, Coprocessor { void serialize(serializer&); private: - Emulator::Interface::Bind* bind; - GameBoy::Interface::Hook* hook; + Emulator::Interface::Bind* bind = nullptr; + GameBoy::Interface::Hook* hook = nullptr; #include "interface/interface.hpp" #include "mmio/mmio.hpp" }; diff --git a/sfc/chip/icd2/interface/interface.cpp b/sfc/chip/icd2/interface/interface.cpp index 27d74624..187429a5 100644 --- a/sfc/chip/icd2/interface/interface.cpp +++ b/sfc/chip/icd2/interface/interface.cpp @@ -1,13 +1,20 @@ #ifdef ICD2_CPP -//called on rendered lines 0-143 (not on Vblank lines 144-153) void ICD2::lcdScanline() { + if(GameBoy::ppu.status.ly > 143) return; //Vblank if((GameBoy::ppu.status.ly & 7) == 0) { - lcd.row = (lcd.row + 1) & 3; + write_bank = (write_bank + 1) & 3; + write_addr = 0; } +} - unsigned offset = (lcd.row * 160 * 8) + ((GameBoy::ppu.status.ly & 7) * 160); - memcpy(lcd.buffer + offset, GameBoy::ppu.screen + GameBoy::ppu.status.ly * 160, 160 * sizeof(uint32)); +void ICD2::lcdOutput(uint2 color) { + unsigned y = write_addr / 160; + unsigned x = write_addr % 160; + unsigned addr = write_bank * 512 + y * 2 + x / 8 * 16; + output[addr + 0] = (output[addr + 0] << 1) | (bool)(color & 1); + output[addr + 1] = (output[addr + 1] << 1) | (bool)(color & 2); + write_addr = (write_addr + 1) % 1280; } void ICD2::joypWrite(bool p15, bool p14) { diff --git a/sfc/chip/icd2/interface/interface.hpp b/sfc/chip/icd2/interface/interface.hpp index 205adffc..3f2278da 100644 --- a/sfc/chip/icd2/interface/interface.hpp +++ b/sfc/chip/icd2/interface/interface.hpp @@ -1,4 +1,5 @@ void lcdScanline(); +void lcdOutput(uint2 color); void joypWrite(bool p15, bool p14); uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue); diff --git a/sfc/chip/icd2/mmio/mmio.cpp b/sfc/chip/icd2/mmio/mmio.cpp index 0847264d..64f61e15 100644 --- a/sfc/chip/icd2/mmio/mmio.cpp +++ b/sfc/chip/icd2/mmio/mmio.cpp @@ -1,27 +1,12 @@ #ifdef ICD2_CPP -//convert linear pixel data to 2bpp planar tiledata -void ICD2::render(const uint32* source) { - memset(lcd.output, 0x00, 320 * sizeof(uint16)); - - for(unsigned y = 0; y < 8; y++) { - for(unsigned x = 0; x < 160; x++) { - unsigned pixel = *source++; - unsigned addr = y * 2 + (x / 8 * 16); - lcd.output[addr + 0] |= ((pixel & 1) >> 0) << (7 - (x & 7)); - lcd.output[addr + 1] |= ((pixel & 2) >> 1) << (7 - (x & 7)); - } - } -} - uint8 ICD2::read(unsigned addr) { addr &= 0xffff; //LY counter if(addr == 0x6000) { - r6000_ly = GameBoy::ppu.status.ly; - r6000_row = lcd.row; - return r6000_ly; + unsigned y = min(143u, GameBoy::ppu.status.ly); + return (y & ~7) | write_bank; } //command ready port @@ -47,8 +32,8 @@ uint8 ICD2::read(unsigned addr) { //VRAM port if(addr == 0x7800) { - uint8 data = lcd.output[r7800]; - r7800 = (r7800 + 1) % 320; + uint8 data = output[read_bank * 512 + read_addr]; + read_addr = (read_addr + 1) & 511; return data; } @@ -60,12 +45,8 @@ void ICD2::write(unsigned addr, uint8 data) { //VRAM port if(addr == 0x6001) { - r6001 = data; - r7800 = 0; - - unsigned offset = (r6000_row - (4 - (r6001 - (r6000_ly & 3)))) & 3; - render(lcd.buffer + offset * 160 * 8); - + read_bank = data & 3; + read_addr = 0; return; } diff --git a/sfc/chip/icd2/mmio/mmio.hpp b/sfc/chip/icd2/mmio/mmio.hpp index df7ab07d..f7edbc4e 100644 --- a/sfc/chip/icd2/mmio/mmio.hpp +++ b/sfc/chip/icd2/mmio/mmio.hpp @@ -1,19 +1,13 @@ -void render(const uint32* source); - -uint8 r6000_ly; //SGB BIOS' cache of LY -uint8 r6000_row; //SGB BIOS' cache of ROW -uint8 r6001; //VRAM conversion uint8 r6003; //control port uint8 r6004; //joypad 1 uint8 r6005; //joypad 2 uint8 r6006; //joypad 3 uint8 r6007; //joypad 4 uint8 r7000[16]; //JOYP packet data -unsigned r7800; //VRAM offset uint8 mlt_req; //number of active joypads -struct LCD { - uint32 buffer[4 * 160 * 8]; //four tile rows of linear video data - uint16 output[320]; //one tile row of 2bpp video data - unsigned row; //active ICD2 rendering tile row -} lcd; +uint8 output[4 * 512]; +unsigned read_bank; +unsigned read_addr; +unsigned write_bank; +unsigned write_addr; diff --git a/sfc/chip/icd2/serialization.cpp b/sfc/chip/icd2/serialization.cpp index d0a1649a..72dfc134 100644 --- a/sfc/chip/icd2/serialization.cpp +++ b/sfc/chip/icd2/serialization.cpp @@ -18,21 +18,19 @@ void ICD2::serialize(serializer& s) { s.integer(bitdata); s.integer(bitoffset); - s.integer(r6000_ly); - s.integer(r6000_row); - s.integer(r6001); s.integer(r6003); s.integer(r6004); s.integer(r6005); s.integer(r6006); s.integer(r6007); s.array(r7000); - s.integer(r7800); s.integer(mlt_req); - s.array(lcd.buffer); - s.array(lcd.output); - s.integer(lcd.row); + s.array(output); + s.integer(read_bank); + s.integer(read_addr); + s.integer(write_bank); + s.integer(write_addr); } #endif diff --git a/sfc/memory/memory-inline.hpp b/sfc/memory/memory-inline.hpp index 7f2e3014..067a0758 100644 --- a/sfc/memory/memory-inline.hpp +++ b/sfc/memory/memory-inline.hpp @@ -56,31 +56,28 @@ MappedRAM::MappedRAM() : data_(nullptr), size_(0), write_protect_(false) {} //Bus unsigned Bus::mirror(unsigned addr, unsigned size) { + if(size == 0) return 0; unsigned base = 0; - if(size) { - unsigned mask = 1 << 23; - while(addr >= size) { - while(!(addr & mask)) mask >>= 1; - addr -= mask; - if(size > mask) { - size -= mask; - base += mask; - } - mask >>= 1; + unsigned mask = 1 << 23; + while(addr >= size) { + while(!(addr & mask)) mask >>= 1; + addr -= mask; + if(size > mask) { + size -= mask; + base += mask; } - base += addr; + mask >>= 1; } - return base; + return base + addr; } unsigned Bus::reduce(unsigned addr, unsigned mask) { - unsigned result = 0, length = 0; - for(unsigned n = 0; n < 24; n++) { - unsigned bit = 1 << n; - if(mask & bit) continue; - result |= (bool)(addr & bit) << length++; + while(mask) { + unsigned bits = (mask & -mask) - 1; + addr = ((addr >> 1) & ~bits) | (addr & bits); + mask = (mask & (mask - 1)) >> 1; } - return result; + return addr; } uint8 Bus::read(unsigned addr) { diff --git a/sfc/sfc.hpp b/sfc/sfc.hpp index 8d99946f..a9d4b516 100644 --- a/sfc/sfc.hpp +++ b/sfc/sfc.hpp @@ -12,7 +12,7 @@ namespace SuperFamicom { namespace Info { static const char Name[] = "bsnes"; - static const unsigned SerializerVersion = 27; + static const unsigned SerializerVersion = 28; } } diff --git a/target-ethos/Makefile b/target-ethos/Makefile index 8ed9cc76..ee3b6284 100644 --- a/target-ethos/Makefile +++ b/target-ethos/Makefile @@ -54,10 +54,10 @@ obj/ui-general.o: $(ui)/general/general.cpp $(call rwildcard,$(ui)/) obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/) obj/ui-tools.o: $(ui)/tools/tools.cpp $(call rwildcard,$(ui)/) -obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*) +obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/) $(compiler) $(rubyflags) -c $< -o $@ -obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*) +obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/) $(compiler) $(phoenixflags) -c $< -o $@ obj/resource.o: $(ui)/resource.rc @@ -99,7 +99,6 @@ else sudo install -D -m 755 out/$(name) $(DESTDIR)$(prefix)/bin/$(name) sudo install -D -m 644 data/$(name).png $(DESTDIR)$(prefix)/share/pixmaps/$(name).png sudo install -D -m 644 data/$(name).desktop $(DESTDIR)$(prefix)/share/applications/$(name).desktop - sudo mkdir -p /usr/share/$(name) sudo cp -R profile/* /usr/share/$(name) sudo cp data/cheats.bml /usr/share/$(name)/cheats.bml diff --git a/target-ethos/utility/utility.cpp b/target-ethos/utility/utility.cpp index a848f5db..a96a4245 100644 --- a/target-ethos/utility/utility.cpp +++ b/target-ethos/utility/utility.cpp @@ -89,7 +89,7 @@ void Utility::load() { presentation->setTitle(system().title()); cheatEditor->load({pathname[0], "cheats.bml"}); - stateManager->load({pathname[0], "bsnes/states.bsa"}, 1); + stateManager->load({pathname[0], "higan/states.bsa"}, 1); synchronizeDSP(); @@ -104,7 +104,7 @@ void Utility::unload() { if(tracerEnable) tracerToggle(); cheatEditor->save({pathname[0], "cheats.bml"}); - stateManager->save({pathname[0], "bsnes/states.bsa"}, 1); + stateManager->save({pathname[0], "higan/states.bsa"}, 1); system().unload(); path.reset(); @@ -125,14 +125,14 @@ void Utility::saveState(unsigned slot) { if(program->active == nullptr) return; serializer s = system().serialize(); if(s.size() == 0) return; - directory::create({pathname[0], "bsnes/"}); - if(file::write({pathname[0], "bsnes/state-", slot, ".bsa"}, s.data(), s.size()) == false); + directory::create({pathname[0], "higan/"}); + if(file::write({pathname[0], "higan/state-", slot, ".bsa"}, s.data(), s.size()) == false); showMessage({"Saved to slot ", slot}); } void Utility::loadState(unsigned slot) { if(program->active == nullptr) return; - auto memory = file::read({pathname[0], "bsnes/state-", slot, ".bsa"}); + auto memory = file::read({pathname[0], "higan/state-", slot, ".bsa"}); if(memory.size() == 0) return showMessage({"Unable to locate slot ", slot, " state"}); serializer s(memory.data(), memory.size()); if(system().unserialize(s) == false) return showMessage({"Slot ", slot, " state incompatible"}); diff --git a/target-loki/Makefile b/target-loki/Makefile new file mode 100644 index 00000000..6f35abda --- /dev/null +++ b/target-loki/Makefile @@ -0,0 +1,65 @@ +name := loki + +processors := arm gsu hg51b lr35902 r65816 spc700 upd96050 +include processor/Makefile + +include sfc/Makefile +include gb/Makefile + +ui_objects := ui-loki +ui_objects += phoenix +ui_objects += $(if $(call streq,$(platform),windows),resource) + +include phoenix/Makefile +link += $(phoenixlink) + +objects := $(ui_objects) $(objects) +objects := $(patsubst %,obj/%.o,$(objects)) + +obj/ui-loki.o: $(ui)/loki.cpp $(call rwildcard,$(ui)/) + +obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/) + $(compiler) $(phoenixflags) -c $< -o $@ + +obj/resource.o: $(ui)/resource.rc +ifeq ($(arch),win32) + windres --target=pe-i386 $(ui)/resource.rc obj/resource.o +else + windres $(ui)/resource.rc obj/resource.o +endif + +build: $(objects) +ifeq ($(platform),windows) + $(strip $(compiler) -shared -o out/phoenix.dll obj/phoenix.o $(phoenixlink)) + $(strip $(compiler) -o out/$(name) $(subst obj/phoenix.o,,$(objects)) $(link) -Lout -lphoenix) +else ifeq ($(platform),macosx) + if [ -d out/$(name).app ]; then rm -r out/$(name).app; fi + mkdir out/$(name).app + mkdir out/$(name).app/Contents + mkdir out/$(name).app/Contents/MacOS + mkdir out/$(name).app/Contents/Resources + cp data/Info.plist out/$(name).app/Contents/Info.plist + $(strip $(compiler) -o out/$(name).app/Contents/MacOS/$(name) $(objects) $(link)) +else + $(strip $(compiler) -o out/$(name) $(objects) $(link)) +endif + +install: +ifeq ($(platform),windows) +else ifeq ($(platform),macosx) + sudo mkdir -p /Library/Application\ Support/$(name) + sudo cp -R profile/* /Library/Application\ Support/$(name) + sudo chmod -R 777 /Library/Application\ Support/$(name) +else + sudo install -D -m 755 out/$(name) $(DESTDIR)$(prefix)/bin/$(name) + sudo mkdir -p /usr/share/$(name) + sudo cp -R profile/* /usr/share/$(name) + sudo chmod -R 777 /usr/share/$(name) +endif + +uninstall: +ifeq ($(platform),windows) +else ifeq ($(platform),macosx) +else + sudo rm $(DESTDIR)$(prefix)/bin/$(name) +endif diff --git a/target-loki/loki.cpp b/target-loki/loki.cpp new file mode 100644 index 00000000..ead8e8c3 --- /dev/null +++ b/target-loki/loki.cpp @@ -0,0 +1,38 @@ +#include "loki.hpp" + +Program* program = nullptr; +DSP dspaudio; + +string Program::path(string name) { + string path = {basepath, name}; + if(file::exists(path) || directory::exists(path)) return path; + path = {userpath, name}; + if(file::exists(path) || directory::exists(path)) return path; + path = {sharedpath, name}; + if(file::exists(path) || directory::exists(path)) return path; + return {userpath, name}; +} + +void Program::main() { +} + +Program::Program(int argc, char** argv) { + program = this; + + basepath = nall::programpath(); + userpath = {nall::configpath(), "loki/"}; + sharedpath = {nall::sharedpath(), "loki/"}; + directory::create(userpath); +} + +int main(int argc, char** argv) { + #if defined(PLATFORM_WINDOWS) + utf8_args(argc, argv); + #endif + + Application::setName("loki"); + new Program(argc, argv); + delete program; + + return 0; +} diff --git a/target-loki/loki.hpp b/target-loki/loki.hpp new file mode 100644 index 00000000..3daeba13 --- /dev/null +++ b/target-loki/loki.hpp @@ -0,0 +1,29 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace nall; + +#include +using namespace phoenix; + +struct Program { + string basepath; + string userpath; + string sharedpath; + + string path(string name); + void main(); + Program(int argc, char** argv); +}; + +extern Program* program; +extern DSP dspaudio;