From 2292cf332c989bf374377b61719beead0706b989 Mon Sep 17 00:00:00 2001 From: arbee Date: Sun, 15 Sep 2019 20:00:59 -0400 Subject: Preliminary Mac native OSD. Not working yet. [R. Belmont] This will compile, link, and run a driver all the way to the first info screen, provided you use -video bgfx. However, although there's a valid NSWindow created, it never actually appears on screen for unknown (but likely silly) reasons. Inputs are not implemented and fullscreen exists but is untried. --- scripts/build/verinfo.py | 2 + scripts/src/osd/mac.lua | 175 +++++++ scripts/src/osd/mac_cfg.lua | 31 ++ scripts/src/osd/modules.lua | 2 + src/osd/mac/appdelegate.h | 15 + src/osd/mac/appdelegate.mm | 54 ++ src/osd/mac/macmain.cpp | 271 ++++++++++ src/osd/mac/main.mm | 19 + src/osd/mac/mamefswindow.h | 15 + src/osd/mac/mamefswindow.mm | 41 ++ src/osd/mac/oglview.h | 19 + src/osd/mac/oglview.mm | 106 ++++ src/osd/mac/osdmac.h | 86 ++++ src/osd/mac/video.cpp | 316 ++++++++++++ src/osd/mac/window.cpp | 970 ++++++++++++++++++++++++++++++++++++ src/osd/mac/window.h | 134 +++++ src/osd/mac/windowcontroller.h | 16 + src/osd/mac/windowcontroller.mm | 121 +++++ src/osd/modules/opengl/osd_opengl.h | 3 + src/osd/modules/render/drawbgfx.cpp | 21 + src/osd/modules/render/drawogl.cpp | 15 +- src/osd/modules/render/drawogl.h | 5 + 22 files changed, 2433 insertions(+), 4 deletions(-) create mode 100644 scripts/src/osd/mac.lua create mode 100644 scripts/src/osd/mac_cfg.lua create mode 100644 src/osd/mac/appdelegate.h create mode 100644 src/osd/mac/appdelegate.mm create mode 100644 src/osd/mac/macmain.cpp create mode 100644 src/osd/mac/main.mm create mode 100644 src/osd/mac/mamefswindow.h create mode 100644 src/osd/mac/mamefswindow.mm create mode 100644 src/osd/mac/oglview.h create mode 100644 src/osd/mac/oglview.mm create mode 100644 src/osd/mac/osdmac.h create mode 100644 src/osd/mac/video.cpp create mode 100644 src/osd/mac/window.cpp create mode 100644 src/osd/mac/window.h create mode 100644 src/osd/mac/windowcontroller.h create mode 100644 src/osd/mac/windowcontroller.mm diff --git a/scripts/build/verinfo.py b/scripts/build/verinfo.py index 51bf4f25d63..f89956d1a53 100644 --- a/scripts/build/verinfo.py +++ b/scripts/build/verinfo.py @@ -165,6 +165,8 @@ elif outfmt == 'plist': fp.write('\t%s\n' % product_name) fp.write('\tCFBundleShortVersionString\n') fp.write('\t%s.%s.%s\n' % (version_major, version_minor, version_build)) + fp.write('\tNSPrincipalClass\n') + fp.write('\tNSApplication\n') fp.write('\n') fp.write('\n') fp.flush() diff --git a/scripts/src/osd/mac.lua b/scripts/src/osd/mac.lua new file mode 100644 index 00000000000..5a732cbc825 --- /dev/null +++ b/scripts/src/osd/mac.lua @@ -0,0 +1,175 @@ +-- license:BSD-3-Clause +-- copyright-holders:MAMEdev Team + +--------------------------------------------------------------------------- +-- +-- mac.lua +-- +-- Rules for the building with SDL +-- +--------------------------------------------------------------------------- + +dofile("modules.lua") + + +function maintargetosdoptions(_target,_subtarget) + osdmodulestargetconf() + + configuration { } +end + +BASE_TARGETOS = "unix" + +local os_version = str_to_version(backtick("sw_vers -productVersion")) +links { + "Cocoa.framework", +} +linkoptions { + "-framework QuartzCore", + "-framework OpenGL", +} +if os_version>=101100 then + linkoptions { + "-weak_framework Metal", + } +end + +project ("qtdbg_" .. _OPTIONS["osd"]) + uuid (os.uuid("qtdbg_" .. _OPTIONS["osd"])) + kind (LIBTYPE) + + dofile("mac_cfg.lua") + includedirs { + MAME_DIR .. "src/emu", + MAME_DIR .. "src/devices", -- accessing imagedev from debugger + MAME_DIR .. "src/osd", + MAME_DIR .. "src/lib", + MAME_DIR .. "src/lib/util", + MAME_DIR .. "src/osd/modules/render", + MAME_DIR .. "3rdparty", + } + configuration { "linux-* or freebsd" } + buildoptions { + "-fPIC", + } + configuration { } + + qtdebuggerbuild() + +project ("osd_" .. _OPTIONS["osd"]) + targetsubdir(_OPTIONS["target"] .."_" .._OPTIONS["subtarget"]) + uuid (os.uuid("osd_" .. _OPTIONS["osd"])) + kind (LIBTYPE) + + dofile("mac_cfg.lua") + osdmodulesbuild() + + includedirs { + MAME_DIR .. "src/emu", + MAME_DIR .. "src/devices", -- accessing imagedev from debugger + MAME_DIR .. "src/osd", + MAME_DIR .. "src/lib", + MAME_DIR .. "src/lib/util", + MAME_DIR .. "src/osd/modules/file", + MAME_DIR .. "src/osd/modules/render", + MAME_DIR .. "3rdparty", + MAME_DIR .. "src/osd/mac", + } + + files { + MAME_DIR .. "src/osd/modules/debugger/debugosx.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/breakpointsview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/breakpointsview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/consoleview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/consoleview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/debugcommandhistory.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/debugcommandhistory.h", + MAME_DIR .. "src/osd/modules/debugger/osx/debugconsole.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/debugconsole.h", + MAME_DIR .. "src/osd/modules/debugger/osx/debugview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/debugview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/debugwindowhandler.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/debugwindowhandler.h", + MAME_DIR .. "src/osd/modules/debugger/osx/deviceinfoviewer.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/deviceinfoviewer.h", + MAME_DIR .. "src/osd/modules/debugger/osx/devicesviewer.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/devicesviewer.h", + MAME_DIR .. "src/osd/modules/debugger/osx/disassemblyview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/disassemblyviewer.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/disassemblyviewer.h", + MAME_DIR .. "src/osd/modules/debugger/osx/errorlogview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/errorlogview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/disassemblyview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/errorlogviewer.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/errorlogviewer.h", + MAME_DIR .. "src/osd/modules/debugger/osx/memoryview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/memoryview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/memoryviewer.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/memoryviewer.h", + MAME_DIR .. "src/osd/modules/debugger/osx/pointsviewer.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/pointsviewer.h", + MAME_DIR .. "src/osd/modules/debugger/osx/registersview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/registersview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/watchpointsview.mm", + MAME_DIR .. "src/osd/modules/debugger/osx/watchpointsview.h", + MAME_DIR .. "src/osd/modules/debugger/osx/debugosx.h", + } + + files { + MAME_DIR .. "src/osd/mac/main.mm", + MAME_DIR .. "src/osd/mac/macmain.cpp", + MAME_DIR .. "src/osd/mac/appdelegate.mm", + MAME_DIR .. "src/osd/mac/appdelegate.h", + MAME_DIR .. "src/osd/mac/video.cpp", + MAME_DIR .. "src/osd/mac/window.cpp", + MAME_DIR .. "src/osd/mac/window.h", + MAME_DIR .. "src/osd/mac/windowcontroller.mm", + MAME_DIR .. "src/osd/mac/windowcontroller.h", + MAME_DIR .. "src/osd/mac/mamefswindow.mm", + MAME_DIR .. "src/osd/mac/mamefswindow.h", + MAME_DIR .. "src/osd/mac/oglview.mm", + MAME_DIR .. "src/osd/mac/oglview.h", + MAME_DIR .. "src/osd/modules/osdwindow.cpp", + MAME_DIR .. "src/osd/modules/osdwindow.h", + } + + +project ("ocore_" .. _OPTIONS["osd"]) + targetsubdir(_OPTIONS["target"] .."_" .. _OPTIONS["subtarget"]) + uuid (os.uuid("ocore_" .. _OPTIONS["osd"])) + kind (LIBTYPE) + + removeflags { + "SingleOutputDir", + } + + dofile("mac_cfg.lua") + + includedirs { + MAME_DIR .. "src/emu", + MAME_DIR .. "src/osd", + MAME_DIR .. "src/lib", + MAME_DIR .. "src/lib/util", + MAME_DIR .. "src/osd/mac", + } + + files { + MAME_DIR .. "src/osd/osdcore.cpp", + MAME_DIR .. "src/osd/osdcore.h", + MAME_DIR .. "src/osd/strconv.cpp", + MAME_DIR .. "src/osd/strconv.h", + MAME_DIR .. "src/osd/osdsync.cpp", + MAME_DIR .. "src/osd/osdsync.h", + MAME_DIR .. "src/osd/modules/osdmodule.cpp", + MAME_DIR .. "src/osd/modules/osdmodule.h", + MAME_DIR .. "src/osd/modules/lib/osdlib_macosx.cpp", + MAME_DIR .. "src/osd/modules/lib/osdlib.h", + MAME_DIR .. "src/osd/modules/file/posixdir.cpp", + MAME_DIR .. "src/osd/modules/file/posixdomain.cpp", + MAME_DIR .. "src/osd/modules/file/posixfile.cpp", + MAME_DIR .. "src/osd/modules/file/posixfile.h", + MAME_DIR .. "src/osd/modules/file/posixptty.cpp", + MAME_DIR .. "src/osd/modules/file/posixsocket.cpp", + } + + diff --git a/scripts/src/osd/mac_cfg.lua b/scripts/src/osd/mac_cfg.lua new file mode 100644 index 00000000000..f16763089ee --- /dev/null +++ b/scripts/src/osd/mac_cfg.lua @@ -0,0 +1,31 @@ +-- license:BSD-3-Clause +-- copyright-holders:MAMEdev Team + +dofile('modules.lua') + +forcedincludes { +-- MAME_DIR .. "src/osd/sdl/sdlprefix.h" +} + +if not _OPTIONS["DONT_USE_NETWORK"] then + defines { + "USE_NETWORK", + "OSD_NET_USE_PCAP", + } +end + +defines { + "OSD_MAC", + "SDLMAME_UNIX", + "SDLMAME_MACOSX", + "SDLMAME_DARWIN" +} + +configuration { "osx*" } + includedirs { + MAME_DIR .. "3rdparty/bx/include/compat/osx", + } + + +configuration { } + diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua index ed4b53e8a5f..4675139f87a 100644 --- a/scripts/src/osd/modules.lua +++ b/scripts/src/osd/modules.lua @@ -104,6 +104,7 @@ function osdmodulesbuild() MAME_DIR .. "src/osd/modules/input/input_xinput.h", MAME_DIR .. "src/osd/modules/input/input_winhybrid.cpp", MAME_DIR .. "src/osd/modules/input/input_uwp.cpp", + MAME_DIR .. "src/osd/modules/input/input_mac.cpp", MAME_DIR .. "src/osd/modules/output/output_module.h", MAME_DIR .. "src/osd/modules/output/none.cpp", MAME_DIR .. "src/osd/modules/output/console.cpp", @@ -115,6 +116,7 @@ function osdmodulesbuild() MAME_DIR .. "src/osd/modules/monitor/monitor_win32.cpp", MAME_DIR .. "src/osd/modules/monitor/monitor_dxgi.cpp", MAME_DIR .. "src/osd/modules/monitor/monitor_sdl.cpp", + MAME_DIR .. "src/osd/modules/monitor/monitor_mac.cpp", } includedirs { ext_includedir("asio"), diff --git a/src/osd/mac/appdelegate.h b/src/osd/mac/appdelegate.h new file mode 100644 index 00000000000..31daea1240a --- /dev/null +++ b/src/osd/mac/appdelegate.h @@ -0,0 +1,15 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// appdelegate.h - Cocoa app delegate +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import + +@interface MAMEAppDelegate : NSObject + +@end diff --git a/src/osd/mac/appdelegate.mm b/src/osd/mac/appdelegate.mm new file mode 100644 index 00000000000..4207f515beb --- /dev/null +++ b/src/osd/mac/appdelegate.mm @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// appdelegate.mm - Cocoa app delegate +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import "appdelegate.h" + +extern int mac_run_emulator(); + +@interface MAMEThread : NSThread +@end + +@implementation MAMEThread +- (void)main +{ + mac_run_emulator(); +} +@end + +@interface MAMEAppDelegate () +@end + +@implementation MAMEAppDelegate +MAMEThread *appThread; + +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + // run MAME on a thread so event dispatching happens normally + appThread = [[MAMEThread alloc] init]; + [appThread start]; +} + +- (void)applicationWillTerminate:(NSNotification *)notification +{ +} + +- (void)applicationDidBecomeActive:(NSNotification *)notification +{ +} + +- (void)applicationDidResignActive:(NSNotification *)notification +{ +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSNotification *)notification +{ + return NSTerminateNow; +} +@end diff --git a/src/osd/mac/macmain.cpp b/src/osd/mac/macmain.cpp new file mode 100644 index 00000000000..8e50361a2b1 --- /dev/null +++ b/src/osd/mac/macmain.cpp @@ -0,0 +1,271 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// macmain.cpp - C++ side main file for MAME on the Mac +// +// Mac OSD by R. Belmont +// +//============================================================ + +// oslog callback +#include + +#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#include +#include +#include + +// MAME headers +#include "osdepend.h" +#include "emu.h" +#include "emuopts.h" +#include "strconv.h" + +// OSD headers +#include "video.h" +#include "osdmac.h" +#include "modules/lib/osdlib.h" +#include "modules/diagnostics/diagnostics_module.h" + +//============================================================ +// OPTIONS +//============================================================ + +#ifndef INI_PATH +#define INI_PATH "$HOME/Library/Application Support/APP_NAME;$HOME/.APP_NAME;.;ini" +#endif // INI_PATH + +//============================================================ +// Local variables +//============================================================ + +const options_entry mac_options::s_option_entries[] = +{ + { MACOPTION_INIPATH, INI_PATH, OPTION_STRING, "path to ini files" }, + + // End of list + { nullptr } +}; + +//============================================================ +// mac_options +//============================================================ + +mac_options::mac_options() +: osd_options() +{ + std::string ini_path(INI_PATH); + add_entries(mac_options::s_option_entries); + strreplace(ini_path,"APP_NAME", emulator_info::get_appname_lower()); + set_default_value(MACOPTION_INIPATH, ini_path.c_str()); +} + +//============================================================ +// main +//============================================================ + +// we do some special sauce on Win32... +int mac_run_emulator() +{ + int argc = *_NSGetArgc(); + char **argv = *_NSGetArgv(); + + std::vector args = osd_get_command_line(argc, argv); + int res = 0; + + // disable I/O buffering + setvbuf(stdout, (char *) nullptr, _IONBF, 0); + setvbuf(stderr, (char *) nullptr, _IONBF, 0); + + // Initialize crash diagnostics + diagnostics_module::get_instance()->init_crash_diagnostics(); + + { + mac_options options; + mac_osd_interface osd(options); + osd.register_options(); + res = emulator_info::start_frontend(options, osd, args); + } + + exit(res); +} + +//============================================================ +// constructor +//============================================================ + +mac_osd_interface::mac_osd_interface(mac_options &options) +: osd_common_t(options), m_options(options) +{ +} + + +//============================================================ +// destructor +//============================================================ + +mac_osd_interface::~mac_osd_interface() +{ +} + + +//============================================================ +// osd_exit +//============================================================ + +void mac_osd_interface::osd_exit() +{ + osd_common_t::osd_exit(); +} + +//============================================================ +// defines_verbose +//============================================================ + +#define MAC_EXPAND_STR(_m) #_m +#define MACRO_VERBOSE(_mac) \ + do { \ + if (strcmp(MAC_EXPAND_STR(_mac), #_mac) != 0) \ + osd_printf_verbose("%s=%s ", #_mac, MAC_EXPAND_STR(_mac)); \ + } while (0) + +#define _mac_VER #mac_MAJOR_VERSION "." #mac_MINOR_VERSION "." #mac_PATCHLEVEL + +static void defines_verbose(void) +{ + osd_printf_verbose("Build version: %s\n", emulator_info::get_build_version()); + osd_printf_verbose("Build architecure: "); + MACRO_VERBOSE(SDLMAME_ARCH); + osd_printf_verbose("\n"); + osd_printf_verbose("Build defines 1: "); + MACRO_VERBOSE(SDLMAME_UNIX); + MACRO_VERBOSE(SDLMAME_X11); + MACRO_VERBOSE(SDLMAME_WIN32); + MACRO_VERBOSE(SDLMAME_MACOSX); + MACRO_VERBOSE(SDLMAME_DARWIN); + MACRO_VERBOSE(SDLMAME_LINUX); + MACRO_VERBOSE(SDLMAME_SOLARIS); + MACRO_VERBOSE(SDLMAME_IRIX); + MACRO_VERBOSE(SDLMAME_BSD); + osd_printf_verbose("\n"); + osd_printf_verbose("Build defines 1: "); + MACRO_VERBOSE(LSB_FIRST); + MACRO_VERBOSE(PTR64); + MACRO_VERBOSE(MAME_NOASM); + MACRO_VERBOSE(MAME_DEBUG); + MACRO_VERBOSE(BIGENDIAN); + MACRO_VERBOSE(CPP_COMPILE); + MACRO_VERBOSE(SYNC_IMPLEMENTATION); + osd_printf_verbose("\n"); + osd_printf_verbose("OpenGL defines: "); + MACRO_VERBOSE(USE_OPENGL); + MACRO_VERBOSE(USE_DISPATCH_GL); + osd_printf_verbose("\n"); + osd_printf_verbose("Compiler defines A: "); + MACRO_VERBOSE(__GNUC__); + MACRO_VERBOSE(__GNUC_MINOR__); + MACRO_VERBOSE(__GNUC_PATCHLEVEL__); + MACRO_VERBOSE(__VERSION__); + osd_printf_verbose("\n"); + osd_printf_verbose("Compiler defines B: "); + MACRO_VERBOSE(__amd64__); + MACRO_VERBOSE(__x86_64__); + MACRO_VERBOSE(__unix__); + MACRO_VERBOSE(__i386__); + MACRO_VERBOSE(__ppc__); + MACRO_VERBOSE(__ppc64__); + osd_printf_verbose("\n"); + osd_printf_verbose("Compiler defines C: "); + MACRO_VERBOSE(_FORTIFY_SOURCE); + MACRO_VERBOSE(__USE_FORTIFY_LEVEL); + osd_printf_verbose("\n"); +} + +//============================================================ +// osd_mac_info +//============================================================ + +static void osd_mac_info(void) +{ +} + + +//============================================================ +// video_register +//============================================================ + +void mac_osd_interface::video_register() +{ + video_options_add("opengl", nullptr); + video_options_add("bgfx", nullptr); +} + +//============================================================ +// output_oslog +//============================================================ + +void mac_osd_interface::output_oslog(const char *buffer) +{ + fputs(buffer, stderr); +} + + +//============================================================ +// osd_setup_osd_specific_emu_options +//============================================================ + +void osd_setup_osd_specific_emu_options(emu_options &opts) +{ + opts.add_entries(osd_options::s_option_entries); +} + + +//============================================================ +// init +//============================================================ + +void mac_osd_interface::init(running_machine &machine) +{ + // call our parent + osd_common_t::init(machine); + + const char *stemp; + + // determine if we are benchmarking, and adjust options appropriately + int bench = options().bench(); + if (bench > 0) + { + options().set_value(OPTION_THROTTLE, false, OPTION_PRIORITY_MAXIMUM); + options().set_value(OSDOPTION_SOUND, "none", OPTION_PRIORITY_MAXIMUM); + options().set_value(OSDOPTION_VIDEO, "none", OPTION_PRIORITY_MAXIMUM); + options().set_value(OPTION_SECONDS_TO_RUN, bench, OPTION_PRIORITY_MAXIMUM); + } + + /* get number of processors */ + stemp = options().numprocessors(); + + osd_num_processors = 0; + + if (strcmp(stemp, "auto") != 0) + { + osd_num_processors = atoi(stemp); + if (osd_num_processors < 1) + { + osd_printf_warning("numprocessors < 1 doesn't make much sense. Assuming auto ...\n"); + osd_num_processors = 0; + } + } + + osd_mac_info(); + + defines_verbose(); + + osd_common_t::init_subsystems(); + + if (options().oslog()) + { + using namespace std::placeholders; + machine.add_logerror_callback(std::bind(&mac_osd_interface::output_oslog, this, _1)); + } +} diff --git a/src/osd/mac/main.mm b/src/osd/mac/main.mm new file mode 100644 index 00000000000..fdc50be53fe --- /dev/null +++ b/src/osd/mac/main.mm @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// main.mm - main file for MAME on Mac +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import "appdelegate.h" + +int main(int argc, char * argv[]) +{ + [NSApplication sharedApplication]; + [NSApp setDelegate: [MAMEAppDelegate new]]; + + return NSApplicationMain(argc, (const char**)argv); +} diff --git a/src/osd/mac/mamefswindow.h b/src/osd/mac/mamefswindow.h new file mode 100644 index 00000000000..d326b9dfb37 --- /dev/null +++ b/src/osd/mac/mamefswindow.h @@ -0,0 +1,15 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// mamefswindow.h - our fullscreen window, subclassed from NSWindow +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import + +@interface MAMEFSWindow : NSWindow + +@end diff --git a/src/osd/mac/mamefswindow.mm b/src/osd/mac/mamefswindow.mm new file mode 100644 index 00000000000..1fcbdcd02c3 --- /dev/null +++ b/src/osd/mac/mamefswindow.mm @@ -0,0 +1,41 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// mamewfsindow.mm - our fullscreen window, subclassed from NSWindow +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import "mamefswindow.h" + +@implementation MAMEFSWindow + +-(instancetype)init +{ + NSRect screenRect = [[NSScreen mainScreen] frame]; + self = [super initWithContentRect:screenRect + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:YES]; + + // Set the window level to be above the menu bar + [self setLevel:NSMainMenuWindowLevel+1]; + [self setOpaque:YES]; + [self setHidesOnDeactivate:YES]; + + return self; +} + +-(BOOL)canBecomeKeyWindow +{ + return YES; +} + +- (void)keyDown:(NSEvent *)event +{ + [[self windowController] keyDown:event]; +} + +@end diff --git a/src/osd/mac/oglview.h b/src/osd/mac/oglview.h new file mode 100644 index 00000000000..2f876952cba --- /dev/null +++ b/src/osd/mac/oglview.h @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// oglview.h - our OpenGL view +// +// Mac OSD by R. Belmont +// +//============================================================ + +#define GL_SILENCE_DEPRECATION (1) + +#import + +@interface MAMEGLView : NSOpenGLView +{ +} + +@end diff --git a/src/osd/mac/oglview.mm b/src/osd/mac/oglview.mm new file mode 100644 index 00000000000..8ef0a94f880 --- /dev/null +++ b/src/osd/mac/oglview.mm @@ -0,0 +1,106 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// oglview.mm - our OpenGL view +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import "oglview.h" + +#define SUPPORT_RETINA_RESOLUTION 1 + +@interface MAMEGLView () +{ +} +@end + +@implementation MAMEGLView + +- (void) awakeFromNib +{ + NSOpenGLPixelFormatAttribute attrs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 24, + 0 + }; + + NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil]; + + [self setPixelFormat:pf]; + [self setOpenGLContext:context]; + +#if SUPPORT_RETINA_RESOLUTION + // Opt-In to Retina resolution + [self setWantsBestResolutionOpenGLSurface:YES]; +#endif // SUPPORT_RETINA_RESOLUTION +} + +- (void) prepareOpenGL +{ + [super prepareOpenGL]; + + [self initGL]; +} + +- (void) windowWillClose:(NSNotification*)notification +{ +} + +- (void) initGL +{ + [[self openGLContext] makeCurrentContext]; + GLint swapInt = 1; + [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; +} + +- (void)reshape +{ + [super reshape]; + + CGLLockContext([[self openGLContext] CGLContextObj]); + +// NSRect viewRectPoints = [self bounds]; + +//#if SUPPORT_RETINA_RESOLUTION +// NSRect viewRectPixels = [self convertRectToBacking:viewRectPoints]; +//#else +// NSRect viewRectPixels = viewRectPoints; +//#endif + + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} + + +- (void)renewGState +{ + [[self window] disableScreenUpdatesUntilFlush]; + [super renewGState]; +} + +- (void) drawRect: (NSRect) theRect +{ +} + +- (void) startDrawView +{ + [[self openGLContext] makeCurrentContext]; + + CGLLockContext([[self openGLContext] CGLContextObj]); +} + +- (void) completeDrawView +{ + CGLFlushDrawable([[self openGLContext] CGLContextObj]); + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} + +- (void) dealloc +{ + [super dealloc]; +} +@end diff --git a/src/osd/mac/osdmac.h b/src/osd/mac/osdmac.h new file mode 100644 index 00000000000..1ed9e6b8a5b --- /dev/null +++ b/src/osd/mac/osdmac.h @@ -0,0 +1,86 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +#ifndef _osdmac_h_ +#define _osdmac_h_ + +#include "modules/lib/osdobj_common.h" +#include "modules/osdmodule.h" +#include "modules/font/font_module.h" + +//============================================================ +// Defines +//============================================================ + +#define MACOPTION_INIPATH "inipath" + +#define MACOPTVAL_OPENGL "opengl" +#define MACOPTVAL_BGFX "bgfx" +#define MACOPTVAL_METAL "metal" + +#define MACOPTVAL_GLLIB "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib" + +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +class mac_options : public osd_options +{ +public: + // construction/destruction + mac_options(); + +private: + static const options_entry s_option_entries[]; +}; + + +class mac_osd_interface : public osd_common_t +{ +public: + // construction/destruction + mac_osd_interface(mac_options &options); + virtual ~mac_osd_interface(); + + // general overridables + virtual void init(running_machine &machine) override; + virtual void update(bool skip_redraw) override; + + // input overridables + virtual void customize_input_type_list(simple_list &typelist) override; + + virtual void video_register() override; + + virtual bool video_init() override; + virtual bool window_init() override; + + virtual void video_exit() override; + virtual void window_exit() override; + + // sdl specific + void poll_inputs(running_machine &machine); + void release_keys(); + bool should_hide_mouse(); + void process_events_buf(); + + virtual mac_options &options() override { return m_options; } + +protected: + virtual void build_slider_list() override; + virtual void update_slider_list() override; + +private: + virtual void osd_exit() override; + + void extract_video_config(); + void output_oslog(const char *buffer); + + mac_options &m_options; +}; + +//============================================================ +// macwork.cpp +//============================================================ + +extern int osd_num_processors; + +#endif diff --git a/src/osd/mac/video.cpp b/src/osd/mac/video.cpp new file mode 100644 index 00000000000..638e7a949b3 --- /dev/null +++ b/src/osd/mac/video.cpp @@ -0,0 +1,316 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// video.cpp - Mac video handling +// +// Mac OSD by R. Belmont +// +//============================================================ + +// MAME headers +#include "emu.h" +#include "rendutil.h" +#include "ui/uimain.h" +#include "emuopts.h" +#include "uiinput.h" + + +// MAMEOS headers +#include "video.h" +#include "window.h" +#include "osdmac.h" +#include "modules/lib/osdlib.h" + +//============================================================ +// CONSTANTS +//============================================================ + + +//============================================================ +// GLOBAL VARIABLES +//============================================================ + +osd_video_config video_config; + +//============================================================ +// LOCAL VARIABLES +//============================================================ + + +//============================================================ +// PROTOTYPES +//============================================================ + +static void check_osd_inputs(running_machine &machine); + +static void get_resolution(const char *defdata, const char *data, osd_window_config *config, int report_error); + + +//============================================================ +// video_init +//============================================================ + +bool mac_osd_interface::video_init() +{ + int index; + + // extract data from the options + extract_video_config(); + + // we need the beam width in a float, contrary to what the core does. + video_config.beamwidth = options().beam_width_min(); + + // initialize the window system so we can make windows + if (!window_init()) + return false; + + // create the windows + for (index = 0; index < video_config.numscreens; index++) + { + osd_window_config conf; + memset(&conf, 0, sizeof(conf)); + get_resolution(options().resolution(), options().resolution(index), &conf, true); + + // create window ... + std::shared_ptr win = std::make_shared(machine(), index, m_monitor_module->pick_monitor(reinterpret_cast(options()), index), &conf); + + if (win->window_init()) + return false; + } + + return true; +} + +//============================================================ +// video_exit +//============================================================ + +void mac_osd_interface::video_exit() +{ + window_exit(); +} + +//============================================================ +// update +//============================================================ + +void mac_osd_interface::update(bool skip_redraw) +{ + osd_common_t::update(skip_redraw); + + // if we're not skipping this redraw, update all windows + if (!skip_redraw) + { +// profiler_mark(PROFILER_BLIT); + for (auto window : osd_common_t::s_window_list) + window->update(); +// profiler_mark(PROFILER_END); + } + + // poll the joystick values here + downcast(machine().osd()).poll_inputs(machine()); + + check_osd_inputs(machine()); + // if we're running, disable some parts of the debugger + if ((machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) != 0) + debugger_update(); +} + +//============================================================ +// check_osd_inputs +//============================================================ + +static void check_osd_inputs(running_machine &machine) +{ + // check for toggling fullscreen mode + if (machine.ui_input().pressed(IPT_OSD_1)) + { + for (auto curwin : osd_common_t::s_window_list) + std::static_pointer_cast(curwin)->toggle_full_screen(); + } + + auto window = osd_common_t::s_window_list.front(); + if (machine.ui_input().pressed(IPT_OSD_2)) + { + //FIXME: on a per window basis + video_config.fullstretch = !video_config.fullstretch; + window->target()->set_scale_mode(video_config.fullstretch? SCALE_FRACTIONAL : SCALE_INTEGER); + machine.ui().popup_time(1, "Uneven stretch %s", video_config.fullstretch? "enabled":"disabled"); + } + + if (machine.ui_input().pressed(IPT_OSD_4)) + { + //FIXME: on a per window basis + video_config.keepaspect = !video_config.keepaspect; + window->target()->set_keepaspect(video_config.keepaspect); + machine.ui().popup_time(1, "Keepaspect %s", video_config.keepaspect? "enabled":"disabled"); + } + + //FIXME: on a per window basis + if (machine.ui_input().pressed(IPT_OSD_5)) + { + video_config.filter = !video_config.filter; + machine.ui().popup_time(1, "Filter %s", video_config.filter? "enabled":"disabled"); + } + + if (machine.ui_input().pressed(IPT_OSD_6)) + std::static_pointer_cast(window)->modify_prescale(-1); + + if (machine.ui_input().pressed(IPT_OSD_7)) + std::static_pointer_cast(window)->modify_prescale(1); + + if (machine.ui_input().pressed(IPT_OSD_8)) + window->renderer().record(); +} + +//============================================================ +// extract_video_config +//============================================================ + +void mac_osd_interface::extract_video_config() +{ + const char *stemp; + + // global options: extract the data + video_config.windowed = options().window(); + video_config.prescale = options().prescale(); + video_config.filter = options().filter(); + video_config.keepaspect = options().keep_aspect(); + video_config.numscreens = options().numscreens(); + video_config.fullstretch = options().uneven_stretch(); + + // if we are in debug mode, never go full screen + if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) + video_config.windowed = true; + + // default to working video please + video_config.novideo = 0; + + // d3d options: extract the data + stemp = options().video(); + if (strcmp(stemp, "auto") == 0) + { + stemp = "opengl"; + } + + if (strcmp(stemp, OSDOPTVAL_NONE) == 0) + { + video_config.mode = VIDEO_MODE_SOFT; + video_config.novideo = 1; + + if (!emulator_info::standalone() && options().seconds_to_run() == 0) + osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n"); + } + + else if (strcmp(stemp, MACOPTVAL_OPENGL) == 0) + video_config.mode = VIDEO_MODE_OPENGL; + else if (strcmp(stemp, MACOPTVAL_BGFX) == 0) + { + video_config.mode = VIDEO_MODE_BGFX; + } + else + { + osd_printf_warning("Invalid video value %s; reverting to OpenGL\n", stemp); + video_config.mode = VIDEO_MODE_OPENGL; + } + + video_config.switchres = options().switch_res(); + video_config.waitvsync = options().wait_vsync(); + video_config.syncrefresh = options().sync_refresh(); + if (!video_config.waitvsync && video_config.syncrefresh) + { + osd_printf_warning("-syncrefresh specified without -waitvsync. Reverting to -nosyncrefresh\n"); + video_config.syncrefresh = 0; + } + + if (video_config.prescale < 1 || video_config.prescale > 3) + { + osd_printf_warning("Invalid prescale option, reverting to '1'\n"); + video_config.prescale = 1; + } + + // default to working video please + video_config.forcepow2texture = options().gl_force_pow2_texture(); + video_config.allowtexturerect = !(options().gl_no_texture_rect()); + video_config.vbo = options().gl_vbo(); + video_config.pbo = options().gl_pbo(); + video_config.glsl = options().gl_glsl(); + if ( video_config.glsl ) + { + int i; + video_config.glsl_filter = options().glsl_filter(); + video_config.glsl_shader_mamebm_num=0; + for(i=0; i0) + { + video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1); + strcpy(video_config.glsl_shader_mamebm[i], stemp); + video_config.glsl_shader_mamebm_num++; + } else { + video_config.glsl_shader_mamebm[i] = nullptr; + } + } + video_config.glsl_shader_scrn_num=0; + for(i=0; i0) + { + video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1); + strcpy(video_config.glsl_shader_scrn[i], stemp); + video_config.glsl_shader_scrn_num++; + } else { + video_config.glsl_shader_scrn[i] = nullptr; + } + } + } else { + int i; + video_config.glsl_filter = 0; + video_config.glsl_shader_mamebm_num=0; + for(i=0; i MAX_VIDEO_WINDOWS) + { + osd_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens); + video_config.numscreens = 1; + } +} + + +//============================================================ +// get_resolution +//============================================================ + +static void get_resolution(const char *defdata, const char *data, osd_window_config *config, int report_error) +{ + config->width = config->height = config->depth = config->refresh = 0; + if (strcmp(data, OSDOPTVAL_AUTO) == 0) + { + if (strcmp(defdata, OSDOPTVAL_AUTO) == 0) + return; + data = defdata; + } + + if (sscanf(data, "%dx%dx%d", &config->width, &config->height, &config->depth) < 2 && report_error) + osd_printf_error("Illegal resolution value = %s\n", data); + + const char * at_pos = strchr(data, '@'); + if (at_pos) + if (sscanf(at_pos + 1, "%d", &config->refresh) < 1 && report_error) + osd_printf_error("Illegal refresh rate in resolution value = %s\n", data); +} diff --git a/src/osd/mac/window.cpp b/src/osd/mac/window.cpp new file mode 100644 index 00000000000..3993b3502d2 --- /dev/null +++ b/src/osd/mac/window.cpp @@ -0,0 +1,970 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// window.cpp - Mac window handling +// +// Mac OSD by R. Belmont +// +//============================================================ + +// standard C headers +#include +#ifndef _MSC_VER +#include +#endif +#include +#include + +// MAME headers +#include "emu.h" +#include "emuopts.h" +#include "render.h" +#include "ui/uimain.h" + +// OSD headers + +#include "window.h" +#include "osdmac.h" +#include "modules/render/drawbgfx.h" +#include "modules/render/drawogl.h" +#include "modules/monitor/monitor_common.h" + +//============================================================ +// PARAMETERS +//============================================================ + +// these are arbitrary values since AFAIK there's no way to make X/SDL tell you +#define WINDOW_DECORATION_WIDTH (8) // should be more than plenty +#define WINDOW_DECORATION_HEIGHT (48) // title bar + bottom drag region + +// minimum window dimension +#define MIN_WINDOW_DIM 200 + +#define WMSZ_TOP (0) +#define WMSZ_BOTTOM (1) +#define WMSZ_BOTTOMLEFT (2) +#define WMSZ_BOTTOMRIGHT (3) +#define WMSZ_LEFT (4) +#define WMSZ_TOPLEFT (5) +#define WMSZ_TOPRIGHT (6) +#define WMSZ_RIGHT (7) + +// debugger +//static int in_background; + + +//============================================================ +// PROTOTYPES +//============================================================ + + +//============================================================ +// window_init +// (main thread) +//============================================================ + +bool mac_osd_interface::window_init() +{ + osd_printf_verbose("Enter macwindow_init\n"); + + // initialize the drawers + + switch (video_config.mode) + { + case VIDEO_MODE_BGFX: + renderer_bgfx::init(machine()); + break; + case VIDEO_MODE_OPENGL: + renderer_ogl::init(machine()); + break; + } + + // set up the window list + osd_printf_verbose("Leave macwindow_init\n"); + return true; +} + + +void mac_osd_interface::update_slider_list() +{ + for (auto window : osd_common_t::s_window_list) + { + // check if any window has dirty sliders + if (window->renderer().sliders_dirty()) + { + build_slider_list(); + return; + } + } +} + +void mac_osd_interface::build_slider_list() +{ + m_sliders.clear(); + + for (auto window : osd_common_t::s_window_list) + { + std::vector window_sliders = window->renderer().get_slider_list(); + m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end()); + } +} + +//============================================================ +// macwindow_exit +// (main thread) +//============================================================ + +void mac_osd_interface::window_exit() +{ + osd_printf_verbose("Enter macwindow_exit\n"); + + // free all the windows + while (!osd_common_t::s_window_list.empty()) + { + auto window = osd_common_t::s_window_list.front(); + + // Part of destroy removes the window from the list + window->destroy(); + } + + switch(video_config.mode) + { + case VIDEO_MODE_BGFX: + renderer_bgfx::exit(); + break; + case VIDEO_MODE_OPENGL: + renderer_ogl::exit(); + break; + default: + break; + } + osd_printf_verbose("Leave macwindow_exit\n"); +} + +void mac_window_info::capture_pointer() +{ + if (!m_mouse_captured) + { + m_mouse_captured = true; + } +} + +void mac_window_info::release_pointer() +{ + if (m_mouse_captured) + { + m_mouse_captured = false; + } +} + +void mac_window_info::hide_pointer() +{ + if (!m_mouse_hidden) + { + m_mouse_hidden = true; + } +} + +void mac_window_info::show_pointer() +{ + if (m_mouse_hidden) + { + m_mouse_hidden = false; + } +} + + +//============================================================ +// macwindow_resize +//============================================================ + +void mac_window_info::resize(int32_t width, int32_t height) +{ + osd_dim cd = get_size(); + + if (width != cd.width() || height != cd.height()) + { + // TODO: change window size here + renderer().notify_changed(); + } +} + + +//============================================================ +// notify_changed +//============================================================ + +void mac_window_info::notify_changed() +{ + renderer().notify_changed(); +} + + +//============================================================ +// toggle_full_screen +//============================================================ + +void mac_window_info::toggle_full_screen() +{ + // if we are in debug mode, never go full screen + if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) + return; + + // If we are going fullscreen (leaving windowed) remember our windowed size + if (!fullscreen()) + { + m_windowed_dim = get_size(); + } + + // reset UI to main menu + machine().ui().menu_reset(); + // kill off the drawers + renderer_reset(); + if (fullscreen() && video_config.switchres) + { + } + //SDL_DestroyWindow(platform_window()); + //set_platform_window(nullptr); + + downcast(machine().osd()).release_keys(); + + set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this())); + + // toggle the window mode + set_fullscreen(!fullscreen()); + + complete_create(); +} + +void mac_window_info::modify_prescale(int dir) +{ + int new_prescale = prescale(); + + if (dir > 0 && prescale() < 3) + new_prescale = prescale() + 1; + if (dir < 0 && prescale() > 1) + new_prescale = prescale() - 1; + + if (new_prescale != prescale()) + { + if (m_fullscreen && video_config.switchres) + { + complete_destroy(); + + m_prescale = new_prescale; + + complete_create(); + } + else + { + notify_changed(); + m_prescale = new_prescale; + } + machine().ui().popup_time(1, "Prescale %d", prescale()); + } +} + +//============================================================ +// update_cursor_state +// (main or window thread) +//============================================================ + +void mac_window_info::update_cursor_state() +{ + // do not do mouse capture if the debugger's enabled to avoid + // the possibility of losing control + if (!(machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)) + { + bool should_hide_mouse = downcast(machine().osd()).should_hide_mouse(); + + if (!fullscreen() && !should_hide_mouse) + { + show_pointer(); + release_pointer(); + } + else + { + hide_pointer(); + capture_pointer(); + } + } +} + +int mac_window_info::xy_to_render_target(int x, int y, int *xt, int *yt) +{ + return renderer().xy_to_render_target(x, y, xt, yt); +} + +//============================================================ +// mac_window_info::window_init +// (main thread) +//============================================================ + +int mac_window_info::window_init() +{ + int result; + + // set the initial maximized state + // FIXME: Does not belong here + mac_options &options = downcast(m_machine.options()); + m_startmaximized = options.maximize(); + + // add us to the list + osd_common_t::s_window_list.push_back(std::static_pointer_cast(shared_from_this())); + + set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast(this)->shared_from_this())); + + // load the layout + m_target = m_machine.render().target_alloc(); + + // set the specific view + set_starting_view(m_index, options.view(), options.view(m_index)); + + // make the window title + if (video_config.numscreens == 1) + sprintf(m_title, "%s: %s [%s]", emulator_info::get_appname(), m_machine.system().type.fullname(), m_machine.system().name); + else + sprintf(m_title, "%s: %s [%s] - Screen %d", emulator_info::get_appname(), m_machine.system().type.fullname(), m_machine.system().name, m_index); + + result = complete_create(); + + // handle error conditions + if (result == 1) + goto error; + + return 0; + +error: + destroy(); + return 1; +} + + +//============================================================ +// mac_window_info::complete_destroy +//============================================================ + +void mac_window_info::complete_destroy() +{ + // Release pointer grab and hide if needed + show_pointer(); + release_pointer(); + + if (fullscreen() && video_config.switchres) + { + } + + //SDL_DestroyWindow(platform_window()); + // release all keys ... + downcast(machine().osd()).release_keys(); +} + +void mac_window_info::destroy() +{ + // remove us from the list + osd_common_t::s_window_list.remove(std::static_pointer_cast(shared_from_this())); + + // free the textures etc + complete_destroy(); + + // free the render target, after the textures! + machine().render().target_free(m_target); +} + + +//============================================================ +// pick_best_mode +//============================================================ + +osd_dim mac_window_info::pick_best_mode() +{ +// int minimum_width, minimum_height, target_width, target_height; +// int i; +// int num; +// float size_score, best_score = 0.0f; + osd_dim ret(0,0); +#if 0 + // determine the minimum width/height for the selected target + m_target->compute_minimum_size(minimum_width, minimum_height); + + // use those as the target for now + target_width = minimum_width * std::max(1, prescale()); + target_height = minimum_height * std::max(1, prescale()); + + // if we're not stretching, allow some slop on the minimum since we can handle it + { + minimum_width -= 4; + minimum_height -= 4; + } + + // FIXME: this should be provided by monitor ! + num = SDL_GetNumDisplayModes(m_monitor->oshandle()); + + if (num == 0) + { + osd_printf_error("SDL: No modes available?!\n"); + exit(-1); + } + else + { + for (i = 0; i < num; ++i) + { + SDL_DisplayMode mode; + SDL_GetDisplayMode(m_monitor->oshandle(), i, &mode); + + // compute initial score based on difference between target and current + size_score = 1.0f / (1.0f + abs((int32_t)mode.w - target_width) + abs((int32_t)mode.h - target_height)); + + // if the mode is too small, give a big penalty + if (mode.w < minimum_width || mode.h < minimum_height) + size_score *= 0.01f; + + // if mode is smaller than we'd like, it only scores up to 0.1 + if (mode.w < target_width || mode.h < target_height) + size_score *= 0.1f; + + // if we're looking for a particular mode, that's a winner + if (mode.w == m_win_config.width && mode.h == m_win_config.height) + size_score = 2.0f; + + // refresh adds some points + if (m_win_config.refresh) + size_score *= 1.0f / (1.0f + abs(m_win_config.refresh - mode.refresh_rate) / 10.0f); + + osd_printf_verbose("%4dx%4d@%2d -> %f\n", (int)mode.w, (int)mode.h, (int) mode.refresh_rate, (double) size_score); + + // best so far? + if (size_score > best_score) + { + best_score = size_score; + ret = osd_dim(mode.w, mode.h); + } + + } + } +#endif + return ret; +} + +//============================================================ +// sdlwindow_video_window_update +// (main thread) +//============================================================ + +void mac_window_info::update() +{ + osd_ticks_t event_wait_ticks; + + // adjust the cursor state + //sdlwindow_update_cursor_state(machine, window); + + update_cursor_state(); + + // if we're visible and running and not in the middle of a resize, draw + if (m_target != nullptr) + { + int tempwidth, tempheight; + + // see if the games video mode has changed + m_target->compute_minimum_size(tempwidth, tempheight); + if (osd_dim(tempwidth, tempheight) != m_minimum_dim) + { + m_minimum_dim = osd_dim(tempwidth, tempheight); + + if (!this->m_fullscreen) + { + //Don't resize window without user interaction; + //window_resize(blitwidth, blitheight); + } + else if (video_config.switchres) + { + osd_dim tmp = this->pick_best_mode(); + resize(tmp.width(), tmp.height()); + } + } + + if (video_config.waitvsync && video_config.syncrefresh) + event_wait_ticks = osd_ticks_per_second(); // block at most a second + else + event_wait_ticks = 0; + + if (m_rendered_event.wait(event_wait_ticks)) + { + const int update = 1; + + // ensure the target bounds are up-to-date, and then get the primitives + + render_primitive_list &primlist = *renderer().get_primitives(); + + // and redraw now + + // Some configurations require events to be polled in the worker thread + downcast< mac_osd_interface& >(machine().osd()).process_events_buf(); + + // Check whether window has vector screens + + { + const screen_device *screen = screen_device_iterator(machine().root_device()).byindex(m_index); + if ((screen != nullptr) && (screen->screen_type() == SCREEN_TYPE_VECTOR)) + renderer().set_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); + else + renderer().clear_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); + } + + m_primlist = &primlist; + + // if no bitmap, just fill + if (m_primlist == nullptr) + { + } + // otherwise, render with our drawing system + else + { + if( video_config.perftest ) + measure_fps(update); + else + renderer().draw(update); + } + + /* all done, ready for next */ + m_rendered_event.set(); + } + } +} + + +//============================================================ +// set_starting_view +// (main thread) +//============================================================ + +void mac_window_info::set_starting_view(int index, const char *defview, const char *view) +{ + int viewindex; + + // choose non-auto over auto + if (strcmp(view, "auto") == 0 && strcmp(defview, "auto") != 0) + view = defview; + + // query the video system to help us pick a view + viewindex = target()->configured_view(view, index, video_config.numscreens); + + // set the view + target()->set_view(viewindex); +} + + +//============================================================ +// complete_create +//============================================================ + +extern void *CreateMAMEWindow(char *title, int x, int y, int w, int h, bool isFullscreen); +extern void *GetOSWindow(void *wincontroller); + +int mac_window_info::complete_create() +{ + osd_dim temp(0,0); + + // clear out original mode. Needed on OSX + if (fullscreen()) + { + // default to the current mode exactly + temp = monitor()->position_size().dim(); + + // if we're allowed to switch resolutions, override with something better + if (video_config.switchres) + temp = pick_best_mode(); + } + else if (m_windowed_dim.width() > 0) + { + // if we have a remembered size force the new window size to it + temp = m_windowed_dim; + } + else if (m_startmaximized) + temp = get_max_bounds(video_config.keepaspect ); + else + temp = get_min_bounds(video_config.keepaspect ); + + // create the window ..... + osd_printf_verbose("Enter mac_window_info::complete_create\n"); + + // get monitor work area for centering + osd_rect work = monitor()->usuable_position_size(); + + auto window = CreateMAMEWindow(m_title, + work.left() + (work.width() - temp.width()) / 2, + work.top() + (work.height() - temp.height()) / 2, + temp.width(), temp.height(), fullscreen()); + + if (window == nullptr) + { + osd_printf_error("Window creation failed!\n"); + return 1; + } + + set_platform_window(window); + + // set main window + if (m_index > 0) + { + for (auto w : osd_common_t::s_window_list) + { + if (w->m_index == 0) + { + set_main_window(std::dynamic_pointer_cast(w)); + break; + } + } + } + else + { + // We must be the main window + set_main_window(shared_from_this()); + } + + // update monitor resolution after mode change to ensure proper pixel aspect + monitor()->refresh(); + if (fullscreen() && video_config.switchres) + monitor()->update_resolution(temp.width(), temp.height()); + + // initialize the drawing backend + if (renderer().create()) + { + osd_printf_verbose("Exiting mac_window_info::complete_create\n"); + return 1; + } + + return 0; +} + + +//============================================================ +// draw_video_contents +// (window thread) +//============================================================ + +void mac_window_info::measure_fps(int update) +{ + const unsigned long frames_skip4fps = 100; + static int64_t lastTime=0, sumdt=0, startTime=0; + static unsigned long frames = 0; + int64_t currentTime, t0; + double dt; + double tps; + osd_ticks_t tps_t; + + tps_t = osd_ticks_per_second(); + tps = (double) tps_t; + + t0 = osd_ticks(); + + renderer().draw(update); + + frames++; + currentTime = osd_ticks(); + if(startTime==0||frames==frames_skip4fps) + startTime=currentTime; + if( frames>=frames_skip4fps ) + sumdt+=currentTime-t0; + if( (currentTime-lastTime)>1L*osd_ticks_per_second() && frames>frames_skip4fps ) + { + dt = (double) (currentTime-startTime) / tps; // in decimale sec. + osd_printf_info("%6.2lfs, %4lu F, " + "avrg game: %5.2lf FPS %.2lf ms/f, " + "avrg video: %5.2lf FPS %.2lf ms/f, " + "last video: %5.2lf FPS %.2lf ms/f\n", + dt, frames-frames_skip4fps, + (double)(frames-frames_skip4fps)/dt, // avrg game fps + ( (currentTime-startTime) / ((frames-frames_skip4fps)) ) * 1000.0 / osd_ticks_per_second(), + (double)(frames-frames_skip4fps)/((double)(sumdt) / tps), // avrg vid fps + ( sumdt / ((frames-frames_skip4fps)) ) * 1000.0 / tps, + 1.0/((currentTime-t0) / osd_ticks_per_second()), // this vid fps + (currentTime-t0) * 1000.0 / tps + ); + lastTime = currentTime; + } +} + +int mac_window_info::wnd_extra_width() +{ + return m_fullscreen ? 0 : WINDOW_DECORATION_WIDTH; +} + +int mac_window_info::wnd_extra_height() +{ + return m_fullscreen ? 0 : WINDOW_DECORATION_HEIGHT; +} + + +//============================================================ +// constrain_to_aspect_ratio +// (window thread) +//============================================================ + +osd_rect mac_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int adjustment) +{ + int32_t extrawidth = wnd_extra_width(); + int32_t extraheight = wnd_extra_height(); + int32_t propwidth, propheight; + int32_t minwidth, minheight; + int32_t maxwidth, maxheight; + int32_t viswidth, visheight; + int32_t adjwidth, adjheight; + float pixel_aspect; + std::shared_ptr monitor = m_monitor; + + // do not constrain aspect ratio for integer scaled views + if (m_target->scale_mode() != SCALE_FRACTIONAL) + return rect; + + // get the pixel aspect ratio for the target monitor + pixel_aspect = monitor->pixel_aspect(); + + // determine the proposed width/height + propwidth = rect.width() - extrawidth; + propheight = rect.height() - extraheight; + + // based on which edge we are adjusting, take either the width, height, or both as gospel + // and scale to fit using that as our parameter + switch (adjustment) + { + case WMSZ_BOTTOM: + case WMSZ_TOP: + m_target->compute_visible_area(10000, propheight, pixel_aspect, m_target->orientation(), propwidth, propheight); + break; + + case WMSZ_LEFT: + case WMSZ_RIGHT: + m_target->compute_visible_area(propwidth, 10000, pixel_aspect, m_target->orientation(), propwidth, propheight); + break; + + default: + m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), propwidth, propheight); + break; + } + + // get the minimum width/height for the current layout + m_target->compute_minimum_size(minwidth, minheight); + + // clamp against the absolute minimum + propwidth = std::max(propwidth, MIN_WINDOW_DIM); + propheight = std::max(propheight, MIN_WINDOW_DIM); + + // clamp against the minimum width and height + propwidth = std::max(propwidth, minwidth); + propheight = std::max(propheight, minheight); + + // clamp against the maximum (fit on one screen for full screen mode) + if (m_fullscreen) + { + maxwidth = monitor->position_size().width() - extrawidth; + maxheight = monitor->position_size().height() - extraheight; + } + else + { + maxwidth = monitor->usuable_position_size().width() - extrawidth; + maxheight = monitor->usuable_position_size().height() - extraheight; + + // further clamp to the maximum width/height in the window + if (m_win_config.width != 0) + maxwidth = std::min(maxwidth, m_win_config.width + extrawidth); + if (m_win_config.height != 0) + maxheight = std::min(maxheight, m_win_config.height + extraheight); + } + + // clamp to the maximum + propwidth = std::min(propwidth, maxwidth); + propheight = std::min(propheight, maxheight); + + // compute the visible area based on the proposed rectangle + m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), viswidth, visheight); + + // compute the adjustments we need to make + adjwidth = (viswidth + extrawidth) - rect.width(); + adjheight = (visheight + extraheight) - rect.height(); + + // based on which corner we're adjusting, constrain in different ways + osd_rect ret(rect); + + switch (adjustment) + { + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_RIGHT: + ret = rect.resize(rect.width() + adjwidth, rect.height() + adjheight); + break; + + case WMSZ_BOTTOMLEFT: + ret = rect.move_by(-adjwidth, 0).resize(rect.width() + adjwidth, rect.height() + adjheight); + break; + + case WMSZ_LEFT: + case WMSZ_TOPLEFT: + case WMSZ_TOP: + ret = rect.move_by(-adjwidth, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); + break; + + case WMSZ_TOPRIGHT: + ret = rect.move_by(0, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); + break; +} + return ret; +} + + + +//============================================================ +// get_min_bounds +// (window thread) +//============================================================ + +osd_dim mac_window_info::get_min_bounds(int constrain) +{ + int32_t minwidth, minheight; + + //assert(GetCurrentThreadId() == window_threadid); + + // get the minimum target size + m_target->compute_minimum_size(minwidth, minheight); + + // expand to our minimum dimensions + if (minwidth < MIN_WINDOW_DIM) + minwidth = MIN_WINDOW_DIM; + if (minheight < MIN_WINDOW_DIM) + minheight = MIN_WINDOW_DIM; + + // account for extra window stuff + minwidth += wnd_extra_width(); + minheight += wnd_extra_height(); + + // if we want it constrained, figure out which one is larger + if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL) + { + // first constrain with no height limit + osd_rect test1(0,0,minwidth,10000); + test1 = constrain_to_aspect_ratio(test1, WMSZ_BOTTOMRIGHT); + + // then constrain with no width limit + osd_rect test2(0,0,10000,minheight); + test2 = constrain_to_aspect_ratio(test2, WMSZ_BOTTOMRIGHT); + + // pick the larger + if (test1.width() > test2.width()) + { + minwidth = test1.width(); + minheight = test1.height(); + } + else + { + minwidth = test2.width(); + minheight = test2.height(); + } + } + + // remove extra window stuff + minwidth -= wnd_extra_width(); + minheight -= wnd_extra_height(); + + return osd_dim(minwidth, minheight); +} + +//============================================================ +// get_size +//============================================================ + +osd_dim mac_window_info::get_size() +{ + int w=0; int h=0; + // TODO: get window size from ObjC +// SDL_GetWindowSize(platform_window(), &w, &h); + return osd_dim(w,h); +} + + +//============================================================ +// get_max_bounds +// (window thread) +//============================================================ + +osd_dim mac_window_info::get_max_bounds(int constrain) +{ + //assert(GetCurrentThreadId() == window_threadid); + + // compute the maximum client area + // m_monitor->refresh(); + osd_rect maximum = m_monitor->usuable_position_size(); + + // clamp to the window's max + int tempw = maximum.width(); + int temph = maximum.height(); + if (m_win_config.width != 0) + { + int temp = m_win_config.width + wnd_extra_width(); + if (temp < maximum.width()) + tempw = temp; + } + if (m_win_config.height != 0) + { + int temp = m_win_config.height + wnd_extra_height(); + if (temp < maximum.height()) + temph = temp; + } + + maximum = maximum.resize(tempw, temph); + + // constrain to fit + if (constrain && m_target->scale_mode() == SCALE_FRACTIONAL) + maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT); + + // remove extra window stuff + maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height()); + + return maximum.dim(); +} + +//============================================================ +// construction and destruction +//============================================================ + +mac_window_info::mac_window_info( + running_machine &a_machine, + int index, + std::shared_ptr a_monitor, + const osd_window_config *config) + : osd_window_t(*config) + , m_next(nullptr) + , m_startmaximized(0) + // Following three are used by input code to defer resizes + , m_minimum_dim(0, 0) + , m_windowed_dim(0, 0) + , m_rendered_event(0, 1) + , m_target(nullptr) + , m_machine(a_machine) + , m_monitor(a_monitor) + , m_fullscreen(0) + , m_mouse_captured(false) + , m_mouse_hidden(false) +{ + m_index = index; + + //FIXME: these should be per_window in config-> or even better a bit set + m_fullscreen = !video_config.windowed; + m_prescale = video_config.prescale; + + m_windowed_dim = osd_dim(config->width, config->height); +} + +mac_window_info::~mac_window_info() +{ +} + + +//============================================================ +// osd_set_aggressive_input_focus +//============================================================ + +void osd_set_aggressive_input_focus(bool aggressive_focus) +{ + // dummy implementation for now +} diff --git a/src/osd/mac/window.h b/src/osd/mac/window.h new file mode 100644 index 00000000000..24e749a425b --- /dev/null +++ b/src/osd/mac/window.h @@ -0,0 +1,134 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// window.h - SDL window handling +// +// Mac OSD by R. Belmont +// +//============================================================ + +#ifndef __MACWINDOW__ +#define __MACWINDOW__ + +#include "osdmac.h" +#include "video.h" + +#include "modules/osdwindow.h" + +#include +#include +#include + +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +class render_target; + +typedef uintptr_t HashT; + +#define OSDWORK_CALLBACK(name) void *name(void *param, ATTR_UNUSED int threadid) + +class mac_window_info : public osd_window_t +{ +public: + mac_window_info(running_machine &a_machine, int index, std::shared_ptr a_monitor, + const osd_window_config *config); + + ~mac_window_info(); + + int window_init(); + + void update() override; + void toggle_full_screen(); + void modify_prescale(int dir); + void resize(int32_t width, int32_t height); + void destroy() override; + + void capture_pointer() override; + void release_pointer() override; + void show_pointer() override; + void hide_pointer() override; + + void notify_changed(); + + osd_dim get_size() override; + + int xy_to_render_target(int x, int y, int *xt, int *yt); + + running_machine &machine() const override { return m_machine; } + osd_monitor_info *monitor() const override { return m_monitor.get(); } + int fullscreen() const override { return m_fullscreen; } + + render_target *target() override { return m_target; } + + int prescale() const { return m_prescale; } + + // Pointer to next window + mac_window_info * m_next; + +private: + // window handle and info + char m_title[256]; + int m_startmaximized; + + // dimensions + osd_dim m_minimum_dim; + osd_dim m_windowed_dim; + + // rendering info + osd_event m_rendered_event; + render_target * m_target; + + //int m_extra_flags; + + // returns 0 on success, else 1 + int complete_create(); + void complete_destroy(); + +private: + int wnd_extra_width(); + int wnd_extra_height(); + void set_starting_view(int index, const char *defview, const char *view); + osd_rect constrain_to_aspect_ratio(const osd_rect &rect, int adjustment); + osd_dim get_min_bounds(int constrain); + osd_dim get_max_bounds(int constrain); + void update_cursor_state(); + osd_dim pick_best_mode(); + void set_fullscreen(int afullscreen) { m_fullscreen = afullscreen; } + + // Pointer to machine + running_machine & m_machine; + + // monitor info + std::shared_ptr m_monitor; + int m_fullscreen; + bool m_mouse_captured; + bool m_mouse_hidden; + + void measure_fps(int update); +}; + +struct osd_draw_callbacks +{ + osd_renderer *(*create)(osd_window *window); +}; + +//============================================================ +// PROTOTYPES +//============================================================ + +//============================================================ +// PROTOTYPES - drawogl.c +//============================================================ + +int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks); + +//============================================================ +// PROTOTYPES - drawbgfx.c +//============================================================ + +int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks); + +#endif /* __MACWINDOW__ */ diff --git a/src/osd/mac/windowcontroller.h b/src/osd/mac/windowcontroller.h new file mode 100644 index 00000000000..54f0b3376e1 --- /dev/null +++ b/src/osd/mac/windowcontroller.h @@ -0,0 +1,16 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// windowcontroller.mm - our window/fullscreen manager +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import +#import "oglview.h" + +@interface MAMEWindowController : NSWindowController + +@end diff --git a/src/osd/mac/windowcontroller.mm b/src/osd/mac/windowcontroller.mm new file mode 100644 index 00000000000..396fbc49238 --- /dev/null +++ b/src/osd/mac/windowcontroller.mm @@ -0,0 +1,121 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +//============================================================ +// +// windowcontroller.mm - our window/fullscreen manager +// +// Mac OSD by R. Belmont +// +//============================================================ + +#import "windowcontroller.h" +#import "mamefswindow.h" + +@interface MAMEWindowController () +{ + MAMEFSWindow *_fullscreenWindow; + NSWindow* _standardWindow; +} +@end + +@implementation MAMEWindowController + +- (instancetype)initWithWindow:(NSWindow *)window +{ + self = [super initWithWindow:window]; + + if (self) + { + _fullscreenWindow = nil; + _standardWindow = window; + } + + return self; +} + +- (void) goFullscreen +{ + if(_fullscreenWindow) + { + return; + } + + _fullscreenWindow = [[MAMEFSWindow alloc] init]; + + NSRect viewRect = [_fullscreenWindow frame]; + [self.window.contentView setFrameSize: viewRect.size]; + [_fullscreenWindow setContentView:self.window.contentView]; + + _standardWindow = [self window]; + [_standardWindow orderOut:self]; + + [self setWindow:_fullscreenWindow]; + [_fullscreenWindow makeKeyAndOrderFront:self]; +} + +- (void) goWindow +{ + if(_fullscreenWindow == nil) + { + return; + } + + NSRect viewRect = [_standardWindow frame]; + [self.window.contentView setFrame:viewRect]; + + [self setWindow:_standardWindow]; + [[self window] setContentView:_fullscreenWindow.contentView]; + [[self window] makeKeyAndOrderFront:self]; + + _fullscreenWindow = nil; +} + + +- (void) keyDown:(NSEvent *)event +{ +// unichar c = [[event charactersIgnoringModifiers] characterAtIndex:0]; + [super keyDown:event]; +} + +- (NSWindow *) getWindow +{ + if(_fullscreenWindow == nil) + { + return _standardWindow; + } + + return _fullscreenWindow; +} +@end + +void *GetOSWindow(void *wincontroller) +{ + MAMEWindowController *wc = (MAMEWindowController *)wincontroller; + + return [wc getWindow]; +} + +void *CreateMAMEWindow(char *title, int x, int y, int w, int h, bool isFullscreen) +{ + NSRect bounds = NSMakeRect(x, y, w, h); + NSUInteger style = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask; + NSWindow *window = [NSWindow alloc]; + MAMEWindowController *controller = [MAMEWindowController alloc]; + + dispatch_sync(dispatch_get_main_queue(), ^{ + [window initWithContentRect:bounds + styleMask:style + backing:NSBackingStoreBuffered + defer:NO]; + [controller initWithWindow:window]; + }); + + if (isFullscreen) + { + [controller goFullscreen]; + } + + [window makeKeyAndOrderFront:nil]; + + return (void *)controller; +} diff --git a/src/osd/modules/opengl/osd_opengl.h b/src/osd/modules/opengl/osd_opengl.h index 26f577f343e..47d0b3c429c 100644 --- a/src/osd/modules/opengl/osd_opengl.h +++ b/src/osd/modules/opengl/osd_opengl.h @@ -32,6 +32,9 @@ #include "GL/wglext.h" #endif #endif + #elif defined(OSD_MAC) + #include + #include #else #include diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 0c483d9eb59..3c15bc3cf96 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -15,8 +15,12 @@ #include #endif #else +#if defined(OSD_MAC) +extern void *GetOSWindow(void *wincontroller); +#else #include #endif +#endif // MAMEOS headers #include "emu.h" @@ -143,6 +147,17 @@ inline void winSetHwnd(::HWND _window) pd.backBufferDS = NULL; bgfx::setPlatformData(pd); } +#elif defined(OSD_MAC) +inline void macSetWindow(void *_window) +{ + bgfx::PlatformData pd; + pd.ndt = NULL; + pd.nwh = GetOSWindow(_window); + pd.context = NULL; + pd.backBuffer = NULL; + pd.backBufferDS = NULL; + bgfx::setPlatformData(pd); +} #elif defined(OSD_SDL) static void* sdlNativeWindowHandle(SDL_Window* _window) { @@ -240,6 +255,8 @@ int renderer_bgfx::create() #elif defined(OSD_UWP) winrtSetWindow(AsInspectable(std::static_pointer_cast(win)->platform_window())); +#elif defined(OSD_MAC) + macSetWindow(std::static_pointer_cast(win)->platform_window()); #else sdlSetWindow(std::dynamic_pointer_cast(win)->platform_window()); #endif @@ -296,6 +313,8 @@ int renderer_bgfx::create() m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast(win)->platform_window(), m_width[win->m_index], m_height[win->m_index]); #elif defined(OSD_UWP) m_framebuffer = m_targets->create_backbuffer(AsInspectable(std::static_pointer_cast(win)->platform_window()), m_width[win->m_index], m_height[win->m_index]); +#elif defined(OSD_MAC) + m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast(win)->platform_window()), m_width[win->m_index], m_height[win->m_index]); #else m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast(win)->platform_window()), m_width[win->m_index], m_height[win->m_index]); #endif @@ -949,6 +968,8 @@ bool renderer_bgfx::update_dimensions() m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast(win)->platform_window(), width, height); #elif defined(OSD_UWP) m_framebuffer = m_targets->create_backbuffer(AsInspectable(std::static_pointer_cast(win)->platform_window()), width, height); +#elif defined(OSD_MAC) + m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast(win)->platform_window()), width, height); #else m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast(win)->platform_window()), width, height); #endif diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp index 6c1cb405316..bd4648be474 100644 --- a/src/osd/modules/render/drawogl.cpp +++ b/src/osd/modules/render/drawogl.cpp @@ -21,7 +21,11 @@ #include "emu.h" #include "emuopts.h" -#ifndef OSD_WINDOWS +#ifdef OSD_MAC +#define GL_SILENCE_DEPRECATION (1) +#endif + +#if !defined(OSD_WINDOWS) && !defined(OSD_MAC) // standard SDL headers #define TOBEMIGRATED 1 #include @@ -36,7 +40,7 @@ #include "modules/opengl/gl_shader_tool.h" #include "modules/opengl/gl_shader_mgr.h" -#if defined(SDLMAME_MACOSX) +#if defined(SDLMAME_MACOSX) || defined(OSD_MAC) #ifndef APIENTRY #define APIENTRY #endif @@ -237,7 +241,7 @@ void renderer_ogl::set_blendmode(int blendmode) //============================================================ // OGL 1.3 -#ifdef GL_ARB_multitexture +#if defined(GL_ARB_multitexture) && !defined(OSD_MAC) static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture = nullptr; #else static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture = nullptr; @@ -558,6 +562,9 @@ int renderer_ogl::create() // create renderer #if defined(OSD_WINDOWS) m_gl_context = global_alloc(win_gl_context(std::static_pointer_cast(win)->platform_window())); +#elif defined(OSD_MAC) +// TODO +// m_gl_context = global_alloc(mac_gl_context(std::static_pointer_cast(win)->platform_window())); #else m_gl_context = global_alloc(sdl_gl_context(std::static_pointer_cast(win)->platform_window())); #endif @@ -886,7 +893,7 @@ void renderer_ogl::loadGLExtensions() if ( m_useglsl ) { - #ifdef GL_ARB_multitexture + #if defined(GL_ARB_multitexture) && !defined(OSD_MAC) pfn_glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) m_gl_context->getProcAddress("glActiveTextureARB"); #else pfn_glActiveTexture = (PFNGLACTIVETEXTUREPROC) m_gl_context->getProcAddress("glActiveTexture"); diff --git a/src/osd/modules/render/drawogl.h b/src/osd/modules/render/drawogl.h index 5444f203141..525ba0c3ffa 100644 --- a/src/osd/modules/render/drawogl.h +++ b/src/osd/modules/render/drawogl.h @@ -15,7 +15,11 @@ // OSD headers #ifndef OSD_WINDOWS +#ifdef OSD_MAC +#include "osdmac.h" +#else #include "osdsdl.h" +#endif #include "window.h" #else #include "../windows/window.h" @@ -24,6 +28,7 @@ typedef uint64_t HashT; #if defined(OSD_WINDOWS) #include "winglcontext.h" +#elif defined (OSD_MAC) #else #include "sdlglcontext.h" #endif -- cgit v1.2.3