mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-01-17 20:58:28 +01:00
4d193d7d94
byuu says: Warning: this is not for the faint of heart. This is a very early, unpolished, buggy release. But help testing/fixing bugs would be greatly appreciated for anyone willing. Requirements: - Mac OS X 10.7+ - Xcode 7.2+ Installation Commands: cd higan gmake -j 4 gmake install cd ../icarus gmake -j 4 gmake install (gmake install is absolutely required, sorry. You'll be missing key files in key places if you don't run it, and nothing will work.) (gmake uninstall also exists, or you can just delete the .app bundles from your Applications folder, and the Dev folder on your desktop.) If you want to use the GBA emulation, then you need to drop the GBA BIOS into ~/Emulation/System/Game\ Boy\ Advance.sys\bios.rom Usage: You'll now find higan.app and icarus.app in your Applications folders. First, run icarus.app, navigate to where you keep your game ROMs. Now click the settings button at the bottom right, and check "Create Manifests", and click OK. (You'll need to do this every time you run icarus because there's some sort of bug on OSX saving the settings.) Now click "Import", and let it bring in your games into ~/Emulation. Note: "Create Manifests" is required. I don't yet have a pipe implementation on OS X for higan to invoke icarus yet. If you don't check this box, it won't create manifest.bml files, and your games won't run at all. Now you can run higan.app. The first thing you'll want to do is go to higan->Preferences... and assign inputs for your gamepads. At the very least, do it for the default controller for all the systems you want to emulate. Now this is very important ... close the application at this point so that it writes your config file to disk. There's a serious crashing bug, and if you trigger it, you'll lose your input bindings. Now the really annoying part ... go to Library->{System} and pick the game you want to play. Right now, there's a ~50% chance the application will bomb. It seems the hiro::pListView object is getting destroyed, yet somehow the internal Cocoa callbacks are being triggered anyway. I don't know how this is possible, and my attempts to debug with lldb have been a failure :( If you're unlucky, the application will crash. Restart and try again. If it crashes every single time, then you can try launching your game from the command-line instead. Example: open /Applications/higan.app \ --args ~/Emulation/Super\ Famicom/Zelda3.sfc/ Help wanted: I could really, really, really use some help with that crashing on game loading. There's a lot of rough edges, but they're all cosmetic. This one thing is pretty much the only major show-stopping issue at the moment, preventing a wider general audience pre-compiled binary preview.
542 lines
9.8 KiB
C++
542 lines
9.8 KiB
C++
#ifdef _WIN32
|
|
#include <initguid.h>
|
|
#include <cguid.h>
|
|
#endif
|
|
|
|
#include <ruby/ruby.hpp>
|
|
using namespace nall;
|
|
using namespace ruby;
|
|
|
|
/* Shared */
|
|
|
|
#undef deprecated
|
|
#undef mkdir
|
|
#undef usleep
|
|
|
|
#if defined(DISPLAY_XORG)
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <X11/Xatom.h>
|
|
#elif defined(DISPLAY_QUARTZ)
|
|
#define Boolean CocoaBoolean
|
|
#define decimal CocoaDecimal
|
|
#include <Cocoa/Cocoa.h>
|
|
#include <Carbon/Carbon.h>
|
|
#undef Boolean
|
|
#undef decimal
|
|
#elif defined(DISPLAY_WINDOWS)
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
/* Video */
|
|
|
|
#if defined(VIDEO_CGL)
|
|
#include <ruby/video/cgl.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_DIRECT3D)
|
|
#include <ruby/video/direct3d.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_DIRECTDRAW)
|
|
#include <ruby/video/directdraw.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_GDI)
|
|
#include <ruby/video/gdi.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_GLX)
|
|
#include <ruby/video/glx.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_GLX2)
|
|
#include <ruby/video/glx2.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_SDL)
|
|
#include <ruby/video/sdl.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_WGL)
|
|
#include <ruby/video/wgl.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_XSHM)
|
|
#include <ruby/video/xshm.cpp>
|
|
#endif
|
|
|
|
#if defined(VIDEO_XV)
|
|
#include <ruby/video/xv.cpp>
|
|
#endif
|
|
|
|
namespace ruby {
|
|
|
|
const string Video::Handle = "Handle";
|
|
const string Video::Synchronize = "Synchronize";
|
|
const string Video::Depth = "Depth";
|
|
const string Video::Filter = "Filter";
|
|
const string Video::Shader = "Shader";
|
|
|
|
const unsigned Video::FilterNearest = 0;
|
|
const unsigned Video::FilterLinear = 1;
|
|
|
|
auto Video::create(const string& driver) -> Video* {
|
|
if(!driver) return create(optimalDriver());
|
|
|
|
#if defined(VIDEO_CGL)
|
|
if(driver == "OpenGL") return new VideoCGL;
|
|
#endif
|
|
|
|
#if defined(VIDEO_DIRECT3D)
|
|
if(driver == "Direct3D") return new VideoD3D;
|
|
#endif
|
|
|
|
#if defined(VIDEO_DIRECTDRAW)
|
|
if(driver == "DirectDraw") return new VideoDD;
|
|
#endif
|
|
|
|
#if defined(VIDEO_GDI)
|
|
if(driver == "GDI") return new VideoGDI;
|
|
#endif
|
|
|
|
#if defined(VIDEO_GLX)
|
|
if(driver == "OpenGL") return new VideoGLX;
|
|
#endif
|
|
|
|
#if defined(VIDEO_GLX2)
|
|
if(driver == "OpenGL2") return new VideoGLX2;
|
|
#endif
|
|
|
|
#if defined(VIDEO_SDL)
|
|
if(driver == "SDL") return new VideoSDL;
|
|
#endif
|
|
|
|
#if defined(VIDEO_WGL)
|
|
if(driver == "OpenGL") return new VideoWGL;
|
|
#endif
|
|
|
|
#if defined(VIDEO_XSHM)
|
|
if(driver == "XShm") return new VideoXShm;
|
|
#endif
|
|
|
|
#if defined(VIDEO_XV)
|
|
if(driver == "X-Video") return new VideoXv;
|
|
#endif
|
|
|
|
return new Video;
|
|
}
|
|
|
|
auto Video::optimalDriver() -> string {
|
|
#if defined(VIDEO_WGL)
|
|
return "OpenGL";
|
|
#elif defined(VIDEO_DIRECT3D)
|
|
return "Direct3D";
|
|
#elif defined(VIDEO_DIRECTDRAW)
|
|
return "DirectDraw";
|
|
#elif defined(VIDEO_GDI)
|
|
return "GDI";
|
|
#elif defined(VIDEO_CGL)
|
|
return "OpenGL";
|
|
#elif defined(VIDEO_GLX)
|
|
return "OpenGL";
|
|
#elif defined(VIDEO_GLX2)
|
|
return "OpenGL2";
|
|
#elif defined(VIDEO_XV)
|
|
return "X-Video";
|
|
#elif defined(VIDEO_XSHM)
|
|
return "XShm";
|
|
#elif defined(VIDEO_SDL)
|
|
return "SDL";
|
|
#else
|
|
return "None";
|
|
#endif
|
|
}
|
|
|
|
auto Video::safestDriver() -> string {
|
|
#if defined(VIDEO_DIRECT3D)
|
|
return "Direct3D";
|
|
#elif defined(VIDEO_WGL)
|
|
return "OpenGL";
|
|
#elif defined(VIDEO_DIRECTDRAW)
|
|
return "DirectDraw";
|
|
#elif defined(VIDEO_GDI)
|
|
return "GDI";
|
|
#elif defined(VIDEO_CGL)
|
|
return "OpenGL";
|
|
#elif defined(VIDEO_XSHM)
|
|
return "XShm";
|
|
#elif defined(VIDEO_SDL)
|
|
return "SDL";
|
|
#elif defined(VIDEO_XV)
|
|
return "X-Video";
|
|
#elif defined(VIDEO_GLX2)
|
|
return "OpenGL2";
|
|
#elif defined(VIDEO_GLX)
|
|
return "OpenGL";
|
|
#else
|
|
return "None";
|
|
#endif
|
|
}
|
|
|
|
auto Video::availableDrivers() -> lstring {
|
|
return {
|
|
|
|
#if defined(VIDEO_WGL)
|
|
"OpenGL",
|
|
#endif
|
|
|
|
#if defined(VIDEO_DIRECT3D)
|
|
"Direct3D",
|
|
#endif
|
|
|
|
#if defined(VIDEO_DIRECTDRAW)
|
|
"DirectDraw",
|
|
#endif
|
|
|
|
#if defined(VIDEO_GDI)
|
|
"GDI",
|
|
#endif
|
|
|
|
#if defined(VIDEO_CGL)
|
|
"OpenGL",
|
|
#endif
|
|
|
|
#if defined(VIDEO_GLX)
|
|
"OpenGL",
|
|
#endif
|
|
|
|
#if defined(VIDEO_GLX2)
|
|
"OpenGL2",
|
|
#endif
|
|
|
|
#if defined(VIDEO_XV)
|
|
"X-Video",
|
|
#endif
|
|
|
|
#if defined(VIDEO_XSHM)
|
|
"XShm",
|
|
#endif
|
|
|
|
#if defined(VIDEO_SDL)
|
|
"SDL",
|
|
#endif
|
|
|
|
"None"};
|
|
}
|
|
|
|
}
|
|
|
|
/* Audio */
|
|
|
|
#if defined(AUDIO_ALSA)
|
|
#include <ruby/audio/alsa.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_AO)
|
|
#include <ruby/audio/ao.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_DIRECTSOUND)
|
|
#include <ruby/audio/directsound.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_OPENAL)
|
|
#include <ruby/audio/openal.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_OSS)
|
|
#include <ruby/audio/oss.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_PULSEAUDIO)
|
|
#include <ruby/audio/pulseaudio.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_PULSEAUDIOSIMPLE)
|
|
#include <ruby/audio/pulseaudiosimple.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_WASAPI)
|
|
#include <ruby/audio/wasapi.cpp>
|
|
#endif
|
|
|
|
#if defined(AUDIO_XAUDIO2)
|
|
#include <ruby/audio/xaudio2.cpp>
|
|
#endif
|
|
|
|
namespace ruby {
|
|
|
|
const string Audio::Device = "Device";
|
|
const string Audio::Exclusive = "Exclusive";
|
|
const string Audio::Handle = "Handle";
|
|
const string Audio::Synchronize = "Synchronize";
|
|
const string Audio::Frequency = "Frequency";
|
|
const string Audio::Latency = "Latency";
|
|
|
|
auto Audio::create(const string& driver) -> Audio* {
|
|
if(!driver) return create(optimalDriver());
|
|
|
|
#if defined(AUDIO_ALSA)
|
|
if(driver == "ALSA") return new AudioALSA;
|
|
#endif
|
|
|
|
#if defined(AUDIO_AO)
|
|
if(driver == "libao") return new AudioAO;
|
|
#endif
|
|
|
|
#if defined(AUDIO_DIRECTSOUND)
|
|
if(driver == "DirectSound") return new AudioDS;
|
|
#endif
|
|
|
|
#if defined(AUDIO_OPENAL)
|
|
if(driver == "OpenAL") return new AudioOpenAL;
|
|
#endif
|
|
|
|
#if defined(AUDIO_OSS)
|
|
if(driver == "OSS") return new AudioOSS;
|
|
#endif
|
|
|
|
#if defined(AUDIO_PULSEAUDIO)
|
|
if(driver == "PulseAudio") return new AudioPulseAudio;
|
|
#endif
|
|
|
|
#if defined(AUDIO_PULSEAUDIOSIMPLE)
|
|
if(driver == "PulseAudioSimple") return new AudioPulseAudioSimple;
|
|
#endif
|
|
|
|
#if defined(AUDIO_WASAPI)
|
|
if(driver == "WASAPI") return new AudioWASAPI;
|
|
#endif
|
|
|
|
#if defined(AUDIO_XAUDIO2)
|
|
if(driver == "XAudio2") return new AudioXAudio2;
|
|
#endif
|
|
|
|
return new Audio;
|
|
}
|
|
|
|
auto Audio::optimalDriver() -> string {
|
|
#if defined(AUDIO_WASAPI)
|
|
return "WASAPI";
|
|
#elif defined(AUDIO_XAUDIO2)
|
|
return "XAudio2";
|
|
#elif defined(AUDIO_DIRECTSOUND)
|
|
return "DirectSound";
|
|
#elif defined(AUDIO_ALSA)
|
|
return "ALSA";
|
|
#elif defined(AUDIO_OSS)
|
|
return "OSS";
|
|
#elif defined(AUDIO_OPENAL)
|
|
return "OpenAL";
|
|
#elif defined(AUDIO_PULSEAUDIO)
|
|
return "PulseAudio";
|
|
#elif defined(AUDIO_PULSEAUDIOSIMPLE)
|
|
return "PulseAudioSimple";
|
|
#elif defined(AUDIO_AO)
|
|
return "libao";
|
|
#else
|
|
return "None";
|
|
#endif
|
|
}
|
|
|
|
auto Audio::safestDriver() -> string {
|
|
#if defined(AUDIO_DIRECTSOUND)
|
|
return "DirectSound";
|
|
#elif defined(AUDIO_WASAPI)
|
|
return "WASAPI";
|
|
#elif defined(AUDIO_XAUDIO2)
|
|
return "XAudio2";
|
|
#elif defined(AUDIO_ALSA)
|
|
return "ALSA";
|
|
#elif defined(AUDIO_OSS)
|
|
return "OSS";
|
|
#elif defined(AUDIO_OPENAL)
|
|
return "OpenAL";
|
|
#elif defined(AUDIO_PULSEAUDIO)
|
|
return "PulseAudio";
|
|
#elif defined(AUDIO_PULSEAUDIOSIMPLE)
|
|
return "PulseAudioSimple";
|
|
#elif defined(AUDIO_AO)
|
|
return "libao";
|
|
#else
|
|
return "None";
|
|
#endif
|
|
}
|
|
|
|
auto Audio::availableDrivers() -> lstring {
|
|
return {
|
|
|
|
#if defined(AUDIO_WASAPI)
|
|
"WASAPI",
|
|
#endif
|
|
|
|
#if defined(AUDIO_XAUDIO2)
|
|
"XAudio2",
|
|
#endif
|
|
|
|
#if defined(AUDIO_DIRECTSOUND)
|
|
"DirectSound",
|
|
#endif
|
|
|
|
#if defined(AUDIO_ALSA)
|
|
"ALSA",
|
|
#endif
|
|
|
|
#if defined(AUDIO_OSS)
|
|
"OSS",
|
|
#endif
|
|
|
|
#if defined(AUDIO_OPENAL)
|
|
"OpenAL",
|
|
#endif
|
|
|
|
#if defined(AUDIO_PULSEAUDIO)
|
|
"PulseAudio",
|
|
#endif
|
|
|
|
#if defined(AUDIO_PULSEAUDIOSIMPLE)
|
|
"PulseAudioSimple",
|
|
#endif
|
|
|
|
#if defined(AUDIO_AO)
|
|
"libao",
|
|
#endif
|
|
|
|
"None"};
|
|
}
|
|
|
|
}
|
|
|
|
/* Input */
|
|
|
|
#if defined(INPUT_CARBON)
|
|
#include <ruby/input/carbon.cpp>
|
|
#endif
|
|
|
|
#if defined(INPUT_QUARTZ)
|
|
#include <ruby/input/quartz.cpp>
|
|
#endif
|
|
|
|
#if defined(INPUT_SDL)
|
|
#include <ruby/input/sdl.cpp>
|
|
#endif
|
|
|
|
#if defined(INPUT_UDEV)
|
|
#include <ruby/input/udev.cpp>
|
|
#endif
|
|
|
|
#if defined(INPUT_WINDOWS)
|
|
#include <ruby/input/windows.cpp>
|
|
#endif
|
|
|
|
#if defined(INPUT_XLIB)
|
|
#include <ruby/input/xlib.cpp>
|
|
#endif
|
|
|
|
namespace ruby {
|
|
|
|
const string Input::Handle = "Handle";
|
|
const string Input::KeyboardSupport = "KeyboardSupport";
|
|
const string Input::MouseSupport = "MouseSupport";
|
|
const string Input::JoypadSupport = "JoypadSupport";
|
|
const string Input::JoypadRumbleSupport = "JoypadRumbleSupport";
|
|
|
|
auto Input::create(const string& driver) -> Input* {
|
|
if(!driver) return create(optimalDriver());
|
|
|
|
#if defined(INPUT_WINDOWS)
|
|
if(driver == "Windows") return new InputWindows;
|
|
#endif
|
|
|
|
#if defined(INPUT_QUARTZ)
|
|
if(driver == "Quartz") return new InputQuartz;
|
|
#endif
|
|
|
|
#if defined(INPUT_CARBON)
|
|
if(driver == "Carbon") return new InputCarbon;
|
|
#endif
|
|
|
|
#if defined(INPUT_UDEV)
|
|
if(driver == "udev") return new InputUdev;
|
|
#endif
|
|
|
|
#if defined(INPUT_SDL)
|
|
if(driver == "SDL") return new InputSDL;
|
|
#endif
|
|
|
|
#if defined(INPUT_XLIB)
|
|
if(driver == "Xlib") return new InputXlib;
|
|
#endif
|
|
|
|
return new Input;
|
|
}
|
|
|
|
auto Input::optimalDriver() -> string {
|
|
#if defined(INPUT_WINDOWS)
|
|
return "Windows";
|
|
#elif defined(INPUT_QUARTZ)
|
|
return "Quartz";
|
|
#elif defined(INPUT_CARBON)
|
|
return "Carbon";
|
|
#elif defined(INPUT_UDEV)
|
|
return "udev";
|
|
#elif defined(INPUT_SDL)
|
|
return "SDL";
|
|
#elif defined(INPUT_XLIB)
|
|
return "Xlib";
|
|
#else
|
|
return "None";
|
|
#endif
|
|
}
|
|
|
|
auto Input::safestDriver() -> string {
|
|
#if defined(INPUT_WINDOWS)
|
|
return "Windows";
|
|
#elif defined(INPUT_QUARTZ)
|
|
return "Quartz";
|
|
#elif defined(INPUT_CARBON)
|
|
return "Carbon";
|
|
#elif defined(INPUT_UDEV)
|
|
return "udev";
|
|
#elif defined(INPUT_SDL)
|
|
return "SDL";
|
|
#elif defined(INPUT_XLIB)
|
|
return "Xlib";
|
|
#else
|
|
return "none";
|
|
#endif
|
|
}
|
|
|
|
auto Input::availableDrivers() -> lstring {
|
|
return {
|
|
|
|
#if defined(INPUT_WINDOWS)
|
|
"Windows",
|
|
#endif
|
|
|
|
#if defined(INPUT_QUARTZ)
|
|
"Quartz",
|
|
#endif
|
|
|
|
#if defined(INPUT_CARBON)
|
|
"Carbon",
|
|
#endif
|
|
|
|
#if defined(INPUT_UDEV)
|
|
"udev",
|
|
#endif
|
|
|
|
#if defined(INPUT_SDL)
|
|
"SDL",
|
|
#endif
|
|
|
|
#if defined(INPUT_XLIB)
|
|
"Xlib",
|
|
#endif
|
|
|
|
"None"};
|
|
}
|
|
|
|
}
|