Updated SDL 1.3 to the latest hg-5868:33245988e8a2 , video resize is not supported yet

This commit is contained in:
pelya
2011-12-05 19:46:32 +02:00
parent 2fe92bdcf9
commit aae35bbf37
678 changed files with 35446 additions and 77654 deletions

View File

@@ -1,42 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* The system dependent timer handling functions */
#include "SDL_timer.h"
#include "SDL_timer_c.h"
/* Initialize the system dependent timer subsystem */
extern int SDL_SYS_TimerInit(void);
/* Quit the system dependent timer subsystem */
extern void SDL_SYS_TimerQuit(void);
/* Start a timer set up by SDL_SetTimer() */
extern int SDL_SYS_StartTimer(void);
/* Stop a previously started timer */
extern void SDL_SYS_StopTimer(void);
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,300 +1,386 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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:
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
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.
*/
#include "SDL_config.h"
#include "SDL_timer.h"
#include "SDL_timer_c.h"
#include "SDL_mutex.h"
#include "SDL_systimer.h"
#include "SDL_atomic.h"
#include "SDL_cpuinfo.h"
#include "SDL_thread.h"
/* #define DEBUG_TIMERS */
int SDL_timer_started = 0;
int SDL_timer_running = 0;
/* Data to handle a single periodic alarm */
Uint32 SDL_alarm_interval = 0;
SDL_TimerCallback SDL_alarm_callback;
/* Data used for a thread-based timer */
static int SDL_timer_threaded = 0;
struct _SDL_TimerID
typedef struct _SDL_Timer
{
Uint32 interval;
SDL_NewTimerCallback cb;
int timerID;
SDL_TimerCallback callback;
void *param;
Uint32 last_alarm;
struct _SDL_TimerID *next;
};
Uint32 interval;
Uint32 scheduled;
volatile SDL_bool canceled;
struct _SDL_Timer *next;
} SDL_Timer;
static SDL_TimerID SDL_timers = NULL;
static SDL_mutex *SDL_timer_mutex;
static volatile SDL_bool list_changed = SDL_FALSE;
/* Set whether or not the timer should use a thread.
This should not be called while the timer subsystem is running.
*/
int
SDL_SetTimerThreaded(int value)
typedef struct _SDL_TimerMap
{
int retval;
int timerID;
SDL_Timer *timer;
struct _SDL_TimerMap *next;
} SDL_TimerMap;
if (SDL_timer_started) {
SDL_SetError("Timer already initialized");
retval = -1;
} else {
retval = 0;
SDL_timer_threaded = value;
/* The timers are kept in a sorted list */
typedef struct {
/* Data used by the main thread */
SDL_Thread *thread;
SDL_atomic_t nextID;
SDL_TimerMap *timermap;
SDL_mutex *timermap_lock;
/* Padding to separate cache lines between threads */
char cache_pad[SDL_CACHELINE_SIZE];
/* Data used to communicate with the timer thread */
SDL_SpinLock lock;
SDL_sem *sem;
SDL_Timer * volatile pending;
SDL_Timer * volatile freelist;
volatile SDL_bool active;
/* List of timers - this is only touched by the timer thread */
SDL_Timer *timers;
} SDL_TimerData;
static SDL_TimerData SDL_timer_data;
/* The idea here is that any thread might add a timer, but a single
* thread manages the active timer queue, sorted by scheduling time.
*
* Timers are removed by simply setting a canceled flag
*/
static void
SDL_AddTimerInternal(SDL_TimerData *data, SDL_Timer *timer)
{
SDL_Timer *prev, *curr;
prev = NULL;
for (curr = data->timers; curr; prev = curr, curr = curr->next) {
if ((Sint32)(timer->scheduled-curr->scheduled) < 0) {
break;
}
}
return retval;
/* Insert the timer here! */
if (prev) {
prev->next = timer;
} else {
data->timers = timer;
}
timer->next = curr;
}
static int
SDL_TimerThread(void *_data)
{
SDL_TimerData *data = (SDL_TimerData *)_data;
SDL_Timer *pending;
SDL_Timer *current;
SDL_Timer *freelist_head = NULL;
SDL_Timer *freelist_tail = NULL;
Uint32 tick, now, interval, delay;
/* Threaded timer loop:
* 1. Queue timers added by other threads
* 2. Handle any timers that should dispatch this cycle
* 3. Wait until next dispatch time or new timer arrives
*/
for ( ; ; ) {
/* Pending and freelist maintenance */
SDL_AtomicLock(&data->lock);
{
/* Get any timers ready to be queued */
pending = data->pending;
data->pending = NULL;
/* Make any unused timer structures available */
if (freelist_head) {
freelist_tail->next = data->freelist;
data->freelist = freelist_head;
}
}
SDL_AtomicUnlock(&data->lock);
/* Sort the pending timers into our list */
while (pending) {
current = pending;
pending = pending->next;
SDL_AddTimerInternal(data, current);
}
freelist_head = NULL;
freelist_tail = NULL;
/* Check to see if we're still running, after maintenance */
if (!data->active) {
break;
}
/* Initial delay if there are no timers */
delay = SDL_MUTEX_MAXWAIT;
tick = SDL_GetTicks();
/* Process all the pending timers for this tick */
while (data->timers) {
current = data->timers;
if ((Sint32)(tick-current->scheduled) < 0) {
/* Scheduled for the future, wait a bit */
delay = (current->scheduled - tick);
break;
}
/* We're going to do something with this timer */
data->timers = current->next;
if (current->canceled) {
interval = 0;
} else {
interval = current->callback(current->interval, current->param);
}
if (interval > 0) {
/* Reschedule this timer */
current->scheduled = tick + interval;
SDL_AddTimerInternal(data, current);
} else {
if (!freelist_head) {
freelist_head = current;
}
if (freelist_tail) {
freelist_tail->next = current;
}
freelist_tail = current;
current->canceled = SDL_TRUE;
}
}
/* Adjust the delay based on processing time */
now = SDL_GetTicks();
interval = (now - tick);
if (interval > delay) {
delay = 0;
} else {
delay -= interval;
}
/* Note that each time a timer is added, this will return
immediately, but we process the timers added all at once.
That's okay, it just means we run through the loop a few
extra times.
*/
SDL_SemWaitTimeout(data->sem, delay);
}
return 0;
}
int
SDL_TimerInit(void)
{
int retval;
SDL_TimerData *data = &SDL_timer_data;
retval = 0;
if (SDL_timer_started) {
SDL_TimerQuit();
if (!data->active) {
const char *name = "SDLTimer";
data->timermap_lock = SDL_CreateMutex();
if (!data->timermap_lock) {
return -1;
}
data->sem = SDL_CreateSemaphore(0);
if (!data->sem) {
SDL_DestroyMutex(data->timermap_lock);
return -1;
}
data->active = SDL_TRUE;
/* !!! FIXME: this is nasty. */
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
#undef SDL_CreateThread
data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL);
#else
data->thread = SDL_CreateThread(SDL_TimerThread, name, data);
#endif
if (!data->thread) {
SDL_TimerQuit();
return -1;
}
SDL_AtomicSet(&data->nextID, 1);
}
if (!SDL_timer_threaded) {
retval = SDL_SYS_TimerInit();
}
if (SDL_timer_threaded) {
SDL_timer_mutex = SDL_CreateMutex();
}
if (retval == 0) {
SDL_timer_started = 1;
}
return (retval);
return 0;
}
void
SDL_TimerQuit(void)
{
SDL_SetTimer(0, NULL);
if (SDL_timer_threaded < 2) {
SDL_SYS_TimerQuit();
}
if (SDL_timer_threaded) {
SDL_DestroyMutex(SDL_timer_mutex);
SDL_timer_mutex = NULL;
}
SDL_timer_started = 0;
SDL_timer_threaded = 0;
}
SDL_TimerData *data = &SDL_timer_data;
SDL_Timer *timer;
SDL_TimerMap *entry;
void
SDL_ThreadedTimerCheck(void)
{
Uint32 now, ms;
SDL_TimerID t, prev, next;
SDL_bool removed;
if (data->active) {
data->active = SDL_FALSE;
SDL_mutexP(SDL_timer_mutex);
list_changed = SDL_FALSE;
now = SDL_GetTicks();
for (prev = NULL, t = SDL_timers; t; t = next) {
removed = SDL_FALSE;
ms = t->interval - SDL_TIMESLICE;
next = t->next;
if ((int) (now - t->last_alarm) > (int) ms) {
struct _SDL_TimerID timer;
if ((now - t->last_alarm) < t->interval) {
t->last_alarm += t->interval;
} else {
t->last_alarm = now;
}
#ifdef DEBUG_TIMERS
printf("Executing timer %p (thread = %lu)\n", t, SDL_ThreadID());
#endif
timer = *t;
SDL_mutexV(SDL_timer_mutex);
ms = timer.cb(timer.interval, timer.param);
SDL_mutexP(SDL_timer_mutex);
if (list_changed) {
/* Abort, list of timers modified */
/* FIXME: what if ms was changed? */
break;
}
if (ms != t->interval) {
if (ms) {
t->interval = ROUND_RESOLUTION(ms);
} else {
/* Remove timer from the list */
#ifdef DEBUG_TIMERS
printf("SDL: Removing timer %p\n", t);
#endif
if (prev) {
prev->next = next;
} else {
SDL_timers = next;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
}
}
/* Shutdown the timer thread */
if (data->thread) {
SDL_SemPost(data->sem);
SDL_WaitThread(data->thread, NULL);
data->thread = NULL;
}
/* Don't update prev if the timer has disappeared */
if (!removed) {
prev = t;
}
}
SDL_mutexV(SDL_timer_mutex);
}
static SDL_TimerID
SDL_AddTimerInternal(Uint32 interval, SDL_NewTimerCallback callback,
void *param)
{
SDL_TimerID t;
t = (SDL_TimerID) SDL_malloc(sizeof(struct _SDL_TimerID));
if (t) {
t->interval = ROUND_RESOLUTION(interval);
t->cb = callback;
t->param = param;
t->last_alarm = SDL_GetTicks();
t->next = SDL_timers;
SDL_timers = t;
++SDL_timer_running;
list_changed = SDL_TRUE;
SDL_DestroySemaphore(data->sem);
data->sem = NULL;
/* Clean up the timer entries */
while (data->timers) {
timer = data->timers;
data->timers = timer->next;
SDL_free(timer);
}
while (data->freelist) {
timer = data->freelist;
data->freelist = timer->next;
SDL_free(timer);
}
while (data->timermap) {
entry = data->timermap;
data->timermap = entry->next;
SDL_free(entry);
}
SDL_DestroyMutex(data->timermap_lock);
data->timermap_lock = NULL;
}
#ifdef DEBUG_TIMERS
printf("SDL_AddTimer(%d) = %08x num_timers = %d\n", interval, (Uint32) t,
SDL_timer_running);
#endif
return t;
}
SDL_TimerID
SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param)
SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
{
SDL_TimerID t;
if (!SDL_timer_mutex) {
if (SDL_timer_started) {
SDL_SetError("This platform doesn't support multiple timers");
} else {
SDL_SetError("You must call SDL_Init(SDL_INIT_TIMER) first");
SDL_TimerData *data = &SDL_timer_data;
SDL_Timer *timer;
SDL_TimerMap *entry;
if (!data->active) {
int status = 0;
SDL_AtomicLock(&data->lock);
if (!data->active) {
status = SDL_TimerInit();
}
SDL_AtomicUnlock(&data->lock);
if (status < 0) {
return 0;
}
return NULL;
}
if (!SDL_timer_threaded) {
SDL_SetError("Multiple timers require threaded events!");
return NULL;
SDL_AtomicLock(&data->lock);
timer = data->freelist;
if (timer) {
data->freelist = timer->next;
}
SDL_mutexP(SDL_timer_mutex);
t = SDL_AddTimerInternal(interval, callback, param);
SDL_mutexV(SDL_timer_mutex);
return t;
SDL_AtomicUnlock(&data->lock);
if (timer) {
SDL_RemoveTimer(timer->timerID);
} else {
timer = (SDL_Timer *)SDL_malloc(sizeof(*timer));
if (!timer) {
SDL_OutOfMemory();
return 0;
}
}
timer->timerID = SDL_AtomicIncRef(&data->nextID);
timer->callback = callback;
timer->param = param;
timer->interval = interval;
timer->scheduled = SDL_GetTicks() + interval;
timer->canceled = SDL_FALSE;
entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry));
if (!entry) {
SDL_free(timer);
SDL_OutOfMemory();
return 0;
}
entry->timer = timer;
entry->timerID = timer->timerID;
SDL_mutexP(data->timermap_lock);
entry->next = data->timermap;
data->timermap = entry;
SDL_mutexV(data->timermap_lock);
/* Add the timer to the pending list for the timer thread */
SDL_AtomicLock(&data->lock);
timer->next = data->pending;
data->pending = timer;
SDL_AtomicUnlock(&data->lock);
/* Wake up the timer thread if necessary */
SDL_SemPost(data->sem);
return entry->timerID;
}
SDL_bool
SDL_RemoveTimer(SDL_TimerID id)
{
SDL_TimerID t, prev = NULL;
SDL_bool removed;
SDL_TimerData *data = &SDL_timer_data;
SDL_TimerMap *prev, *entry;
SDL_bool canceled = SDL_FALSE;
removed = SDL_FALSE;
SDL_mutexP(SDL_timer_mutex);
/* Look for id in the linked list of timers */
for (t = SDL_timers; t; prev = t, t = t->next) {
if (t == id) {
/* Find the timer */
SDL_mutexP(data->timermap_lock);
prev = NULL;
for (entry = data->timermap; entry; prev = entry, entry = entry->next) {
if (entry->timerID == id) {
if (prev) {
prev->next = t->next;
prev->next = entry->next;
} else {
SDL_timers = t->next;
data->timermap = entry->next;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
list_changed = SDL_TRUE;
break;
}
}
#ifdef DEBUG_TIMERS
printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %lu\n",
(Uint32) id, removed, SDL_timer_running, SDL_ThreadID());
#endif
SDL_mutexV(SDL_timer_mutex);
return removed;
}
SDL_mutexV(data->timermap_lock);
/* Old style callback functions are wrapped through this */
static Uint32 SDLCALL
callback_wrapper(Uint32 ms, void *param)
{
SDL_TimerCallback func = (SDL_TimerCallback) param;
return (*func) (ms);
}
int
SDL_SetTimer(Uint32 ms, SDL_TimerCallback callback)
{
int retval;
#ifdef DEBUG_TIMERS
printf("SDL_SetTimer(%d)\n", ms);
#endif
retval = 0;
if (SDL_timer_threaded) {
SDL_mutexP(SDL_timer_mutex);
}
if (SDL_timer_running) { /* Stop any currently running timer */
if (SDL_timer_threaded) {
while (SDL_timers) {
SDL_TimerID freeme = SDL_timers;
SDL_timers = SDL_timers->next;
SDL_free(freeme);
}
SDL_timer_running = 0;
list_changed = SDL_TRUE;
} else {
SDL_SYS_StopTimer();
SDL_timer_running = 0;
if (entry) {
if (!entry->timer->canceled) {
entry->timer->canceled = SDL_TRUE;
canceled = SDL_TRUE;
}
SDL_free(entry);
}
if (ms) {
if (SDL_timer_threaded) {
if (SDL_AddTimerInternal
(ms, callback_wrapper, (void *) callback) == NULL) {
retval = -1;
}
} else {
SDL_timer_running = 1;
SDL_alarm_interval = ms;
SDL_alarm_callback = callback;
retval = SDL_SYS_StartTimer();
}
}
if (SDL_timer_threaded) {
SDL_mutexV(SDL_timer_mutex);
}
return retval;
return canceled;
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,23 +1,22 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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:
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
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.
*/
#include "SDL_config.h"
@@ -27,21 +26,7 @@
#define ROUND_RESOLUTION(X) \
(((X+TIMER_RESOLUTION-1)/TIMER_RESOLUTION)*TIMER_RESOLUTION)
extern int SDL_timer_started;
extern int SDL_timer_running;
/* Data to handle a single periodic alarm */
extern Uint32 SDL_alarm_interval;
extern SDL_TimerCallback SDL_alarm_callback;
/* Set whether or not the timer should use a thread.
This should be called while the timer subsystem is running.
*/
extern int SDL_SetTimerThreaded(int value);
extern int SDL_TimerInit(void);
extern void SDL_TimerQuit(void);
/* This function is called from the SDL event thread if it is available */
extern void SDL_ThreadedTimerCheck(void);
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,23 +1,22 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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:
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
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.
*/
#include "SDL_config.h"
@@ -25,9 +24,7 @@
#include <be/kernel/OS.h>
#include "SDL_thread.h"
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
static bigtime_t start;
@@ -44,61 +41,24 @@ SDL_GetTicks(void)
return ((system_time() - start) / 1000);
}
Uint64
SDL_GetPerformanceCounter(void)
{
return system_time();
}
Uint64
SDL_GetPerformanceFrequency(void)
{
return 1000000;
}
void
SDL_Delay(Uint32 ms)
{
snooze(ms * 1000);
}
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int
RunTimer(void *unused)
{
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
}
return (0);
}
/* This is only called if the event thread is not running */
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: BeOS uses threaded timer");
return (-1);
}
void
SDL_SYS_StopTimer(void)
{
return;
}
#endif /* SDL_TIMER_BEOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,30 +1,28 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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:
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
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.
*/
#include "SDL_config.h"
#if defined(SDL_TIMER_DUMMY) || defined(SDL_TIMERS_DISABLED)
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
void
SDL_StartTicks(void)
@@ -38,63 +36,24 @@ SDL_GetTicks(void)
return 0;
}
Uint64
SDL_GetPerformanceCounter(void)
{
return SDL_GetTicks();
}
Uint64
SDL_GetPerformanceFrequency(void)
{
return 1000;
}
void
SDL_Delay(Uint32 ms)
{
SDL_Unsupported();
}
#include "SDL_thread.h"
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int
RunTimer(void *unused)
{
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return (0);
}
/* This is only called if the event thread is not running */
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: threaded timer in use");
return (-1);
}
void
SDL_SYS_StopTimer(void)
{
return;
}
#endif /* SDL_TIMER_DUMMY || SDL_TIMERS_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,23 +1,22 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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:
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
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.
*/
#include "SDL_config.h"
@@ -27,22 +26,23 @@
#include <nds/timers.h>
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
#include "../SDL_systimer.h"
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static Uint32 timer_ticks;
/* Will wrap after 49 days. Shouldn't be an issue. */
static volatile Uint32 timer_ticks;
static void
NDS_TimerInterrupt(void)
{
timer_ticks++;
}
void
SDL_StartTicks(void)
{
if (!timer_alive) {
SDL_SYS_TimerInit();
SDL_SYS_StartTimer();
}
timer_ticks = 0;
/* Set timer 2 to fire every ms. */
timerStart(2, ClockDivider_1024, TIMER_FREQ_1024(1000), NDS_TimerInterrupt);
}
Uint32
@@ -51,70 +51,28 @@ SDL_GetTicks(void)
return timer_ticks;
}
Uint64
SDL_GetPerformanceCounter(void)
{
return SDL_GetTicks();
}
Uint64
SDL_GetPerformanceFrequency(void)
{
return 1000;
}
void
SDL_Delay(Uint32 ms)
{
Uint32 start = SDL_GetTicks();
while (timer_alive) {
while (1) {
if ((SDL_GetTicks() - start) >= ms)
break;
}
}
static int
RunTimer(void *unused)
{
while (timer_alive) {
if (SDL_timer_running) {
}
SDL_Delay(1);
}
return (0);
}
void
NDS_TimerInterrupt(void)
{
timer_ticks++;
}
/* This is only called if the event thread is not running */
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer_ticks = 0;
TIMER_CR(3) = TIMER_DIV_1024 | TIMER_IRQ_REQ;
TIMER_DATA(3) = TIMER_FREQ_1024(1000);
irqSet(IRQ_TIMER3, NDS_TimerInterrupt);
irqEnable(IRQ_TIMER3);
return 0;
}
void
SDL_SYS_TimerQuit(void)
{
if (timer_alive) {
TIMER_CR(3) = 0;
}
timer_alive = 0;
irqDisable(IRQ_TIMER3);
}
int
SDL_SYS_StartTimer(void)
{
TIMER_CR(3) |= TIMER_ENABLE;
return 0;
}
void
SDL_SYS_StopTimer(void)
{
TIMER_CR(3) &= ~TIMER_ENABLE;
return;
}
#endif /* SDL_TIMER_NDS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,248 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifdef SDL_TIMER_RISCOS
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
#if SDL_THREADS_DISABLED
/* Timer SDL_arraysize(Timer ),start/reset time */
static Uint32 timerStart;
/* Timer running function */
void RISCOS_CheckTimer();
#else
#include <pthread.h>
extern SDL_threadID riscos_main_thread;
extern int riscos_using_threads;
extern SDL_threadID SDL_ThreadID();
extern SDL_threadID SDL_EventThreadID(void);
#endif
extern void RISCOS_BackgroundTasks(void);
/* The first ticks value of the application */
clock_t start;
void
SDL_StartTicks(void)
{
/* Set first ticks value */
start = clock();
}
Uint32
SDL_GetTicks(void)
{
clock_t ticks;
ticks = clock() - start;
#if CLOCKS_PER_SEC == 1000
return (ticks);
#elif CLOCKS_PER_SEC == 100
return (ticks * 10);
#else
return ticks * (1000 / CLOCKS_PER_SEC);
#endif
}
void
SDL_Delay(Uint32 ms)
{
Uint32 now, then, elapsed;
#if !SDL_THREADS_DISABLED
int is_event_thread;
if (riscos_using_threads) {
is_event_thread = 0;
if (SDL_EventThreadID()) {
if (SDL_EventThreadID() == SDL_ThreadID())
is_event_thread = 1;
} else if (SDL_ThreadID() == riscos_main_thread)
is_event_thread = 1;
} else
is_event_thread = 1;
#endif
/*TODO: Next version of Unixlib may allow us to use usleep here */
/* for non event threads */
/* Set the timeout interval - Linux only needs to do this once */
then = SDL_GetTicks();
do {
/* Do background tasks required while sleeping as we are not multithreaded */
#if SDL_THREADS_DISABLED
RISCOS_BackgroundTasks();
#else
/* For threaded build only run background tasks in event thread */
if (is_event_thread)
RISCOS_BackgroundTasks();
#endif
/* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks();
elapsed = (now - then);
then = now;
if (elapsed >= ms) {
break;
}
ms -= elapsed;
#if !SDL_THREADS_DISABLED
/* Need to yield to let other threads have a go */
if (riscos_using_threads)
pthread_yield();
#endif
} while (1);
}
#if SDL_THREADS_DISABLED
/* Non-threaded version of timer */
int
SDL_SYS_TimerInit(void)
{
return (0);
}
void
SDL_SYS_TimerQuit(void)
{
SDL_SetTimer(0, NULL);
}
int
SDL_SYS_StartTimer(void)
{
timerStart = SDL_GetTicks();
return (0);
}
void
SDL_SYS_StopTimer(void)
{
/* Don't need to do anything as we use SDL_timer_running
to detect if we need to check the timer */
}
void
RISCOS_CheckTimer()
{
if (SDL_timer_running
&& SDL_GetTicks() - timerStart >= SDL_alarm_interval) {
Uint32 ms;
ms = SDL_alarm_callback(SDL_alarm_interval);
if (ms != SDL_alarm_interval) {
if (ms) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
} else {
SDL_alarm_interval = 0;
SDL_timer_running = 0;
}
}
if (SDL_alarm_interval)
timerStart = SDL_GetTicks();
}
}
#else
/* Threaded version of timer - based on code for linux */
#include "SDL_thread.h"
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int
RunTimer(void *unused)
{
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return (0);
}
/* This is only called if the event thread is not running */
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: RISC OS uses threaded timer");
return (-1);
}
void
SDL_SYS_StopTimer(void)
{
return;
}
#endif /* SDL_THREADS_DISABLED */
#endif /* SDL_TIMER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,23 +1,22 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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:
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
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.
*/
#include "SDL_config.h"
@@ -25,14 +24,10 @@
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "SDL_timer.h"
#include "../SDL_systimer.h"
#include "../SDL_timer_c.h"
/* The clock_gettime provides monotonous time, so we should use it if
it's available. The clock_gettime function is behind ifdef
@@ -43,10 +38,6 @@
#include <time.h>
#endif
#if SDL_THREADS_DISABLED
#define USE_ITIMER
#endif
/* The first ticks value of the application */
#ifdef HAVE_CLOCK_GETTIME
static struct timespec start;
@@ -72,6 +63,7 @@ SDL_GetTicks(void)
#if HAVE_CLOCK_GETTIME
Uint32 ticks;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
@@ -80,6 +72,7 @@ SDL_GetTicks(void)
#else
Uint32 ticks;
struct timeval now;
gettimeofday(&now, NULL);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
@@ -88,6 +81,40 @@ SDL_GetTicks(void)
#endif
}
Uint64
SDL_GetPerformanceCounter(void)
{
#if HAVE_CLOCK_GETTIME
Uint64 ticks;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
ticks = now.tv_sec;
ticks *= 1000000000;
ticks += now.tv_nsec;
return (ticks);
#else
Uint64 ticks;
struct timeval now;
gettimeofday(&now, NULL);
ticks = now.tv_sec;
ticks *= 1000000;
ticks += now.tv_usec;
return (ticks);
#endif
}
Uint64
SDL_GetPerformanceFrequency(void)
{
#if HAVE_CLOCK_GETTIME
return 1000000000;
#else
return 1000000;
#endif
}
void
SDL_Delay(Uint32 ms)
{
@@ -131,118 +158,6 @@ SDL_Delay(Uint32 ms)
} while (was_error && (errno == EINTR));
}
#ifdef USE_ITIMER
static void
HandleAlarm(int sig)
{
Uint32 ms;
if (SDL_alarm_callback) {
ms = (*SDL_alarm_callback) (SDL_alarm_interval);
if (ms != SDL_alarm_interval) {
SDL_SetTimer(ms, SDL_alarm_callback);
}
}
}
int
SDL_SYS_TimerInit(void)
{
struct sigaction action;
/* Set the alarm handler (Linux specific) */
SDL_memset(&action, 0, sizeof(action));
action.sa_handler = HandleAlarm;
action.sa_flags = SA_RESTART;
sigemptyset(&action.sa_mask);
sigaction(SIGALRM, &action, NULL);
return (0);
}
void
SDL_SYS_TimerQuit(void)
{
SDL_SetTimer(0, NULL);
}
int
SDL_SYS_StartTimer(void)
{
struct itimerval timer;
timer.it_value.tv_sec = (SDL_alarm_interval / 1000);
timer.it_value.tv_usec = (SDL_alarm_interval % 1000) * 1000;
timer.it_interval.tv_sec = (SDL_alarm_interval / 1000);
timer.it_interval.tv_usec = (SDL_alarm_interval % 1000) * 1000;
setitimer(ITIMER_REAL, &timer, NULL);
return (0);
}
void
SDL_SYS_StopTimer(void)
{
struct itimerval timer;
SDL_memset(&timer, 0, (sizeof timer));
setitimer(ITIMER_REAL, &timer, NULL);
}
#else /* USE_ITIMER */
#include "SDL_thread.h"
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int
RunTimer(void *unused)
{
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return (0);
}
/* This is only called if the event thread is not running */
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: Linux uses threaded timer");
return (-1);
}
void
SDL_SYS_StopTimer(void)
{
return;
}
#endif /* USE_ITIMER */
#endif /* SDL_TIMER_UNIX */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,165 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifdef SDL_TIMER_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
#ifdef _WIN32_WCE
#error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead.
#endif
#define TIME_WRAP_VALUE (~(DWORD)0)
/* The first (low-resolution) ticks value of the application */
static DWORD start;
#ifndef USE_GETTICKCOUNT
/* Store if a high-resolution performance counter exists on the system */
static BOOL hires_timer_available;
/* The first high-resolution ticks value of the application */
static LARGE_INTEGER hires_start_ticks;
/* The number of ticks per second of the high-resolution performance counter */
static LARGE_INTEGER hires_ticks_per_second;
#endif
void
SDL_StartTicks(void)
{
/* Set first ticks value */
#ifdef USE_GETTICKCOUNT
start = GetTickCount();
#else
#if 0 /* Apparently there are problems with QPC on Win2K */
if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) {
hires_timer_available = TRUE;
QueryPerformanceCounter(&hires_start_ticks);
} else
#endif
{
hires_timer_available = FALSE;
timeBeginPeriod(1); /* use 1 ms timer precision */
start = timeGetTime();
}
#endif
}
Uint32
SDL_GetTicks(void)
{
DWORD now, ticks;
#ifndef USE_GETTICKCOUNT
LARGE_INTEGER hires_now;
#endif
#ifdef USE_GETTICKCOUNT
now = GetTickCount();
#else
if (hires_timer_available) {
QueryPerformanceCounter(&hires_now);
hires_now.QuadPart -= hires_start_ticks.QuadPart;
hires_now.QuadPart *= 1000;
hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
return (DWORD) hires_now.QuadPart;
} else {
now = timeGetTime();
}
#endif
if (now < start) {
ticks = (TIME_WRAP_VALUE - start) + now;
} else {
ticks = (now - start);
}
return (ticks);
}
void
SDL_Delay(Uint32 ms)
{
Sleep(ms);
}
/* Data to handle a single periodic alarm */
static UINT timerID = 0;
static void CALLBACK
HandleAlarm(UINT uID, UINT uMsg, DWORD_PTR dwUser,
DWORD_PTR dw1, DWORD_PTR dw2)
{
SDL_ThreadedTimerCheck();
}
int
SDL_SYS_TimerInit(void)
{
MMRESULT result;
/* Set timer resolution */
result = timeBeginPeriod(TIMER_RESOLUTION);
if (result != TIMERR_NOERROR) {
SDL_SetError("Warning: Can't set %d ms timer resolution",
TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID =
timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC);
if (!timerID) {
SDL_SetError("timeSetEvent() failed");
return (-1);
}
return (SDL_SetTimerThreaded(1));
}
void
SDL_SYS_TimerQuit(void)
{
if (timerID) {
timeKillEvent(timerID);
}
timeEndPeriod(TIMER_RESOLUTION);
}
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: Win32 uses threaded timer");
return (-1);
}
void
SDL_SYS_StopTimer(void)
{
return;
}
#endif /* SDL_TIMER_WIN32 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,35 +1,30 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
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:
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
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.
*/
#include "SDL_config.h"
#ifdef SDL_TIMER_WINCE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include "../../core/windows/SDL_windows.h"
#include "SDL_thread.h"
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
static Uint64 start_date;
static Uint64 start_ticks;
@@ -70,6 +65,14 @@ wce_rel_date(void)
return ((Sint32) (wce_date() - start_date));
}
/* Recard start-time of application for reference */
void
SDL_StartTicks(void)
{
start_date = wce_date();
start_ticks = wce_ticks();
}
/* Return time in ms relative to when SDL was started */
Uint32
SDL_GetTicks()
@@ -83,6 +86,18 @@ SDL_GetTicks()
return ((Uint32) wce_rel_ticks());
}
Uint64
SDL_GetPerformanceCounter(void)
{
return SDL_GetTicks();
}
Uint64
SDL_GetPerformanceFrequency(void)
{
return 1000;
}
/* Give up approx. givem milliseconds to the OS. */
void
SDL_Delay(Uint32 ms)
@@ -90,122 +105,6 @@ SDL_Delay(Uint32 ms)
Sleep(ms);
}
/* Recard start-time of application for reference */
void
SDL_StartTicks(void)
{
start_date = wce_date();
start_ticks = wce_ticks();
}
static UINT WIN_timer;
#if ( _WIN32_WCE <= 420 )
static HANDLE timersThread = 0;
static HANDLE timersQuitEvent = 0;
DWORD
TimersThreadProc(void *data)
{
while (WaitForSingleObject(timersQuitEvent, 10) == WAIT_TIMEOUT) {
SDL_ThreadedTimerCheck();
}
return 0;
}
int
SDL_SYS_TimerInit(void)
{
// create a thread to process a threaded timers
// SetTimer does not suit the needs because
// TimerCallbackProc will be called only when WM_TIMER occured
timersQuitEvent = CreateEvent(0, TRUE, FALSE, 0);
if (!timersQuitEvent) {
SDL_SetError("Cannot create event for timers thread");
return -1;
}
timersThread = CreateThread(NULL, 0, TimersThreadProc, 0, 0, 0);
if (!timersThread) {
SDL_SetError
("Cannot create timers thread, check amount of RAM available");
return -1;
}
SetThreadPriority(timersThread, THREAD_PRIORITY_HIGHEST);
return (SDL_SetTimerThreaded(1));
}
void
SDL_SYS_TimerQuit(void)
{
SetEvent(timersQuitEvent);
if (WaitForSingleObject(timersThread, 2000) == WAIT_TIMEOUT)
TerminateThread(timersThread, 0);
CloseHandle(timersThread);
CloseHandle(timersQuitEvent);
return;
}
#else
#pragma comment(lib, "mmtimer.lib")
/* Data to handle a single periodic alarm */
static UINT timerID = 0;
static void CALLBACK
HandleAlarm(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
SDL_ThreadedTimerCheck();
}
int
SDL_SYS_TimerInit(void)
{
MMRESULT result;
/* Set timer resolution */
result = timeBeginPeriod(TIMER_RESOLUTION);
if (result != TIMERR_NOERROR) {
SDL_SetError("Warning: Can't set %d ms timer resolution",
TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID =
timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC);
if (!timerID) {
SDL_SetError("timeSetEvent() failed");
return (-1);
}
return (SDL_SetTimerThreaded(1));
}
void
SDL_SYS_TimerQuit(void)
{
if (timerID) {
timeKillEvent(timerID);
}
timeEndPeriod(TIMER_RESOLUTION);
}
#endif
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: WinCE uses threaded timer");
return (-1);
}
void
SDL_SYS_StopTimer(void)
{
return;
}
#endif /* SDL_TIMER_WINCE */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,131 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2011 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.
*/
#include "SDL_config.h"
#ifdef SDL_TIMER_WINDOWS
#include "../../core/windows/SDL_windows.h"
#include <mmsystem.h>
#include "SDL_timer.h"
#ifdef _WIN32_WCE
#error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead.
#endif
#define TIME_WRAP_VALUE (~(DWORD)0)
/* The first (low-resolution) ticks value of the application */
static DWORD start;
#ifndef USE_GETTICKCOUNT
/* Store if a high-resolution performance counter exists on the system */
static BOOL hires_timer_available;
/* The first high-resolution ticks value of the application */
static LARGE_INTEGER hires_start_ticks;
/* The number of ticks per second of the high-resolution performance counter */
static LARGE_INTEGER hires_ticks_per_second;
#endif
void
SDL_StartTicks(void)
{
/* Set first ticks value */
#ifdef USE_GETTICKCOUNT
start = GetTickCount();
#else
#if 0 /* Apparently there are problems with QPC on Win2K */
if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) {
hires_timer_available = TRUE;
QueryPerformanceCounter(&hires_start_ticks);
} else
#endif
{
hires_timer_available = FALSE;
timeBeginPeriod(1); /* use 1 ms timer precision */
start = timeGetTime();
}
#endif
}
Uint32
SDL_GetTicks(void)
{
DWORD now, ticks;
#ifndef USE_GETTICKCOUNT
LARGE_INTEGER hires_now;
#endif
#ifdef USE_GETTICKCOUNT
now = GetTickCount();
#else
if (hires_timer_available) {
QueryPerformanceCounter(&hires_now);
hires_now.QuadPart -= hires_start_ticks.QuadPart;
hires_now.QuadPart *= 1000;
hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
return (DWORD) hires_now.QuadPart;
} else {
now = timeGetTime();
}
#endif
if (now < start) {
ticks = (TIME_WRAP_VALUE - start) + now;
} else {
ticks = (now - start);
}
return (ticks);
}
Uint64
SDL_GetPerformanceCounter(void)
{
LARGE_INTEGER counter;
if (!QueryPerformanceCounter(&counter)) {
return SDL_GetTicks();
}
return counter.QuadPart;
}
Uint64
SDL_GetPerformanceFrequency(void)
{
LARGE_INTEGER frequency;
if (!QueryPerformanceFrequency(&frequency)) {
return 1000;
}
return frequency.QuadPart;
}
void
SDL_Delay(Uint32 ms)
{
Sleep(ms);
}
#endif /* SDL_TIMER_WINDOWS */
/* vi: set ts=4 sw=4 expandtab: */