macOS Cocoa: fix reshape, resize, and fullscreen handling#42
Conversation
- Add reshape method to MyOpenGLView: was registered as selector but never defined, so window resize never updated game screen info. Now calls InitDeviceScreenInfoEx with correct bounds + openGLContext update. - Remove premature OnResizeFinished call from windowWillResize (used old bounds before resize completed). windowDidResize -> reshape is now the single correct path for all resize and fullscreen transitions. - Remove redundant GetBaseApp()->Init() from prepareOpenGL: InitDeviceScreenInfoEx already guards with IsInitted() and owns the init call.
|
@SethRobinson without these changes modern Macs will not open, because Macs don’t support support direct SDL anymore. |
- OSXUtils.h/mm: add OSXToggleFullscreen() using dispatch_async + [window toggleFullScreen:nil] so App.cpp can call it from C++ without importing Cocoa headers in a .cpp file. - MainController.mm: add windowDidEnterFullScreen/windowDidExitFullScreen delegates to track g_bIsFullScreen and update the fullscreen var, and call reshape on exit to restore correct viewport.
…clarations - Remove goFullScreen:, goWindow, OnResizeFinished declarations (not implemented, fullscreen now handled via OSXToggleFullscreen/toggleFullScreen: delegate). - Remove old fullscreen ivar block (fullScreenWindow, fullScreenView, CGLContextObj). - Add App.h import so GetApp() is available in MainController.mm.
|
@SethRobinson I wait that migration to Cocoa in Mac to be completed. |
The NSTimer was starting before prepareOpenGL was called, so IsInitted() was always false and drawRect never ran the game. Now we explicitly call makeCurrentContext + prepareOpenGL (which calls InitDeviceScreenInfoEx -> GetBaseApp()->Init()) before starting the timer, guaranteeing the game is initialized when the first frame fires.
…unds prepareOpenGL is called lazily by the system. At awakeFromNib time the view bounds are zero, so calling it there initializes with 0x0 screen size and the game never starts. Instead: - awakeFromNib: just sets up timer and working directory (no init) - drawRect: if not yet initted and bounds are valid (>0), call prepareOpenGL now - this is the first moment we have real screen size
…artup logging - Remove NSOpenGLPFAWindow (deprecated macOS 10.14+, may silently fail context creation) - Add NSOpenGLProfileVersionLegacy for compatibility with OpenGL 2.x code - Add fallback pixel format if primary fails - Add NSLog in drawRect and prepareOpenGL to diagnose startup issues
Calling drawRect: directly from a timer bypasses the macOS display system and the OpenGL context may not be properly current. Using [self display] triggers the proper display cycle ensuring the context is set up correctly before drawing.
The app was silently exiting because the window was never made visible. applicationShouldTerminateAfterLastWindowClosed returns YES, so if the window never appears macOS terminates the app immediately. Force the main window to front after launch.
…O, return NO from shouldTerminateAfterLastWindowClosed, terminate on windowWillClose
…ved-resolution support
…ode/resolution changes never being processed
|
@SethRobinson let's explain correct, this PR only change files to work in mac, don't change multiplatform. |
…. Luxton wired) - was only handling SDL_CONTROLLERDEVICEADDED
|
@SethRobinson do you have a official controller? |
|
@SethRobinson gamepad still untested, this PR #42 can now be merged. |
|
An official controller for Proton? No, the goal is just to support as many popular ones as possible. I'd prefer not to review things until they are tested (ie, arm, controller support). Keep in mind you can put up a build on your fork and ask for testing. Please clearly let me know which parts are tested on real hardware and untested vibe code |
|
@SethRobinson this changes in Proton dont change just the controller, but the main thing is implemented Cocoa Windows functions on Mac. |
|
@SethRobinson without Cocoa functions in Proton the game on Mac doesn't work, Mac does not support direct SDL anymore. |
|
@SethRobinson I tested on Mac Intel, and Arm with MacInCloud (not real Mac MacInCloud) the game Works but without gamepad, the Luketon is just a example, i am testing with gamepad but i don't know if it is problem in Driver on Mac. |
|
Proton has its own apps designed to test (generally this is a lot easier than a big external game like Dink as they are tiny) RTBareBones -> Test app/windowing (super basic) If you can get these demo/example apps to work on Mac, it will allow Proton users to have a working example without getting Dink If this is out of scope for you to do (ie, you only really need dink working), I understand. In that case maybe just put up your Dink build and wait for me to do this when I get more time |
|
@SethRobinson The shared OSX/app/ fixes (MainController.mm, MyOpenGLView.mm) are already structured to work for all Proton apps — they use the same shared code. RTSimpleApp already has PLATFORM_OSX defined. RTBareBones and RTLooneyLadders just need PLATFORM_OSX added to their Xcode preprocessor definitions (same one-line fix done for RTDink). |
|
@SethRobinson I can get RTBareBones working on macOS — it's minimal and has no audio dependency. For RTSimpleApp and RTLooneyLadders, the blocker is FMOD: they use it for audio on macOS, and I'd need to either switch them to SDL audio (like I did for RTDink) or skip audio. RTLooneyLadders also has no OSX Xcode project at all and would need one created from scratch. I'm happy to do RTBareBones now as a clean point for the PR. |
AudioManagerFMODStudio.cpp was still in the Sources build phase causing 'fmod.h not found' compile error. Remove all FMOD references: - AudioManagerFMODStudio.cpp/h from Sources, file refs, and Audio group - libfmod.dylib from Frameworks build phase, file ref, and Frameworks group - CopyFiles build phase (was only used to embed libfmod.dylib)
…anager RTSimpleApp does not have a GamepadManager instance, so the PLATFORM_OSX block calling GetGamepadManager()->AddProvider(new GamepadProviderSDL2()) caused 'member access into incomplete type GamepadManager' compile error. Remove: - SDL_Init + GamepadProviderSDL2 from App::Init - SDL_PumpEvents/SDL_PeepEvents event drain from App::Update - Unused GamepadProviderSDL2.h, SDL2/SDL.h includes - g_sig_SDLEvent definition (not needed without event pump) AudioManagerSDL handles its own SDL init internally.
All three apps (RTSimpleApp, RTBareBones, RTLooneyLadders) were failing with undefined _png_* linker errors because libpng was not compiled in. RTDink compiles libpng from source (shared/Irrlicht/source/Irrlicht/libpng/). Apply the same approach to all three demo projects: - Add all 15 libpng .c files to Sources build phase - Add file references and libpng group in project navigator - Copy pnglibconf.h from pnglibconf.h.prebuilt (required by libpng headers)
Add arm_init.c, filter_neon_intrinsics.c, palette_neon_intrinsics.c from libpng/arm/ to fix undefined _png_*_neon linker errors on ARM64. Also add EXCLUDED_SOURCE_FILE_NAMES[arch=x86_64] to exclude these ARM-only files when building for Intel, matching RTDink's approach.
… apps Two linker errors in RTSimpleApp (and potentially RTBareBones/RTLooneyLadders): 1. _LogMsg undefined: RT_CUSTOM_LOGMSG was set in all 3 Xcode projects, which suppresses LogMsg definition in OSXUtils.mm. The demo apps have no custom LogMsg, so remove RT_CUSTOM_LOGMSG from all 3 projects. 2. _g_bIsFullScreen (shown as _p_linearScreen in linker output) undefined: This global is defined in SDL2Main.cpp for SDL builds, but the OSX Cocoa build does not compile SDL2Main.cpp. Add definition in each App.cpp for the PLATFORM_OSX / macOS branch.
…and RTLooneyLadders
…nd RTLooneyLadders OSX projects
…ded Dink Smallwood HD
… add update_media note to README
…dProviderSDL2, GamepadSDL2, etc.)
…er errors Add ArcadeInputComponent, DPadComponent, EmitVirtualKeyComponent, EmitVirtualKeyComponentAdvanced, and TouchHandlerArcadeComponent to the Xcode project build phases. These were referenced by game code but missing from the pbxproj, causing undefined symbol linker errors.
… error LogDisplayComponent.cpp defines SetConsole(bool, bool) which is called by ControllerTestMenu.cpp but was missing from the Xcode project.
TouchDragComponent.cpp is included by LogDisplayComponent.cpp (for the scrollable console widget) but was missing from the Xcode project.
…ow bug MainController.mm now creates the window programmatically in applicationDidFinishLaunching. The XIB window definition was still present, causing two windows to appear on launch. Remove the <window> block and the openGLView outlet from both XIBs so only the programmatic window is created.
Same fix as RTSimpleApp/RTLooneyLadders: MainController.mm creates the window programmatically, so the XIB window block and openGLView outlet are removed to prevent a second blank window on launch.
The Release XCBuildConfiguration was missing the closing }; for its buildSettings block, causing Xcode to report a parse error and refuse to open the project.
GetApp() returns the app-specific subclass which may not have GetVar (e.g. RTBareBones). GetBaseApp()->GetVar() works for all apps.
Neither BaseApp nor all App subclasses have GetVar. The global g_bIsFullScreen flag is sufficient for OSX fullscreen tracking.
These files provide JPEG loading support (RT_JPG_SUPPORT is defined in the build settings) but were missing from the Xcode project, causing undefined symbol linker errors.
|
@SethRobinson now I tested and the three examples are working, Dink Smallworld HD continues working on Mac, in Dink code I just removed the code that change Proton SDK because nil->0 script in Dink code that is not necessary anymore because in commit c21614d I fixed that.
PS: sorry to just fix these problems today (in Monday), Sunday (yesterday) I was making public competition to possible be an analyst in Brazilian Parliament. |
|
Ok, I'm merging these now (found some minor issues I want to fix first, but will push in an hour or two probably) |
|
Ok, I merged, worked ok - a few notes:
The gamepad does not work - but I think it's an SDL2/Mac issue. Gamepad Support on macOS (Cocoa build path) During testing of PR #42, I found that SDL2 gamepad detection doesn't work in the native Cocoa build path (RTLooneyLadders). The Xbox controller is recognized by macOS (visible in System Settings > Game Controllers) but SDL2 never sees it. This is because SDL2's joystick subsystem conflicts with the Cocoa NSApplication run loop - SDL2 expects to own the event loop, but in our Cocoa builds it doesn't. The fix for a future PR would be to create a new GamepadProviderGCController (similar to the existing GamepadProviderSDL2) that uses Apple's native Game Controller framework (GameController. framework / GCController). This integrates natively with the Cocoa run loop and supports Xbox, PlayStation, Switch Pro, and MFi controllers out of the box. Key APIs: [GCController controllers] for enumeration, the extendedGamepad profile for button/axis mapping, and GCController notifications for connect/disconnect. However - please do not submit a Mac gamepad PR unless it's actually been tested with real gamepads. <--- important! |
|
@SethRobinson sorry to not work, i can make another PR trying to work joystick, perhaps its the problem of joystick of Dink Smallwood HD. |
|
No worries. LooneyLadders is the Proton joystick/gamepad testing app, if it works there, it should work ok with Dink |
|
@SethRobinson if you want you can merge, SethRobinson/RTDink#23 PR, but I warn, will not work joystick on Mac util fixed Lonely Ladders. |



Add reshape method to MyOpenGLView: was registered as selector but never defined, so window resize never updated game screen info. Now calls InitDeviceScreenInfoEx with correct bounds + openGLContext update.
Remove premature OnResizeFinished call from windowWillResize (used old bounds before resize completed). windowDidResize -> reshape is now the single correct path for all resize and fullscreen transitions.
Remove redundant GetBaseApp()->Init() from prepareOpenGL: InitDeviceScreenInfoEx already guards with IsInitted() and owns the init call.
These fixes are macOS Cocoa-only and don't touch Linux/Windows/iOS paths, so they're safe to merge upstream.