src/timer/riscos/SDL_systimer.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 12 Feb 2005 18:01:31 +0000
changeset 1035 974ba6ae0fa3
parent 955 d74fbf56f2f6
child 1312 c9b51268668f
permissions -rw-r--r--
Date: Wed, 26 Jan 2005 13:37:09 GMT
From: Peter Naulls
Subject: RISC OS SDL Patches

Sam, I've attached a diff of the latest changes to libSDL for RISC OS
support. These changes are by Alan Buckley and myself.

The most significant of these are:

Optimised assembler blit rountines - I've attached the file
src/video/riscos/SDL_riscosASM.s which is needed for this.

Move to using /dev/dsp instead of its own audio implementation.
This means that src/audio/riscos/SDL_drenderer.c should be removed

Typo fixes. Mainly correct spelling of "RISC OS", but some from elsewhere
too.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@devolution.com
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #include <stdio.h>
    29 #include <time.h>
    30 #include <sys/time.h>
    31 #include <unistd.h>
    32 #include <string.h>
    33 #include <errno.h>
    34 
    35 #include "SDL_error.h"
    36 #include "SDL_timer.h"
    37 #include "SDL_timer_c.h"
    38 
    39 #ifdef DISABLE_THREADS
    40 /* Timer start/reset time */
    41 static Uint32 timerStart;
    42 /* Timer running function */
    43 void RISCOS_CheckTimer();
    44 #else
    45 #include <pthread.h>
    46 extern Uint32 riscos_main_thread;
    47 extern int riscos_using_threads;
    48 extern Uint32 SDL_ThreadID();
    49 extern Uint32 SDL_EventThreadID(void);
    50 #endif
    51 
    52 
    53 extern void RISCOS_BackgroundTasks(void);
    54 
    55 /* The first ticks value of the application */
    56 clock_t start;
    57 
    58 void SDL_StartTicks(void)
    59 {
    60 	/* Set first ticks value */
    61 	start = clock();
    62 }
    63 
    64 Uint32 SDL_GetTicks (void)
    65 {
    66 	clock_t ticks;
    67 
    68 	ticks=clock()-start;
    69 
    70 
    71 #if CLOCKS_PER_SEC == 1000
    72 
    73 	return(ticks);
    74 
    75 #elif CLOCKS_PER_SEC == 100
    76 
    77 	return (ticks * 10);
    78 
    79 #else
    80 
    81 	return ticks*(1000/CLOCKS_PER_SEC);
    82 
    83 #endif
    84 
    85 }
    86 
    87 void SDL_Delay (Uint32 ms)
    88 {
    89     Uint32 now,then,elapsed;
    90 #ifndef DISABLE_THREADS
    91     int is_event_thread;
    92     if (riscos_using_threads)
    93     {
    94        is_event_thread = 0;
    95        if (SDL_EventThreadID())
    96        {
    97           if (SDL_EventThreadID() == SDL_ThreadID()) is_event_thread = 1;
    98        } else if (SDL_ThreadID() == riscos_main_thread) is_event_thread = 1;
    99     } else is_event_thread = 1;
   100 #endif
   101 
   102         /*TODO: Next version of Unixlib may allow us to use usleep here */
   103         /*      for non event threads */
   104 
   105 	/* Set the timeout interval - Linux only needs to do this once */
   106 	then = SDL_GetTicks();
   107 
   108 	do {
   109 		/* Do background tasks required while sleeping as we are not multithreaded */
   110 #ifdef DISABLE_THREADS
   111 		RISCOS_BackgroundTasks();
   112 #else
   113 		/* For threaded build only run background tasks in event thread */
   114 		if (is_event_thread) RISCOS_BackgroundTasks();
   115 #endif
   116 
   117 		/* Calculate the time interval left (in case of interrupt) */
   118 		now = SDL_GetTicks();
   119 		elapsed = (now-then);
   120 		then = now;
   121 		if ( elapsed >= ms ) {
   122 			break;
   123 		}
   124 		ms -= elapsed;
   125 #ifndef DISABLE_THREADS
   126             /* Need to yield to let other threads have a go */
   127             if (riscos_using_threads) pthread_yield();
   128 #endif
   129 
   130 	} while ( 1 );
   131 }
   132 
   133 #ifdef DISABLE_THREADS
   134 
   135 /* Non-threaded version of timer */
   136 
   137 int SDL_SYS_TimerInit(void)
   138 {
   139 	return(0);
   140 }
   141 
   142 void SDL_SYS_TimerQuit(void)
   143 {
   144 	SDL_SetTimer(0, NULL);
   145 }
   146 
   147 int SDL_SYS_StartTimer(void)
   148 {
   149 	timerStart = SDL_GetTicks();
   150 
   151 	return(0);
   152 }
   153 
   154 void SDL_SYS_StopTimer(void)
   155 {
   156 	/* Don't need to do anything as we use SDL_timer_running
   157 	   to detect if we need to check the timer */
   158 }
   159 
   160 
   161 void RISCOS_CheckTimer()
   162 {
   163 	if (SDL_timer_running && SDL_GetTicks() - timerStart >= SDL_alarm_interval)
   164 	{
   165 		Uint32 ms;
   166 
   167 		ms = SDL_alarm_callback(SDL_alarm_interval);
   168 		if ( ms != SDL_alarm_interval )
   169 		{
   170 			if ( ms )
   171 			{
   172 				SDL_alarm_interval = ROUND_RESOLUTION(ms);
   173 			} else
   174 			{
   175 				SDL_alarm_interval = 0;
   176 				SDL_timer_running = 0;
   177 			}
   178 		}
   179 		if (SDL_alarm_interval) timerStart = SDL_GetTicks();
   180 	}
   181 }
   182 
   183 #else
   184 
   185 /* Threaded version of timer - based on code for linux */
   186 
   187 #include "SDL_thread.h"
   188 
   189 /* Data to handle a single periodic alarm */
   190 static int timer_alive = 0;
   191 static SDL_Thread *timer = NULL;
   192 
   193 static int RunTimer(void *unused)
   194 {
   195 	while ( timer_alive ) {
   196 		if ( SDL_timer_running ) {
   197 			SDL_ThreadedTimerCheck();
   198 		}
   199 		SDL_Delay(1);
   200 	}
   201 	return(0);
   202 }
   203 
   204 /* This is only called if the event thread is not running */
   205 int SDL_SYS_TimerInit(void)
   206 {
   207 	timer_alive = 1;
   208 	timer = SDL_CreateThread(RunTimer, NULL);
   209 	if ( timer == NULL )
   210 		return(-1);
   211 	return(SDL_SetTimerThreaded(1));
   212 }
   213 
   214 void SDL_SYS_TimerQuit(void)
   215 {
   216 	timer_alive = 0;
   217 	if ( timer ) {
   218 		SDL_WaitThread(timer, NULL);
   219 		timer = NULL;
   220 	}
   221 }
   222 
   223 int SDL_SYS_StartTimer(void)
   224 {
   225 	SDL_SetError("Internal logic error: RISC OS uses threaded timer");
   226 	return(-1);
   227 }
   228 
   229 void SDL_SYS_StopTimer(void)
   230 {
   231 	return;
   232 }
   233 
   234 #endif /* DISABLE_THREADS */