Added a hint to control the Windows timer resolution: SDL_HINT_TIMER_RESOLUTION

Added an API to watch hint changes: SDL_AddHintCallback(), SDL_DelHintCallback()
You can now dynamically set the joystick background event hint.
This commit is contained in:
Sam Lantinga 2013-07-13 03:13:41 -07:00
parent 9102ff84ca
commit 6956070880
7 changed files with 212 additions and 89 deletions

View file

@ -67,7 +67,6 @@
04F7808512FB753F00FC43C0 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */; }; 04F7808512FB753F00FC43C0 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */; };
04FFAB8B12E23B8D00BA343D /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; }; 04FFAB8B12E23B8D00BA343D /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; };
04FFAB8C12E23B8D00BA343D /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; }; 04FFAB8C12E23B8D00BA343D /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; };
22C905CD13A22646003FE4E4 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C905CC13A22646003FE4E4 /* SDL_hints_c.h */; };
56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */; }; 56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */; };
56EA86FC13E9EC2B002E47EB /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */; }; 56EA86FC13E9EC2B002E47EB /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */; };
56ED04E1118A8EE200A56AA6 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; }; 56ED04E1118A8EE200A56AA6 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; };
@ -260,7 +259,6 @@
04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_nullframebuffer.c; sourceTree = "<group>"; }; 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_nullframebuffer.c; sourceTree = "<group>"; };
04FFAB8912E23B8D00BA343D /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; }; 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_atomic.c; sourceTree = "<group>"; };
04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_spinlock.c; sourceTree = "<group>"; }; 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_spinlock.c; sourceTree = "<group>"; };
22C905CC13A22646003FE4E4 /* SDL_hints_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_hints_c.h; path = ../../src/SDL_hints_c.h; sourceTree = "<group>"; };
56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_coreaudio.c; path = coreaudio/SDL_coreaudio.c; sourceTree = "<group>"; }; 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_coreaudio.c; path = coreaudio/SDL_coreaudio.c; sourceTree = "<group>"; };
56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_coreaudio.h; path = coreaudio/SDL_coreaudio.h; sourceTree = "<group>"; }; 56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_coreaudio.h; path = coreaudio/SDL_coreaudio.h; sourceTree = "<group>"; };
56ED04E0118A8EE200A56AA6 /* SDL_power.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_power.c; path = ../../src/power/SDL_power.c; sourceTree = SOURCE_ROOT; }; 56ED04E0118A8EE200A56AA6 /* SDL_power.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_power.c; path = ../../src/power/SDL_power.c; sourceTree = SOURCE_ROOT; };
@ -747,7 +745,6 @@
FD99B9D60DD52EDC00FB1D6B /* SDL_fatal.c */, FD99B9D60DD52EDC00FB1D6B /* SDL_fatal.c */,
FD99B9D70DD52EDC00FB1D6B /* SDL_fatal.h */, FD99B9D70DD52EDC00FB1D6B /* SDL_fatal.h */,
0442EC5412FE1C3F004C9285 /* SDL_hints.c */, 0442EC5412FE1C3F004C9285 /* SDL_hints.c */,
22C905CC13A22646003FE4E4 /* SDL_hints_c.h */,
04BAC09B1300C1290055DE28 /* SDL_log.c */, 04BAC09B1300C1290055DE28 /* SDL_log.c */,
FD99B9D80DD52EDC00FB1D6B /* SDL.c */, FD99B9D80DD52EDC00FB1D6B /* SDL.c */,
); );
@ -967,7 +964,6 @@
0442EC5012FE1C1E004C9285 /* SDL_render_sw_c.h in Headers */, 0442EC5012FE1C1E004C9285 /* SDL_render_sw_c.h in Headers */,
0402A85A12FE70C600CECEE3 /* SDL_shaders_gles2.h in Headers */, 0402A85A12FE70C600CECEE3 /* SDL_shaders_gles2.h in Headers */,
04BAC09C1300C1290055DE28 /* SDL_assert_c.h in Headers */, 04BAC09C1300C1290055DE28 /* SDL_assert_c.h in Headers */,
22C905CD13A22646003FE4E4 /* SDL_hints_c.h in Headers */,
56EA86FC13E9EC2B002E47EB /* SDL_coreaudio.h in Headers */, 56EA86FC13E9EC2B002E47EB /* SDL_coreaudio.h in Headers */,
93CB792313FC5E5200BD3E05 /* SDL_uikitviewcontroller.h in Headers */, 93CB792313FC5E5200BD3E05 /* SDL_uikitviewcontroller.h in Headers */,
AA628ADC159369E3005138DD /* SDL_rotate.h in Headers */, AA628ADC159369E3005138DD /* SDL_rotate.h in Headers */,

View file

@ -218,13 +218,13 @@ extern "C" {
/** /**
* \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background.
* *
* The default value is "0".
*
* The variable can be set to the following values: * The variable can be set to the following values:
* "0" - Disable joystick & gamecontroller input events when the * "0" - Disable joystick & gamecontroller input events when the
* application is in the background. * application is in the background.
* "1" - Enable joystick & gamecontroller input events when the * "1" - Enable joystick & gamecontroller input events when the
* application is in the backgroumd. * application is in the backgroumd.
*
* The default value is "0". This hint may be set at any time.
*/ */
#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" #define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
@ -240,6 +240,23 @@ extern "C" {
#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST" #define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST"
/**
* \brief A variable that controls the timer resolution, in milliseconds.
*
* The higher resolution the timer, the more frequently the CPU services
* timer interrupts, and the more precise delays are, but this takes up
* power and CPU time. This hint is only used on Windows 7 and earlier.
*
* See this blog post for more information:
* http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/
*
* If this variable is set to "0", the system timer resolution is not set.
*
* The default value is "1". This hint may be set at any time.
*/
#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION"
/** /**
* \brief An enumeration of hint priorities * \brief An enumeration of hint priorities
@ -273,7 +290,6 @@ extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name,
extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
const char *value); const char *value);
/** /**
* \brief Get a hint * \brief Get a hint
* *
@ -281,6 +297,29 @@ extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
*/ */
extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
/**
* \brief Add a function to watch a particular hint
*
* \param name The hint to watch
* \param callback The function to call when the hint value changes
* \param userdata A pointer to pass to the callback function
*/
typedef void (*SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue);
extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name,
SDL_HintCallback callback,
void *userdata);
/**
* \brief Remove a function watching a particular hint
*
* \param name The hint being watched
* \param callback The function being called when the hint value changes
* \param userdata A pointer being passed to the callback function
*/
extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name,
SDL_HintCallback callback,
void *userdata);
/** /**
* \brief Clear all hints * \brief Clear all hints
* *

View file

@ -21,43 +21,35 @@
#include "SDL_config.h" #include "SDL_config.h"
#include "SDL_hints.h" #include "SDL_hints.h"
#include "SDL_hints_c.h" #include "SDL_error.h"
/* Assuming there aren't many hints set and they aren't being queried in /* Assuming there aren't many hints set and they aren't being queried in
critical performance paths, we'll just use a linked list here. critical performance paths, we'll just use linked lists here.
*/ */
typedef struct SDL_HintWatch {
SDL_HintCallback callback;
void *userdata;
struct SDL_HintWatch *next;
} SDL_HintWatch;
typedef struct SDL_Hint { typedef struct SDL_Hint {
char *name; char *name;
char *value; char *value;
SDL_HintPriority priority; SDL_HintPriority priority;
SDL_HintChangedCb callback; SDL_HintWatch *callbacks;
struct SDL_Hint *next; struct SDL_Hint *next;
} SDL_Hint; } SDL_Hint;
static SDL_Hint *SDL_hints; static SDL_Hint *SDL_hints;
SDL_bool
SDL_RegisterHintChangedCb(const char *name, SDL_HintChangedCb hintCb)
{
SDL_Hint *hint;
for (hint = SDL_hints; hint; hint = hint->next) {
if (SDL_strcmp(name, hint->name) == 0) {
hint->callback = hintCb;
return SDL_TRUE;
}
}
return SDL_FALSE;
}
SDL_bool SDL_bool
SDL_SetHintWithPriority(const char *name, const char *value, SDL_SetHintWithPriority(const char *name, const char *value,
SDL_HintPriority priority) SDL_HintPriority priority)
{ {
const char *env; const char *env;
SDL_Hint *hint; SDL_Hint *hint;
SDL_HintWatch *entry;
if (!name || !value) { if (!name || !value) {
return SDL_FALSE; return SDL_FALSE;
@ -73,12 +65,21 @@ SDL_SetHintWithPriority(const char *name, const char *value,
if (priority < hint->priority) { if (priority < hint->priority) {
return SDL_FALSE; return SDL_FALSE;
} }
if (SDL_strcmp(hint->value, value) != 0) { if (!hint->value || !value || SDL_strcmp(hint->value, value) != 0) {
if (hint->callback != NULL) { for (entry = hint->callbacks; entry; ) {
(*hint->callback)(name, hint->value, value); /* Save the next entry in case this one is deleted */
SDL_HintWatch *next = entry->next;
entry->callback(entry->userdata, name, hint->value, value);
entry = next;
} }
if (hint->value) {
SDL_free(hint->value); SDL_free(hint->value);
}
if (value) {
hint->value = SDL_strdup(value); hint->value = SDL_strdup(value);
} else {
hint->value = NULL;
}
} }
hint->priority = priority; hint->priority = priority;
return SDL_TRUE; return SDL_TRUE;
@ -91,9 +92,9 @@ SDL_SetHintWithPriority(const char *name, const char *value,
return SDL_FALSE; return SDL_FALSE;
} }
hint->name = SDL_strdup(name); hint->name = SDL_strdup(name);
hint->value = SDL_strdup(value); hint->value = value ? SDL_strdup(value) : NULL;
hint->priority = priority; hint->priority = priority;
hint->callback = NULL; hint->callbacks = NULL;
hint->next = SDL_hints; hint->next = SDL_hints;
SDL_hints = hint; SDL_hints = hint;
return SDL_TRUE; return SDL_TRUE;
@ -123,16 +124,100 @@ SDL_GetHint(const char *name)
return env; return env;
} }
void
SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
{
SDL_Hint *hint;
SDL_HintWatch *entry;
const char *value;
if (!name || !*name) {
SDL_InvalidParamError("name");
return;
}
if (!callback) {
SDL_InvalidParamError("callback");
return;
}
SDL_DelHintCallback(name, callback, userdata);
entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry));
entry->callback = callback;
entry->userdata = userdata;
for (hint = SDL_hints; hint; hint = hint->next) {
if (SDL_strcmp(name, hint->name) == 0) {
break;
}
}
if (!hint) {
/* Need to add a hint entry for this watcher */
hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
if (!hint) {
return;
}
hint->name = SDL_strdup(name);
hint->value = NULL;
hint->priority = SDL_HINT_DEFAULT;
hint->callbacks = NULL;
hint->next = SDL_hints;
SDL_hints = hint;
}
/* Add it to the callbacks for this hint */
entry->next = hint->callbacks;
hint->callbacks = entry;
/* Now call it with the current value */
value = SDL_GetHint(name);
callback(userdata, name, value, value);
}
void
SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
{
SDL_Hint *hint;
SDL_HintWatch *entry, *prev;
for (hint = SDL_hints; hint; hint = hint->next) {
if (SDL_strcmp(name, hint->name) == 0) {
prev = NULL;
for (entry = hint->callbacks; entry; entry = entry->next) {
if (callback == entry->callback && userdata == entry->userdata) {
if (prev) {
prev->next = entry->next;
} else {
hint->callbacks = entry->next;
}
SDL_free(entry);
break;
}
prev = entry;
}
return;
}
}
}
void SDL_ClearHints(void) void SDL_ClearHints(void)
{ {
SDL_Hint *hint; SDL_Hint *hint;
SDL_HintWatch *entry;
while (SDL_hints) { while (SDL_hints) {
hint = SDL_hints; hint = SDL_hints;
SDL_hints = hint->next; SDL_hints = hint->next;
SDL_free(hint->name); SDL_free(hint->name);
if (hint->value) {
SDL_free(hint->value); SDL_free(hint->value);
}
for (entry = hint->callbacks; entry; ) {
SDL_HintWatch *freeable = entry;
entry = entry->next;
SDL_free(freeable);
}
SDL_free(hint); SDL_free(hint);
} }
} }

View file

@ -1,34 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_hints_c_h
#define _SDL_hints_c_h
/**
* \brief A callback function that is optionally called when a hint changes
*/
typedef void (*SDL_HintChangedCb)(const char *name, const char *oldValue, const char *newValue);
extern SDL_bool SDL_RegisterHintChangedCb(const char *name, SDL_HintChangedCb hintCb);
#endif /* _SDL_hints_c_h */
/* vi: set ts=4 sw=4 expandtab: */

View file

@ -36,17 +36,24 @@ static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE;
static SDL_Joystick *SDL_joysticks = NULL; static SDL_Joystick *SDL_joysticks = NULL;
static SDL_Joystick *SDL_updating_joystick = NULL; static SDL_Joystick *SDL_updating_joystick = NULL;
static void
SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
if (hint && *hint == '1') {
SDL_joystick_allows_background_events = SDL_TRUE;
} else {
SDL_joystick_allows_background_events = SDL_FALSE;
}
}
int int
SDL_JoystickInit(void) SDL_JoystickInit(void)
{ {
const char *hint;
int status; int status;
/* Check to see if we should allow joystick events while in the background */ /* See if we should allow joystick events while in the background */
hint = SDL_GetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS); SDL_AddHintCallback(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS,
if (hint && *hint == '1') { SDL_JoystickAllowBackgroundEventsChanged, NULL);
SDL_joystick_allows_background_events = SDL_TRUE;
}
#if !SDL_EVENTS_DISABLED #if !SDL_EVENTS_DISABLED
if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) { if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) {

View file

@ -26,8 +26,8 @@
#include <mmsystem.h> #include <mmsystem.h>
#include "SDL_timer.h" #include "SDL_timer.h"
#include "SDL_hints.h"
#define TIME_WRAP_VALUE (~(DWORD)0)
/* The first (low-resolution) ticks value of the application */ /* The first (low-resolution) ticks value of the application */
static DWORD start; static DWORD start;
@ -41,6 +41,40 @@ static LARGE_INTEGER hires_start_ticks;
static LARGE_INTEGER hires_ticks_per_second; static LARGE_INTEGER hires_ticks_per_second;
#endif #endif
static void
timeSetPeriod(UINT uPeriod)
{
static UINT timer_period = 0;
if (uPeriod != timer_period) {
if (timer_period) {
timeEndPeriod(timer_period);
}
timer_period = uPeriod;
if (timer_period) {
timeBeginPeriod(timer_period);
}
}
}
static void
SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
UINT uPeriod;
/* Unless the hint says otherwise, let's have good sleep precision */
if (hint && *hint) {
uPeriod = SDL_atoi(hint);
} else {
uPeriod = 1;
}
if (uPeriod || oldValue != hint) {
timeSetPeriod(uPeriod);
}
}
void void
SDL_StartTicks(void) SDL_StartTicks(void)
{ {
@ -56,16 +90,19 @@ SDL_StartTicks(void)
QueryPerformanceCounter(&hires_start_ticks); QueryPerformanceCounter(&hires_start_ticks);
} else { } else {
hires_timer_available = FALSE; hires_timer_available = FALSE;
timeBeginPeriod(1); /* use 1 ms timer precision */ timeSetPeriod(1); /* use 1 ms timer precision */
start = timeGetTime(); start = timeGetTime();
} }
#endif #endif
SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION,
SDL_TimerResolutionChanged, NULL);
} }
Uint32 Uint32
SDL_GetTicks(void) SDL_GetTicks(void)
{ {
DWORD now, ticks; DWORD now;
#ifndef USE_GETTICKCOUNT #ifndef USE_GETTICKCOUNT
LARGE_INTEGER hires_now; LARGE_INTEGER hires_now;
#endif #endif
@ -86,12 +123,7 @@ SDL_GetTicks(void)
} }
#endif #endif
if (now < start) { return (now - start);
ticks = (TIME_WRAP_VALUE - start) + now;
} else {
ticks = (now - start);
}
return (ticks);
} }
Uint64 Uint64

View file

@ -25,7 +25,6 @@
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
#include "SDL_assert.h" #include "SDL_assert.h"
#include "SDL_hints.h" #include "SDL_hints.h"
#include "../../SDL_hints_c.h"
#include "SDL_system.h" #include "SDL_system.h"
#include "SDL_main.h" #include "SDL_main.h"
@ -69,11 +68,10 @@ int main(int argc, char **argv)
return exit_status; return exit_status;
} }
static void SDL_IdleTimerDisabledChanged(const char *name, const char *oldValue, const char *newValue) static void
SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{ {
SDL_assert(SDL_strcmp(name, SDL_HINT_IDLE_TIMER_DISABLED) == 0); BOOL disable = (hint && *hint != '0');
BOOL disable = (*newValue != '0');
[UIApplication sharedApplication].idleTimerDisabled = disable; [UIApplication sharedApplication].idleTimerDisabled = disable;
} }
@ -218,8 +216,8 @@ static void SDL_IdleTimerDisabledChanged(const char *name, const char *oldValue,
[[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]]; [[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
/* register a callback for the idletimer hint */ /* register a callback for the idletimer hint */
SDL_SetHint(SDL_HINT_IDLE_TIMER_DISABLED, "0"); SDL_AddHintCallback(SDL_HINT_IDLE_TIMER_DISABLED,
SDL_RegisterHintChangedCb(SDL_HINT_IDLE_TIMER_DISABLED, &SDL_IdleTimerDisabledChanged); SDL_IdleTimerDisabledChanged, NULL);
SDL_SetMainReady(); SDL_SetMainReady();
[self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0]; [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0];