1// Cross-platform free Puyo-Puyo clone.
2// Copyright (C) 2006, 2007 Emma's Software
3// Based on the work of Darrel Walisser <dwaliss1@purdue.edu> and
4// Max Horn <max@quendi.de>.
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19//
20#import <sys/param.h> // for MAXPATHLEN. */
21#import <unistd.h>
22#import <SDL.h>
23#import "AmoebaxMain.h"
24
25#if defined (main)
26#undef main
27#endif // main
28
29// Global variables where the command line arguments gets stored,
30// so we can pass them to SDL_main later.
31static int g_argc;
32static char **g_argv;
33
34@interface Amoebax: NSApplication
35@end
36
37@implementation Amoebax
38///
39/// \brief Posts a SQL_QUIT event.
40///
41/// This is called from the `Quit' menu item.
42///
43- (void)terminate: (id)sender
44{
45    SDL_Event quitEvent;
46
47    quitEvent.type = SDL_QUIT;
48    SDL_PushEvent (&quitEvent);
49}
50
51///
52/// \brief Ignores keystrokes which doesn't use the the Command key.
53///
54-(void)sendEvent: (NSEvent *)event
55{
56    if ( NSKeyDown == [event type] || NSKeyUp == [event type] )
57    {
58        if ( NSCommandKeyMask == ([event modifierFlags] & NSCommandKeyMask) )
59        {
60            [super sendEvent: event];
61        }
62    }
63    else
64    {
65        [super sendEvent: event];
66    }
67}
68@end
69
70@implementation AmoebaxMain
71///
72/// \brief Sets the working directory to the bundle's resource directory.
73///
74- (void)setupWorkingDirectory: (BOOL)shouldChdir
75{
76    if ( shouldChdir )
77    {
78        char resourcesDirectory[MAXPATHLEN];
79        CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ());
80        if ( CFURLGetFileSystemRepresentation (resourcesUrl, true, (UInt8 *)resourcesDirectory, MAXPATHLEN) )
81        {
82            assert ( chdir (resourcesDirectory) == 0 );
83        }
84        CFRelease (resourcesUrl);
85    }
86}
87
88///
89/// \brief Gets called when the internal event loop has just started running.
90///
91- (void)applicationDidFinishLaunching: (NSNotification *)note
92{
93    [self setupWorkingDirectory:true];
94    int status = SDL_main (g_argc, g_argv);
95    // Done!
96    exit (status);
97}
98@end
99
100///
101/// \brief Shows an alert.
102///
103/// \param title The alert's title.
104/// \param error The error message.
105///
106void
107OSXAlert (const char *title, const char *error)
108{
109    NSRunAlertPanel ([NSString stringWithCString: title],
110                     [NSString stringWithCString: error],
111                     [NSString stringWithCString: "OK"], nil, nil);
112}
113
114///
115/// \brief Main entry point of executable. Should *not* be SDL_main!
116///
117int
118main (int argc, char **argv)
119{
120    // This is passed if we are launched by double-clicking. */
121    if ( 2 <= argc && strncmp (argv[1], "-psn", 4) == 0 )
122    {
123        g_argc = 1;
124        g_argv = (char **)SDL_malloc (sizeof (char *) * 2);
125        g_argv[0] = argv[0];
126        g_argv[1] = NULL;
127    }
128    else
129    {
130        int currentArgument = 0;
131
132        g_argc = argc;
133        g_argv = (char **)SDL_malloc (sizeof (char *) * (argc + 1));
134        for ( currentArgument = 0 ; currentArgument <= argc ; ++currentArgument )
135        {
136            g_argv[currentArgument] = argv[currentArgument];
137        }
138    }
139    [Amoebax poseAsClass:[NSApplication class]];
140    NSApplicationMain (argc, (const char **)argv);
141
142    return 0;
143}
144