#include "VISIRenderer.hpp" #include #include "athena/Global.hpp" #include "logvisor/logvisor.hpp" #include "../version.h" #include #if !__has_feature(objc_arc) #error ARC Required #endif static std::thread s_task; static const NSOpenGLPixelFormatAttribute PF_RGBA8_Z24_ATTRS[] = { NSOpenGLPFAAccelerated, NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, //NSOpenGLPFADoubleBuffer, NSOpenGLPFAColorSize, 24, NSOpenGLPFAAlphaSize, 8, NSOpenGLPFADepthSize, 24, 0, 0 }; @interface OpenGLView : NSOpenGLView { VISIRenderer* m_renderer; } - (id)initWithFrame:(NSRect)frame renderer:(VISIRenderer*)renderer; @end static NSWindow* s_Window; static void UpdatePercent(float percent) { dispatch_async(dispatch_get_main_queue(), ^{ s_Window.title = [NSString stringWithFormat:@"VISIGen [%g%%]", percent * 100.f]; }); } @implementation OpenGLView - (id)initWithFrame:(NSRect)frame renderer:(VISIRenderer*)renderer; { NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:PF_RGBA8_Z24_ATTRS]; self = [super initWithFrame:frame pixelFormat:pf]; m_renderer = renderer; return self; } - (void)prepareOpenGL { [super prepareOpenGL]; s_task = std::thread([self](){ [[self openGLContext] makeCurrentContext]; m_renderer->Run(UpdatePercent); [NSApp terminate:nil]; }); } @end @interface AppDelegate : NSObject { VISIRenderer* m_renderer; NSWindow* m_window; NSOpenGLView* m_glView; int m_instanceIdx; } - (id)initWithRenderer:(VISIRenderer*)renderer instIdx:(int)instIdx; @end @implementation AppDelegate - (id)initWithRenderer:(VISIRenderer*)renderer instIdx:(int)instIdx { self = [super init]; m_renderer = renderer; m_instanceIdx = instIdx; return self; } - (void)applicationDidFinishLaunching:(NSNotification*)notification { int x = 0; int y = 0; if (m_instanceIdx != -1) { x = (m_instanceIdx & 1) != 0; y = (m_instanceIdx & 2) != 0; } NSRect cRect = NSMakeRect(x * 768, y * 534, 768, 512); m_window = [[NSWindow alloc] initWithContentRect:cRect styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable backing:NSBackingStoreBuffered defer:NO]; m_window.releasedWhenClosed = NO; m_window.title = @"VISIGen"; s_Window = m_window; m_glView = [[OpenGLView alloc] initWithFrame:cRect renderer:m_renderer]; m_window.contentView = m_glView; [m_window makeKeyAndOrderFront:nil]; } - (void)applicationWillTerminate:(NSNotification*)notification { m_renderer->Terminate(); if (s_task.joinable()) s_task.join(); exit(m_renderer->ReturnVal()); } @end static logvisor::Module AthenaLog("Athena"); static void AthenaExc(athena::error::Level level, const char* /*file*/, const char*, int /*line*/, fmt::string_view fmt, fmt::format_args args) { AthenaLog.vreport(logvisor::Level(level), fmt, args); } int main(int argc, char** argv) { if (argc > 1 && !strcmp(argv[1], "--dlpackage")) { fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE); return 100; } logvisor::RegisterStandardExceptions(); logvisor::RegisterConsoleLogger(); atSetExceptionHandler(AthenaExc); VISIRenderer renderer(argc, argv); int instIdx = -1; if (argc > 3) instIdx = atoi(argv[3]); @autoreleasepool { [[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular]; /* Delegate (OS X callbacks) */ AppDelegate* appDelegate = [[AppDelegate alloc] initWithRenderer:&renderer instIdx:instIdx]; [[NSApplication sharedApplication] setDelegate:appDelegate]; [[NSApplication sharedApplication] run]; } return renderer.ReturnVal(); }