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