Date: Fri, 25 Jun 2004 13:29:15 +0100
authorSam Lantinga <slouken@libsdl.org>
Fri, 17 Sep 2004 13:20:10 +0000
changeset 955d74fbf56f2f6
parent 954 3acd16ea0180
child 956 4263beff9e38
Date: Fri, 25 Jun 2004 13:29:15 +0100
From: "alan buckley"
Subject: Modification for RISC OS version of SDL

Ive attached a zip file with the changes to this email, it contains the
following:

The file sdldiff.txt is the output from cvs diff u. .
The directory thread/riscos contains all the new files to support threading.

Readme.riscos is a new readme file to add.
README.RISCOS
configure.in
src/audio/SDL_audio.c
src/audio/riscos/SDL_drenderer.c
src/thread/riscos/SDL_syscond.c
src/thread/riscos/SDL_sysmutex.c
src/thread/riscos/SDL_sysmutex_c.h
src/thread/riscos/SDL_syssem.c
src/thread/riscos/SDL_systhread.c
src/thread/riscos/SDL_systhread_c.h
src/timer/riscos/SDL_systimer.c
src/video/riscos/SDL_riscosevents.c
src/video/riscos/SDL_riscostask.c
src/video/riscos/SDL_wimppoll.c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/README.RISCOS	Fri Sep 17 13:20:10 2004 +0000
     1.3 @@ -0,0 +1,112 @@
     1.4 +Readme for RISC OS port of SDL
     1.5 +==============================
     1.6 +
     1.7 +This document last updated on 25th June 2004
     1.8 +
     1.9 +This is a RISC OS port of the Simple Direct Media Layer (SDL) by Alan Buckley.
    1.10 +
    1.11 +Details of the SDL can be found at http://www.libsdl.org.
    1.12 +
    1.13 +The source code including the RISC OS version can be obtained from http://www.libsdl.org.
    1.14 +
    1.15 +RISC OS makefiles, pre built libraries and many games and applications compiled for RISC OS using this library can be downloaded from The Unix Porting Project at http://www.chocky.org/unix/index.html.
    1.16 +
    1.17 +This is released under the LGPL see the file COPYING for details.
    1.18 +
    1.19 +
    1.20 +RISCOS port of SDL runtime information
    1.21 +======================================
    1.22 +
    1.23 +Runtime requirements
    1.24 +--------------------
    1.25 +
    1.26 +This library currently needs a minimum of RISCOS 3.6. The source code for the library (and a lot of the programs built with it) also need long file names.
    1.27 +
    1.28 +To use the audio you also need 16 bit sound and to have installed the Digital Render module by Andreas Dehmel version 0.51 available from his web site:
    1.29 +  http://home.t-online.de/~zarquon
    1.30 +
    1.31 +Note: As most programs ported from other OS's use high resolution graphics and a memory back buffer a machine with a StrongARM processor and 1 or 2MB of VRAM (or a better machine) is recomended.
    1.32 +
    1.33 +
    1.34 +RISCOS runtime parameters
    1.35 +-------------------------
    1.36 +
    1.37 +Several environmental variables have been defined to make porting programs easier (i.e. By setting these variable you do not need to have source code differences between OS's).
    1.38 +
    1.39 +They are all defined on an application basis.
    1.40 +
    1.41 +The <appname> used below is found as follows:
    1.42 +1. Use the name of the program unless it is !RunImage
    1.43 +2. Check the folder specification for the folder !RunImage is run from. If it is a folder name use that name, otherwise if it is an environmental variable of the form <XXX$Dir> use the value of XXX.
    1.44 +
    1.45 +The variables are:
    1.46 +
    1.47 +SDL$<appname>$TaskName - The name of the task for RISCOS. If omitted then <appname> is used for the task name,
    1.48 +
    1.49 +SDL$<appname>$BackBuffer - set to 1 to use a system memory back buffer for the screen in full screen mode. Some programs on other systems assume their is always a back buffer even though the SDL specification specifies this is not the case. The current RISCOS implementation uses direct writes to the screen if a hardware fullscreen is requested.
    1.50 +
    1.51 +SDL$<appname>$CloseAction - set the action for the close icon. Again as programs don't match the specification you can set this to 0 to remove the close icon from the main window for applications where this does not affect the program.
    1.52 +
    1.53 +SDL$<appname>$AudioBuffer - set the minimum size of the audio buffer in samples in steps of 512. If this is less than the minimum calculated from the parameters requested in the program by SDL_OpenAudio these will be used instead. If this parameter is not used or set to 0 the buffer size will be calculated to buffer 10 centisecond of sound. The time buffered can be calculated as specified size/frequency in seconds. The larger the buffer the more audio data that will be buffered, but this can lead to a lag between a sound being requested and it being heard, so the size should be kept to a minimum. You should only set this parameter if the sound is being missed out. 
    1.54 +
    1.55 +
    1.56 +
    1.57 +RISCOS SDL port API notes
    1.58 +=========================
    1.59 +
    1.60 +Current level of implementation
    1.61 +-------------------------------
    1.62 +
    1.63 +The following list is an overview of how much of the SDL is implemented. The areas match the main areas of the SDL.
    1.64 +
    1.65 +video - Mostly done. Doesn't cover gamma, YUV-overlay or open gl.
    1.66 +Window Manager - Mostly done. SetIcon/IconifyWindow not implemented.
    1.67 +Events - Mostly done. Resize and some joystick events missing.
    1.68 +Joystick - Currently assumes a single joystick with 4 buttons.
    1.69 +Audio - Requires Digital Renderer module.
    1.70 +CDROM - Not implemented.
    1.71 +Threads - Done
    1.72 +Timers - Done
    1.73 +
    1.74 +Thread support can be removed by defining DISABLE_THREADS and recompiling the library.
    1.75 +
    1.76 +SDL API notes
    1.77 +-------------
    1.78 +
    1.79 +This section contains additional notes on some specific commands.
    1.80 +
    1.81 +SDL_SetVideoMode
    1.82 +  On RISCOS a fullscreen mode directly accesses the screen. This can be modified by the environmental variable (SDL$<appname>$BackBuffer) or by using the SDL_SWSURFACE flag to write to an offscreen buffer that is updated using SDL_UpdateRects.
    1.83 +  Open GL is not supported so SDL_OPENGL and SDL_OPENGLBLIT flags fail.
    1.84 +  SDL_RESIZEABLE and SDL_NOFRAME flags are not supported.
    1.85 +
    1.86 +SDL_SetColors
    1.87 +  In a wimp mode the screen colours are not changed for a hardware palette instead the RISCOS sprite colour mapping is used to get the best matching colours.
    1.88 +
    1.89 +SDL_CreateCursor
    1.90 +   Inverted colour is not supported.
    1.91 +
    1.92 +SDL_WM_ToggleFullScreen
    1.93 +   Currently this won't work if the application starts up in Fullscreen mode.
    1.94 +   Toggling to fullscreen will only work if the monitor is set up to support the exact screen size requested.
    1.95 +
    1.96 +SDL_EnableUNICODE
    1.97 +   Unicode translation used here is only really accurate for 7 bit characters.
    1.98 +
    1.99 +SDL_NumJoysticks/JoystickName etc.
   1.100 +   Hardcoded to expect only 1 joystick with 4 buttons if the Joystick module is loaded.
   1.101 +
   1.102 +SDL_GetTicks
   1.103 +   Timer used has only a centisecond accuracy. This applies to other time related functions.
   1.104 +   
   1.105 +SDL_Delay
   1.106 +   Modified to poll keyboard/mouse during the delay on the event thread.
   1.107 +
   1.108 +
   1.109 +Notes on current implementation
   1.110 +-------------------------------
   1.111 +
   1.112 +Keyboard and mouse are polled so if too long a time is spent between a call to SDL_PumpEvents, functions that use it, or SDL_Delay events can be missed.
   1.113 +
   1.114 +The sound is sent to the digital renderer player in a seperate thread. If there is too long a delay between this thread being processed (possibly if a lot else is running in the Wimp) the sound may sound incorrect or dissappear.
   1.115 +
     2.1 --- a/configure.in	Sat Sep 11 18:00:41 2004 +0000
     2.2 +++ b/configure.in	Fri Sep 17 13:20:10 2004 +0000
     2.3 @@ -2605,20 +2605,45 @@
     2.4          ;;
     2.5      *-*-riscos)
     2.6          ARCH=riscos
     2.7 -        JOYSTICK_SUBDIRS="$JOYSTICK_SUBDIRS riscos"
     2.8 -        JOYSTICK_DRIVERS="$JOYSTICK_DRIVERS riscos/libjoystick_riscos.la"
     2.9 -        COPY_ARCH_SRC(src/timer, riscos, SDL_systimer.c)
    2.10 -        VIDEO_SUBDIRS="$VIDEO_SUBDIRS riscos"
    2.11 -        VIDEO_DRIVERS="$VIDEO_DRIVERS riscos/libvideo_riscos.la"
    2.12 -        AUDIO_SUBDIRS="$AUDIO_SUBDIRS riscos"
    2.13 -        AUDIO_DRIVERS="$AUDIO_DRIVERS riscos/libaudio_riscos.la"
    2.14 -
    2.15 +        # Set up files for the video library
    2.16 +        if test x$enable_video = xyes; then
    2.17 +            VIDEO_SUBDIRS="$VIDEO_SUBDIRS riscos"
    2.18 +            VIDEO_DRIVERS="$VIDEO_DRIVERS riscos/libvideo_riscos.la"
    2.19 +        fi
    2.20 +        # Set up files for the audio library
    2.21 +        if test x$enable_audio = xyes; then
    2.22 +            AUDIO_SUBDIRS="$AUDIO_SUBDIRS riscos"
    2.23 +            AUDIO_DRIVERS="$AUDIO_DRIVERS riscos/libaudio_riscos.la"
    2.24 +        fi
    2.25 +        # Set up files for the joystick library
    2.26 +        if test x$enable_joystick = xyes; then
    2.27 +            JOYSTICK_SUBDIRS="$JOYSTICK_SUBDIRS riscos"
    2.28 +            JOYSTICK_DRIVERS="$JOYSTICK_DRIVERS riscos/libjoystick_riscos.la"
    2.29 +        fi
    2.30 +        # Set up files for the cdrom library
    2.31          if test x$enable_cdrom = xyes; then
    2.32              CDROM_SUBDIRS="$CDROM_SUBDIRS dummy"
    2.33              CDROM_DRIVERS="$CDROM_DRIVERS dummy/libcdrom_dummy.la"
    2.34          fi
    2.35 +        # Set up files for the thread library
    2.36 +        if test x$enable_threads = xyes; then
    2.37 +            COPY_ARCH_SRC(src/thread, riscos, SDL_systhread.c)
    2.38 +            COPY_ARCH_SRC(src/thread, riscos, SDL_systhread_c.h)
    2.39 +            COPY_ARCH_SRC(src/thread, riscos, SDL_sysmutex.c)
    2.40 +            COPY_ARCH_SRC(src/thread, riscos, SDL_sysmutex_c.h)
    2.41 +            COPY_ARCH_SRC(src/thread, riscos, SDL_syssem.c)
    2.42 +            COPY_ARCH_SRC(src/thread, generic, SDL_syssem_c.h)
    2.43 +            COPY_ARCH_SRC(src/thread, riscos, SDL_syscond.c)
    2.44 +            COPY_ARCH_SRC(src/thread, generic, SDL_syscond_c.h)
    2.45 +        else
    2.46 +            CFLAGS="$CFLAGS -DDISABLE_THREADS"
    2.47 +        fi
    2.48 +        # Set up files for the timer library
    2.49 +        if test x$enable_timers = xyes; then
    2.50 +            COPY_ARCH_SRC(src/timer, riscos, SDL_systimer.c)
    2.51 +        fi
    2.52  
    2.53 -        CFLAGS="$CFLAGS -DDISABLE_THREADS -DENABLE_RISCOS -DDRENDERER_SUPPORT"
    2.54 +        CFLAGS="$CFLAGS -DENABLE_RISCOS -DDRENDERER_SUPPORT"
    2.55  
    2.56          SYSTEM_LIBS="$SYSTEM_LIBS -ljpeg -ltiff -lpng -lz"
    2.57          ;;
     3.1 --- a/src/audio/SDL_audio.c	Sat Sep 11 18:00:41 2004 +0000
     3.2 +++ b/src/audio/SDL_audio.c	Fri Sep 17 13:20:10 2004 +0000
     3.3 @@ -399,7 +399,7 @@
     3.4  		return(-1);
     3.5  	}
     3.6  
     3.7 -#if defined(macintosh) || defined(__riscos__)
     3.8 +#if defined(macintosh) || (defined(__riscos__) && !defined(DISABLE_THREADS))
     3.9  	/* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
    3.10  #else
    3.11  #if defined(__MINT__) && !defined(ENABLE_THREADS)
     4.1 --- a/src/audio/riscos/SDL_drenderer.c	Sat Sep 11 18:00:41 2004 +0000
     4.2 +++ b/src/audio/riscos/SDL_drenderer.c	Fri Sep 17 13:20:10 2004 +0000
     4.3 @@ -35,6 +35,10 @@
     4.4  #include "SDL_sysaudio.h"
     4.5  #include "SDL_drenderer.h"
     4.6  
     4.7 +#ifndef DISABLE_THREADS
     4.8 +#include <pthread.h>
     4.9 +#endif
    4.10 +
    4.11  #define DigitalRenderer_Activate    0x4F700
    4.12  #define DigitalRenderer_Deactivate	0x4F701
    4.13  #define DigitalRenderer_ReadState	0x4F705
    4.14 @@ -57,6 +61,12 @@
    4.15  static void DRenderer_CloseAudio(_THIS);
    4.16  static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec);
    4.17  
    4.18 +#ifndef DISABLE_THREADS
    4.19 +static void DRenderer_WaitAudio(_THIS);
    4.20 +static Uint8 *DRenderer_GetAudioBuf(_THIS);
    4.21 +static void DRenderer_PlayAudio(_THIS);
    4.22 +#endif
    4.23 +
    4.24  /* Audio driver bootstrap functions */
    4.25  
    4.26  /* Define following to dump stats to stdout */
    4.27 @@ -104,6 +114,11 @@
    4.28      /* Set the function pointers */
    4.29      this->OpenAudio   = DRenderer_OpenAudio;
    4.30      this->CloseAudio  = DRenderer_CloseAudio;
    4.31 +#ifndef DISABLE_THREADS
    4.32 +    this->GetAudioBuf = DRenderer_GetAudioBuf;
    4.33 +    this->PlayAudio   = DRenderer_PlayAudio;
    4.34 +    this->WaitAudio   = DRenderer_WaitAudio;
    4.35 +#endif
    4.36      this->free        = Audio_DeleteDevice;
    4.37  
    4.38      return this;
    4.39 @@ -117,6 +132,9 @@
    4.40  /* Routine called to check and fill audio buffers if necessary */
    4.41  static Uint8 *buffer = NULL;
    4.42  
    4.43 +#ifdef DISABLE_THREADS
    4.44 +
    4.45 +/* Buffer fill routine called during polling */
    4.46  void DRenderer_FillBuffers()
    4.47  {
    4.48  	SDL_AudioDevice *audio = current_audio;
    4.49 @@ -182,15 +200,33 @@
    4.50     }
    4.51  }
    4.52  
    4.53 +#endif
    4.54 +
    4.55  /* Size of DMA buffer to use */
    4.56  #define DRENDERER_BUFFER_SIZE 512
    4.57  
    4.58  /* Number of centiseconds of sound to buffer.
    4.59     Hopefully more than the maximum time between calls to the
    4.60 -   FillBuffers routine above
    4.61 +   FillBuffers routine above (non-threaded) or the PlayAudio
    4.62 +   routine below (threaded).
    4.63  */
    4.64 +
    4.65  #define DRENDERER_CSEC_TO_BUFFER 10
    4.66  
    4.67 +static void DeactivateAudio()
    4.68 +{
    4.69 +	_kernel_swi_regs regs;
    4.70 +
    4.71 +	/* Close down the digital renderer */
    4.72 +	_kernel_swi(DigitalRenderer_Deactivate, &regs, &regs);
    4.73 +
    4.74 +	if (buffer != NULL)
    4.75 +	{
    4.76 +	   free(buffer);
    4.77 +	   buffer = NULL;
    4.78 +	}
    4.79 +}
    4.80 +
    4.81  static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
    4.82  {
    4.83  	_kernel_swi_regs regs;
    4.84 @@ -200,6 +236,7 @@
    4.85      printf("Request format %d\n", spec->format);
    4.86      printf("Request freq   %d\n", spec->freq);
    4.87      printf("Samples        %d\n", spec->samples);
    4.88 +    printf("Channels       %d\n", spec->channels);
    4.89  #endif
    4.90  
    4.91  	/* Only support signed 16bit format */
    4.92 @@ -207,9 +244,6 @@
    4.93  
    4.94      if (spec->samples < DRENDERER_BUFFER_SIZE) spec->samples = DRENDERER_BUFFER_SIZE;
    4.95  
    4.96 -    SDL_CalculateAudioSpec(spec);
    4.97 -
    4.98 -
    4.99  	buffers_per_sample = spec->samples / DRENDERER_BUFFER_SIZE;
   4.100  
   4.101  	if ((spec->samples % DRENDERER_BUFFER_SIZE) != 0)
   4.102 @@ -217,6 +251,7 @@
   4.103  		buffers_per_sample++;
   4.104  		spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE;
   4.105  	}
   4.106 +	
   4.107  
   4.108  	/* Set number of buffers to use - the following should give enough
   4.109  	   data between calls to the sound polling.
   4.110 @@ -227,7 +262,19 @@
   4.111      	FillBuffer = (int)((double)DRENDERER_CSEC_TO_BUFFER / ((double)DRENDERER_BUFFER_SIZE * 100.0 / (double)spec->freq)) + 1;
   4.112      } else FillBuffer = riscos_audiobuffer/DRENDERER_BUFFER_SIZE - buffers_per_sample;
   4.113  
   4.114 -	if (FillBuffer < buffers_per_sample) FillBuffer = buffers_per_sample;
   4.115 +    if (FillBuffer < buffers_per_sample) FillBuffer = buffers_per_sample;
   4.116 +#ifndef DISABLE_THREADS
   4.117 +    if (buffers_per_sample < FillBuffer)
   4.118 +    {
   4.119 +       /* For the threaded version we are only called once per cycle
   4.120 +          so the callback needs to give us the full data we need in
   4.121 +          one go, rather than multiple calls as it the case for the
   4.122 +          non threaded version */
   4.123 +       buffers_per_sample = FillBuffer;
   4.124 +       spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE;
   4.125 +    }
   4.126 +#endif
   4.127 +        SDL_CalculateAudioSpec(spec);
   4.128  	regs.r[0] = FillBuffer + buffers_per_sample;
   4.129  
   4.130  #ifdef DUMP_AUDIO
   4.131 @@ -259,6 +306,9 @@
   4.132  		spec->freq = regs.r[0];
   4.133  	}
   4.134  
   4.135 +        /* Ensure sound is deactivated if we exit without calling SDL_Quit */
   4.136 +        atexit(DeactivateAudio);
   4.137 +
   4.138  #ifdef DUMP_AUDIO
   4.139      printf("Got format %d\n", spec->format);
   4.140      printf("Frequency  %d\n", spec->freq);
   4.141 @@ -277,17 +327,56 @@
   4.142  		return -1;
   4.143  	}
   4.144  
   4.145 +#ifdef DISABLE_THREADS
   4.146     /* Hopefully returning 2 will show success, but not start up an audio thread */
   4.147     return 2;
   4.148 +#else
   4.149 +   /* Success and start audio thread */
   4.150 +   return 0;
   4.151 +#endif
   4.152  }
   4.153  
   4.154  static void DRenderer_CloseAudio(_THIS)
   4.155  {
   4.156 +        DeactivateAudio();
   4.157 +}
   4.158 +
   4.159 +#ifndef DISABLE_THREADS
   4.160 +
   4.161 +/* Routines for threaded version of audio */
   4.162 +
   4.163 +void DRenderer_WaitAudio(_THIS)
   4.164 +{
   4.165 +   _kernel_swi_regs regs;
   4.166 +   int waiting = 1;
   4.167 +
   4.168 +   while (waiting)
   4.169 +   {
   4.170 +      /* Check filled buffers count */
   4.171 +      _kernel_swi(DigitalRenderer_StreamStatistics, &regs, &regs);
   4.172 +#if 0
   4.173 +    if (regs.r[0] <= FillBuffer)
   4.174 +    {
   4.175 +       printf("Buffers in use %d\n", regs.r[0]);
   4.176 +    }
   4.177 +#endif
   4.178 +      if (regs.r[0] <= FillBuffer) waiting = 0;
   4.179 +      else pthread_yield();
   4.180 +   }
   4.181 +}
   4.182 +
   4.183 +Uint8 *DRenderer_GetAudioBuf(_THIS)
   4.184 +{
   4.185 +    return buffer;
   4.186 +}
   4.187 +
   4.188 +void DRenderer_PlayAudio(_THIS)
   4.189 +{
   4.190  	_kernel_swi_regs regs;
   4.191  
   4.192 -	/* Close down the digital renderer */
   4.193 -	_kernel_swi(DigitalRenderer_Deactivate, &regs, &regs);
   4.194 -
   4.195 -	if (buffer != NULL) free(buffer);
   4.196 +	regs.r[0] = (int)buffer;
   4.197 +	regs.r[1] = current_audio->spec.samples * current_audio->spec.channels;
   4.198 +	_kernel_swi(DigitalRenderer_Stream16BitSamples, &regs, &regs);
   4.199  }
   4.200  
   4.201 +#endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/thread/riscos/SDL_syscond.c	Fri Sep 17 13:20:10 2004 +0000
     5.3 @@ -0,0 +1,167 @@
     5.4 +/*
     5.5 +    SDL - Simple DirectMedia Layer
     5.6 +    Copyright (C) 1997-2004 Sam Lantinga
     5.7 +
     5.8 +    This library is free software; you can redistribute it and/or
     5.9 +    modify it under the terms of the GNU Library General Public
    5.10 +    License as published by the Free Software Foundation; either
    5.11 +    version 2 of the License, or (at your option) any later version.
    5.12 +
    5.13 +    This library is distributed in the hope that it will be useful,
    5.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 +    Library General Public License for more details.
    5.17 +
    5.18 +    You should have received a copy of the GNU Library General Public
    5.19 +    License along with this library; if not, write to the Free
    5.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.21 +
    5.22 +    Sam Lantinga
    5.23 +    slouken@libsdl.org
    5.24 +*/
    5.25 +
    5.26 +/* RISC OS implementations uses pthreads based on linux code */
    5.27 +
    5.28 +#ifdef SAVE_RCSID
    5.29 +static char rcsid =
    5.30 + "@(#) $Id$";
    5.31 +#endif
    5.32 +
    5.33 +#ifdef DISABLE_THREADS
    5.34 +#include "../generic/SDL_syscond.c"
    5.35 +#else
    5.36 +#include <sys/time.h>
    5.37 +#include <unistd.h>
    5.38 +#include <errno.h>
    5.39 +#include <stdlib.h>
    5.40 +#include <pthread.h>
    5.41 +
    5.42 +#include "SDL_error.h"
    5.43 +#include "SDL_thread.h"
    5.44 +#include "SDL_sysmutex_c.h"
    5.45 +
    5.46 +struct SDL_cond
    5.47 +{
    5.48 +	pthread_cond_t cond;
    5.49 +};
    5.50 +
    5.51 +/* Create a condition variable */
    5.52 +SDL_cond * SDL_CreateCond(void)
    5.53 +{
    5.54 +	SDL_cond *cond;
    5.55 +
    5.56 +	cond = (SDL_cond *) malloc(sizeof(SDL_cond));
    5.57 +	if ( cond ) {
    5.58 +		if ( pthread_cond_init(&cond->cond, NULL) < 0 ) {
    5.59 +			SDL_SetError("pthread_cond_init() failed");
    5.60 +			free(cond);
    5.61 +			cond = NULL;
    5.62 +		}
    5.63 +	}
    5.64 +	return(cond);
    5.65 +}
    5.66 +
    5.67 +/* Destroy a condition variable */
    5.68 +void SDL_DestroyCond(SDL_cond *cond)
    5.69 +{
    5.70 +	if ( cond ) {
    5.71 +		pthread_cond_destroy(&cond->cond);
    5.72 +		free(cond);
    5.73 +	}
    5.74 +}
    5.75 +
    5.76 +/* Restart one of the threads that are waiting on the condition variable */
    5.77 +int SDL_CondSignal(SDL_cond *cond)
    5.78 +{
    5.79 +	int retval;
    5.80 +
    5.81 +	if ( ! cond ) {
    5.82 +		SDL_SetError("Passed a NULL condition variable");
    5.83 +		return -1;
    5.84 +	}
    5.85 +
    5.86 +	retval = 0;
    5.87 +	if ( pthread_cond_signal(&cond->cond) != 0 ) {
    5.88 +		SDL_SetError("pthread_cond_signal() failed");
    5.89 +		retval = -1;
    5.90 +	}
    5.91 +	return retval;
    5.92 +}
    5.93 +
    5.94 +/* Restart all threads that are waiting on the condition variable */
    5.95 +int SDL_CondBroadcast(SDL_cond *cond)
    5.96 +{
    5.97 +	int retval;
    5.98 +
    5.99 +	if ( ! cond ) {
   5.100 +		SDL_SetError("Passed a NULL condition variable");
   5.101 +		return -1;
   5.102 +	}
   5.103 +
   5.104 +	retval = 0;
   5.105 +	if ( pthread_cond_broadcast(&cond->cond) != 0 ) {
   5.106 +		SDL_SetError("pthread_cond_broadcast() failed");
   5.107 +		retval = -1;
   5.108 +	}
   5.109 +	return retval;
   5.110 +}
   5.111 +
   5.112 +int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
   5.113 +{
   5.114 +	int retval;
   5.115 +	struct timeval delta;
   5.116 +	struct timespec abstime;
   5.117 +
   5.118 +	if ( ! cond ) {
   5.119 +		SDL_SetError("Passed a NULL condition variable");
   5.120 +		return -1;
   5.121 +	}
   5.122 +
   5.123 +	gettimeofday(&delta, NULL);
   5.124 +
   5.125 +	abstime.tv_sec = delta.tv_sec + (ms/1000);
   5.126 +	abstime.tv_nsec = (delta.tv_usec + (ms%1000) * 1000) * 1000;
   5.127 +        if ( abstime.tv_nsec > 1000000000 ) {
   5.128 +          abstime.tv_sec += 1;
   5.129 +          abstime.tv_nsec -= 1000000000;
   5.130 +        }
   5.131 +
   5.132 +  tryagain:
   5.133 +	retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
   5.134 +	switch (retval) {
   5.135 +	    case EINTR:
   5.136 +		goto tryagain;
   5.137 +		break;
   5.138 +	    case ETIMEDOUT:
   5.139 +		retval = SDL_MUTEX_TIMEDOUT;
   5.140 +		break;
   5.141 +	    case 0:
   5.142 +		break;
   5.143 +	    default:
   5.144 +		SDL_SetError("pthread_cond_timedwait() failed");
   5.145 +		retval = -1;
   5.146 +		break;
   5.147 +	}
   5.148 +	return retval;
   5.149 +}
   5.150 +
   5.151 +/* Wait on the condition variable, unlocking the provided mutex.
   5.152 +   The mutex must be locked before entering this function!
   5.153 + */
   5.154 +int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
   5.155 +{
   5.156 +	int retval;
   5.157 +
   5.158 +	if ( ! cond ) {
   5.159 +		SDL_SetError("Passed a NULL condition variable");
   5.160 +		return -1;
   5.161 +	}
   5.162 +
   5.163 +	retval = 0;
   5.164 +	if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) {
   5.165 +		SDL_SetError("pthread_cond_wait() failed");
   5.166 +		retval = -1;
   5.167 +	}
   5.168 +	return retval;
   5.169 +}
   5.170 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/thread/riscos/SDL_sysmutex.c	Fri Sep 17 13:20:10 2004 +0000
     6.3 @@ -0,0 +1,160 @@
     6.4 +/*
     6.5 +    SDL - Simple DirectMedia Layer
     6.6 +    Copyright (C) 1997-2004 Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Library General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Library General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Library General Public
    6.19 +    License along with this library; if not, write to the Free
    6.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.21 +
    6.22 +    Sam Lantinga
    6.23 +    slouken@libsdl.org
    6.24 +*/
    6.25 +
    6.26 +/* RISC OS implementations uses pthreads based on linux code */
    6.27 +
    6.28 +#ifdef SAVE_RCSID
    6.29 +static char rcsid =
    6.30 + "@(#) $Id$";
    6.31 +#endif
    6.32 +
    6.33 +#ifdef DISABLE_THREADS
    6.34 +#include "../generic/SDL_sysmutex.c"
    6.35 +#else
    6.36 +
    6.37 +#include <stdlib.h>
    6.38 +#include <stdio.h>
    6.39 +#include <pthread.h>
    6.40 +
    6.41 +#include "SDL_error.h"
    6.42 +#include "SDL_thread.h"
    6.43 +
    6.44 +struct SDL_mutex {
    6.45 +	pthread_mutex_t id;
    6.46 +#ifdef PTHREAD_NO_RECURSIVE_MUTEX
    6.47 +	int recursive;
    6.48 +	pthread_t owner;
    6.49 +#endif
    6.50 +};
    6.51 +
    6.52 +SDL_mutex *SDL_CreateMutex (void)
    6.53 +{
    6.54 +	SDL_mutex *mutex;
    6.55 +	pthread_mutexattr_t attr;
    6.56 +
    6.57 +	/* Allocate the structure */
    6.58 +	mutex = (SDL_mutex *)calloc(1, sizeof(*mutex));
    6.59 +	if ( mutex ) {
    6.60 +		pthread_mutexattr_init(&attr);
    6.61 +#ifdef PTHREAD_NO_RECURSIVE_MUTEX
    6.62 +		/* No extra attributes necessary */
    6.63 +#else
    6.64 +		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    6.65 +#endif /* PTHREAD_NO_RECURSIVE_MUTEX */
    6.66 +		if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) {
    6.67 +			SDL_SetError("pthread_mutex_init() failed");
    6.68 +			free(mutex);
    6.69 +			mutex = NULL;
    6.70 +		}
    6.71 +	} else {
    6.72 +		SDL_OutOfMemory();
    6.73 +	}
    6.74 +	return(mutex);
    6.75 +}
    6.76 +
    6.77 +void SDL_DestroyMutex(SDL_mutex *mutex)
    6.78 +{
    6.79 +	if ( mutex ) {
    6.80 +		pthread_mutex_destroy(&mutex->id);
    6.81 +		free(mutex);
    6.82 +	}
    6.83 +}
    6.84 +
    6.85 +/* Lock the mutex */
    6.86 +int SDL_mutexP(SDL_mutex *mutex)
    6.87 +{
    6.88 +	int retval;
    6.89 +#ifdef PTHREAD_NO_RECURSIVE_MUTEX
    6.90 +	pthread_t this_thread;
    6.91 +#endif
    6.92 +
    6.93 +	if ( mutex == NULL ) {
    6.94 +		SDL_SetError("Passed a NULL mutex");
    6.95 +		return -1;
    6.96 +	}
    6.97 +
    6.98 +	retval = 0;
    6.99 +#ifdef PTHREAD_NO_RECURSIVE_MUTEX
   6.100 +	this_thread = pthread_self();
   6.101 +	if ( mutex->owner == this_thread ) {
   6.102 +		++mutex->recursive;
   6.103 +	} else {
   6.104 +		/* The order of operations is important.
   6.105 +		   We set the locking thread id after we obtain the lock
   6.106 +		   so unlocks from other threads will fail.
   6.107 +		*/
   6.108 +		if ( pthread_mutex_lock(&mutex->id) == 0 ) {
   6.109 +			mutex->owner = this_thread;
   6.110 +			mutex->recursive = 0;
   6.111 +		} else {
   6.112 +			SDL_SetError("pthread_mutex_lock() failed");
   6.113 +			retval = -1;
   6.114 +		}
   6.115 +	}
   6.116 +#else
   6.117 +	if ( pthread_mutex_lock(&mutex->id) < 0 ) {
   6.118 +		SDL_SetError("pthread_mutex_lock() failed");
   6.119 +		retval = -1;
   6.120 +	}
   6.121 +#endif
   6.122 +	return retval;
   6.123 +}
   6.124 +
   6.125 +int SDL_mutexV(SDL_mutex *mutex)
   6.126 +{
   6.127 +	int retval;
   6.128 +
   6.129 +	if ( mutex == NULL ) {
   6.130 +		SDL_SetError("Passed a NULL mutex");
   6.131 +		return -1;
   6.132 +	}
   6.133 +
   6.134 +	retval = 0;
   6.135 +#ifdef PTHREAD_NO_RECURSIVE_MUTEX
   6.136 +	/* We can only unlock the mutex if we own it */
   6.137 +	if ( pthread_self() == mutex->owner ) {
   6.138 +		if ( mutex->recursive ) {
   6.139 +			--mutex->recursive;
   6.140 +		} else {
   6.141 +			/* The order of operations is important.
   6.142 +			   First reset the owner so another thread doesn't lock
   6.143 +			   the mutex and set the ownership before we reset it,
   6.144 +			   then release the lock semaphore.
   6.145 +			 */
   6.146 +			mutex->owner = 0;
   6.147 +			pthread_mutex_unlock(&mutex->id);
   6.148 +		}
   6.149 +	} else {
   6.150 +		SDL_SetError("mutex not owned by this thread");
   6.151 +		retval = -1;
   6.152 +	}
   6.153 +
   6.154 +#else
   6.155 +	if ( pthread_mutex_unlock(&mutex->id) < 0 ) {
   6.156 +		SDL_SetError("pthread_mutex_unlock() failed");
   6.157 +		retval = -1;
   6.158 +	}
   6.159 +#endif /* PTHREAD_NO_RECURSIVE_MUTEX */
   6.160 +
   6.161 +	return retval;
   6.162 +}
   6.163 +#endif
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/thread/riscos/SDL_sysmutex_c.h	Fri Sep 17 13:20:10 2004 +0000
     7.3 @@ -0,0 +1,38 @@
     7.4 +/*
     7.5 +    SDL - Simple DirectMedia Layer
     7.6 +    Copyright (C) 1997-2004 Sam Lantinga
     7.7 +
     7.8 +    This library is free software; you can redistribute it and/or
     7.9 +    modify it under the terms of the GNU Library General Public
    7.10 +    License as published by the Free Software Foundation; either
    7.11 +    version 2 of the License, or (at your option) any later version.
    7.12 +
    7.13 +    This library is distributed in the hope that it will be useful,
    7.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.16 +    Library General Public License for more details.
    7.17 +
    7.18 +    You should have received a copy of the GNU Library General Public
    7.19 +    License along with this library; if not, write to the Free
    7.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.21 +
    7.22 +    Sam Lantinga
    7.23 +    slouken@libsdl.org
    7.24 +*/
    7.25 +
    7.26 +#ifdef SAVE_RCSID
    7.27 +static char rcsid =
    7.28 + "@(#) $Id$";
    7.29 +#endif
    7.30 +
    7.31 +#ifndef _SDL_mutex_c_h
    7.32 +#define _SDL_mutex_c_h
    7.33 +
    7.34 +#ifndef DISABLE_THREADS
    7.35 +struct SDL_mutex {
    7.36 +	pthread_mutex_t id;
    7.37 +};
    7.38 +#endif
    7.39 +
    7.40 +
    7.41 +#endif /* _SDL_mutex_c_h */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/thread/riscos/SDL_syssem.c	Fri Sep 17 13:20:10 2004 +0000
     8.3 @@ -0,0 +1,216 @@
     8.4 +/*
     8.5 +    SDL - Simple DirectMedia Layer
     8.6 +    Copyright (C) 1997-2004 Sam Lantinga
     8.7 +
     8.8 +    This library is free software; you can redistribute it and/or
     8.9 +    modify it under the terms of the GNU Library General Public
    8.10 +    License as published by the Free Software Foundation; either
    8.11 +    version 2 of the License, or (at your option) any later version.
    8.12 +
    8.13 +    This library is distributed in the hope that it will be useful,
    8.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 +    Library General Public License for more details.
    8.17 +
    8.18 +    You should have received a copy of the GNU Library General Public
    8.19 +    License along with this library; if not, write to the Free
    8.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 +
    8.22 +    Sam Lantinga
    8.23 +    slouken@libsdl.org
    8.24 +*/
    8.25 +
    8.26 +/* RISC OS doesn't have semiphores so use code based on generic implementation */
    8.27 +
    8.28 +#ifdef SAVE_RCSID
    8.29 +static char rcsid =
    8.30 + "@(#) $Id$";
    8.31 +#endif
    8.32 +
    8.33 +/* An implementation of semaphores using mutexes and condition variables */
    8.34 +
    8.35 +#include <stdlib.h>
    8.36 +
    8.37 +#include "SDL_error.h"
    8.38 +#include "SDL_timer.h"
    8.39 +#include "SDL_thread.h"
    8.40 +
    8.41 +#include "SDL_systhread_c.h"
    8.42 +
    8.43 +#ifdef DISABLE_THREADS
    8.44 +
    8.45 +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
    8.46 +{
    8.47 +	SDL_SetError("SDL not configured with thread support");
    8.48 +	return (SDL_sem *)0;
    8.49 +}
    8.50 +
    8.51 +void SDL_DestroySemaphore(SDL_sem *sem)
    8.52 +{
    8.53 +	return;
    8.54 +}
    8.55 +
    8.56 +int SDL_SemTryWait(SDL_sem *sem)
    8.57 +{
    8.58 +	SDL_SetError("SDL not configured with thread support");
    8.59 +	return -1;
    8.60 +}
    8.61 +
    8.62 +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
    8.63 +{
    8.64 +	SDL_SetError("SDL not configured with thread support");
    8.65 +	return -1;
    8.66 +}
    8.67 +
    8.68 +int SDL_SemWait(SDL_sem *sem)
    8.69 +{
    8.70 +	SDL_SetError("SDL not configured with thread support");
    8.71 +	return -1;
    8.72 +}
    8.73 +
    8.74 +Uint32 SDL_SemValue(SDL_sem *sem)
    8.75 +{
    8.76 +	return 0;
    8.77 +}
    8.78 +
    8.79 +int SDL_SemPost(SDL_sem *sem)
    8.80 +{
    8.81 +	SDL_SetError("SDL not configured with thread support");
    8.82 +	return -1;
    8.83 +}
    8.84 +
    8.85 +#else
    8.86 +
    8.87 +struct SDL_semaphore
    8.88 +{
    8.89 +	Uint32 count;
    8.90 +	Uint32 waiters_count;
    8.91 +	SDL_mutex *count_lock;
    8.92 +	SDL_cond *count_nonzero;
    8.93 +};
    8.94 +
    8.95 +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
    8.96 +{
    8.97 +	SDL_sem *sem;
    8.98 +
    8.99 +	sem = (SDL_sem *)malloc(sizeof(*sem));
   8.100 +	if ( ! sem ) {
   8.101 +		SDL_OutOfMemory();
   8.102 +		return(0);
   8.103 +	}
   8.104 +	sem->count = initial_value;
   8.105 +	sem->waiters_count = 0;
   8.106 +
   8.107 +	sem->count_lock = SDL_CreateMutex();
   8.108 +	sem->count_nonzero = SDL_CreateCond();
   8.109 +	if ( ! sem->count_lock || ! sem->count_nonzero ) {
   8.110 +		SDL_DestroySemaphore(sem);
   8.111 +		return(0);
   8.112 +	}
   8.113 +
   8.114 +	return(sem);
   8.115 +}
   8.116 +
   8.117 +/* WARNING:
   8.118 +   You cannot call this function when another thread is using the semaphore.
   8.119 +*/
   8.120 +void SDL_DestroySemaphore(SDL_sem *sem)
   8.121 +{
   8.122 +	if ( sem ) {
   8.123 +		sem->count = 0xFFFFFFFF;
   8.124 +		while ( sem->waiters_count > 0) {
   8.125 +			SDL_CondSignal(sem->count_nonzero);
   8.126 +			SDL_Delay(10);
   8.127 +		}
   8.128 +		SDL_DestroyCond(sem->count_nonzero);
   8.129 +		SDL_mutexP(sem->count_lock);
   8.130 +		SDL_mutexV(sem->count_lock);
   8.131 +		SDL_DestroyMutex(sem->count_lock);
   8.132 +		free(sem);
   8.133 +	}
   8.134 +}
   8.135 +
   8.136 +int SDL_SemTryWait(SDL_sem *sem)
   8.137 +{
   8.138 +	int retval;
   8.139 +
   8.140 +	if ( ! sem ) {
   8.141 +		SDL_SetError("Passed a NULL semaphore");
   8.142 +		return -1;
   8.143 +	}
   8.144 +
   8.145 +	retval = SDL_MUTEX_TIMEDOUT;
   8.146 +	SDL_LockMutex(sem->count_lock);
   8.147 +	if ( sem->count > 0 ) {
   8.148 +		--sem->count;
   8.149 +		retval = 0;
   8.150 +	}
   8.151 +	SDL_UnlockMutex(sem->count_lock);
   8.152 +
   8.153 +	return retval;
   8.154 +}
   8.155 +
   8.156 +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
   8.157 +{
   8.158 +	int retval;
   8.159 +
   8.160 +	if ( ! sem ) {
   8.161 +		SDL_SetError("Passed a NULL semaphore");
   8.162 +		return -1;
   8.163 +	}
   8.164 +
   8.165 +	/* A timeout of 0 is an easy case */
   8.166 +	if ( timeout == 0 ) {
   8.167 +		return SDL_SemTryWait(sem);
   8.168 +	}
   8.169 +
   8.170 +	SDL_LockMutex(sem->count_lock);
   8.171 +	++sem->waiters_count;
   8.172 +	retval = 0;
   8.173 +	while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
   8.174 +		retval = SDL_CondWaitTimeout(sem->count_nonzero,
   8.175 +		                             sem->count_lock, timeout);
   8.176 +	}
   8.177 +	--sem->waiters_count;
   8.178 +	--sem->count;
   8.179 +	SDL_UnlockMutex(sem->count_lock);
   8.180 +
   8.181 +	return retval;
   8.182 +}
   8.183 +
   8.184 +int SDL_SemWait(SDL_sem *sem)
   8.185 +{
   8.186 +	return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
   8.187 +}
   8.188 +
   8.189 +Uint32 SDL_SemValue(SDL_sem *sem)
   8.190 +{
   8.191 +	Uint32 value;
   8.192 +	
   8.193 +	value = 0;
   8.194 +	if ( sem ) {
   8.195 +		SDL_LockMutex(sem->count_lock);
   8.196 +		value = sem->count;
   8.197 +		SDL_UnlockMutex(sem->count_lock);
   8.198 +	}
   8.199 +	return value;
   8.200 +}
   8.201 +
   8.202 +int SDL_SemPost(SDL_sem *sem)
   8.203 +{
   8.204 +	if ( ! sem ) {
   8.205 +		SDL_SetError("Passed a NULL semaphore");
   8.206 +		return -1;
   8.207 +	}
   8.208 +
   8.209 +	SDL_LockMutex(sem->count_lock);
   8.210 +	if ( sem->waiters_count > 0 ) {
   8.211 +		SDL_CondSignal(sem->count_nonzero);
   8.212 +	}
   8.213 +	++sem->count;
   8.214 +	SDL_UnlockMutex(sem->count_lock);
   8.215 +
   8.216 +	return 0;
   8.217 +}
   8.218 +
   8.219 +#endif /* DISABLE_THREADS */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/thread/riscos/SDL_systhread.c	Fri Sep 17 13:20:10 2004 +0000
     9.3 @@ -0,0 +1,149 @@
     9.4 +/*
     9.5 +    SDL - Simple DirectMedia Layer
     9.6 +    Copyright (C) 1997-2004 Sam Lantinga
     9.7 +
     9.8 +    This library is free software; you can redistribute it and/or
     9.9 +    modify it under the terms of the GNU Library General Public
    9.10 +    License as published by the Free Software Foundation; either
    9.11 +    version 2 of the License, or (at your option) any later version.
    9.12 +
    9.13 +    This library is distributed in the hope that it will be useful,
    9.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.16 +    Library General Public License for more details.
    9.17 +
    9.18 +    You should have received a copy of the GNU Library General Public
    9.19 +    License along with this library; if not, write to the Free
    9.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.21 +
    9.22 +    Sam Lantinga
    9.23 +    slouken@libsdl.org
    9.24 +*/
    9.25 +
    9.26 +/* RISC OS version based on pthreads linux source */
    9.27 +
    9.28 +#ifdef SAVE_RCSID
    9.29 +static char rcsid =
    9.30 + "@(#) $Id$";
    9.31 +#endif
    9.32 +
    9.33 +#include "SDL_error.h"
    9.34 +#include "SDL_thread.h"
    9.35 +#include "SDL_systhread.h"
    9.36 +
    9.37 +#ifdef DISABLE_THREADS
    9.38 +
    9.39 +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
    9.40 +{
    9.41 +	SDL_SetError("Threads have not been compiled into this version of the library");
    9.42 +	return(-1);
    9.43 +}
    9.44 +
    9.45 +void SDL_SYS_SetupThread(void)
    9.46 +{
    9.47 +	return;
    9.48 +}
    9.49 +
    9.50 +Uint32 SDL_ThreadID(void)
    9.51 +{
    9.52 +	return(0);
    9.53 +}
    9.54 +
    9.55 +void SDL_SYS_WaitThread(SDL_Thread *thread)
    9.56 +{
    9.57 +	return;
    9.58 +}
    9.59 +
    9.60 +void SDL_SYS_KillThread(SDL_Thread *thread)
    9.61 +{
    9.62 +	return;
    9.63 +}
    9.64 +
    9.65 +#else
    9.66 +
    9.67 +#include <signal.h>
    9.68 +
    9.69 +/* List of signals to mask in the subthreads */
    9.70 +static int sig_list[] = {
    9.71 +	SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
    9.72 +	SIGVTALRM, SIGPROF, 0
    9.73 +};
    9.74 +
    9.75 +#include <pthread.h>
    9.76 +
    9.77 +int riscos_using_threads = 0;
    9.78 +Uint32 riscos_main_thread = 0; /* Thread running events */
    9.79 +
    9.80 +static void *RunThread(void *data)
    9.81 +{
    9.82 +	SDL_RunThread(data);
    9.83 +	pthread_exit((void*)0);
    9.84 +	return((void *)0);		/* Prevent compiler warning */
    9.85 +}
    9.86 +
    9.87 +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
    9.88 +{
    9.89 +	pthread_attr_t type;
    9.90 +
    9.91 +	/* Set the thread attributes */
    9.92 +	if ( pthread_attr_init(&type) != 0 ) {
    9.93 +		SDL_SetError("Couldn't initialize pthread attributes");
    9.94 +		return(-1);
    9.95 +	}
    9.96 +	pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
    9.97 +
    9.98 +	/* Create the thread and go! */
    9.99 +	if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) {
   9.100 +		SDL_SetError("Not enough resources to create thread");
   9.101 +		return(-1);
   9.102 +	}
   9.103 +
   9.104 +        if (riscos_using_threads == 0)
   9.105 +        {
   9.106 +           riscos_using_threads = 1;
   9.107 +           riscos_main_thread = SDL_ThreadID();
   9.108 +        }
   9.109 +      
   9.110 +	return(0);
   9.111 +}
   9.112 +
   9.113 +void SDL_SYS_SetupThread(void)
   9.114 +{
   9.115 +	int i;
   9.116 +	sigset_t mask;
   9.117 +
   9.118 +	/* Mask asynchronous signals for this thread */
   9.119 +	sigemptyset(&mask);
   9.120 +	for ( i=0; sig_list[i]; ++i ) {
   9.121 +		sigaddset(&mask, sig_list[i]);
   9.122 +	}
   9.123 +	pthread_sigmask(SIG_BLOCK, &mask, 0);
   9.124 +	
   9.125 +#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
   9.126 +	/* Allow ourselves to be asynchronously cancelled */
   9.127 +	{ int oldstate;
   9.128 +		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
   9.129 +	}
   9.130 +#endif
   9.131 +}
   9.132 +
   9.133 +Uint32 SDL_ThreadID(void)
   9.134 +{
   9.135 +	return((Uint32)pthread_self());
   9.136 +}
   9.137 +
   9.138 +void SDL_SYS_WaitThread(SDL_Thread *thread)
   9.139 +{
   9.140 +	pthread_join(thread->handle, 0);
   9.141 +}
   9.142 +
   9.143 +void SDL_SYS_KillThread(SDL_Thread *thread)
   9.144 +{
   9.145 +#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
   9.146 +	pthread_cancel(thread->handle);
   9.147 +#else
   9.148 +	pthread_kill(thread->handle, SIGKILL);
   9.149 +#endif
   9.150 +}
   9.151 +
   9.152 +#endif
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/thread/riscos/SDL_systhread_c.h	Fri Sep 17 13:20:10 2004 +0000
    10.3 @@ -0,0 +1,33 @@
    10.4 +/*
    10.5 +    SDL - Simple DirectMedia Layer
    10.6 +    Copyright (C) 1997-2004 Sam Lantinga
    10.7 +
    10.8 +    This library is free software; you can redistribute it and/or
    10.9 +    modify it under the terms of the GNU Library General Public
   10.10 +    License as published by the Free Software Foundation; either
   10.11 +    version 2 of the License, or (at your option) any later version.
   10.12 +
   10.13 +    This library is distributed in the hope that it will be useful,
   10.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   10.16 +    Library General Public License for more details.
   10.17 +
   10.18 +    You should have received a copy of the GNU Library General Public
   10.19 +    License along with this library; if not, write to the Free
   10.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   10.21 +
   10.22 +    Sam Lantinga
   10.23 +    slouken@libsdl.org
   10.24 +*/
   10.25 +
   10.26 +#ifdef DISABLE_THREADS
   10.27 +
   10.28 +typedef int SYS_ThreadHandle;
   10.29 +
   10.30 +#else
   10.31 +
   10.32 +#include <pthread.h>
   10.33 +
   10.34 +typedef pthread_t SYS_ThreadHandle;
   10.35 +
   10.36 +#endif
    11.1 --- a/src/timer/riscos/SDL_systimer.c	Sat Sep 11 18:00:41 2004 +0000
    11.2 +++ b/src/timer/riscos/SDL_systimer.c	Fri Sep 17 13:20:10 2004 +0000
    11.3 @@ -36,10 +36,19 @@
    11.4  #include "SDL_timer.h"
    11.5  #include "SDL_timer_c.h"
    11.6  
    11.7 +#ifdef DISABLE_THREADS
    11.8  /* Timer start/reset time */
    11.9  static Uint32 timerStart;
   11.10  /* Timer running function */
   11.11  void RISCOS_CheckTimer();
   11.12 +#else
   11.13 +#include <pthread.h>
   11.14 +extern Uint32 riscos_main_thread;
   11.15 +extern int riscos_using_threads;
   11.16 +extern Uint32 SDL_ThreadID();
   11.17 +extern Uint32 SDL_EventThreadID(void);
   11.18 +#endif
   11.19 +
   11.20  
   11.21  extern void RISCOS_BackgroundTasks(void);
   11.22  
   11.23 @@ -75,18 +84,36 @@
   11.24  
   11.25  }
   11.26  
   11.27 -extern void DRenderer_FillBuffers();
   11.28 -
   11.29  void SDL_Delay (Uint32 ms)
   11.30  {
   11.31      Uint32 now,then,elapsed;
   11.32 +#ifndef DISABLE_THREADS
   11.33 +    int is_event_thread;
   11.34 +    if (riscos_using_threads)
   11.35 +    {
   11.36 +       is_event_thread = 0;
   11.37 +       if (SDL_EventThreadID())
   11.38 +       {
   11.39 +          if (SDL_EventThreadID() == SDL_ThreadID()) is_event_thread = 1;
   11.40 +       } else if (SDL_ThreadID() == riscos_main_thread) is_event_thread = 1;
   11.41 +    } else is_event_thread = 1;
   11.42 +#endif
   11.43 +
   11.44 +/*TODO: Next version of unixlib may allow us to use usleep here */
   11.45 +/*      for non event threads */
   11.46  
   11.47  	/* Set the timeout interval - Linux only needs to do this once */
   11.48  	then = SDL_GetTicks();
   11.49  
   11.50  	do {
   11.51  		/* Do background tasks required while sleeping as we are not multithreaded */
   11.52 +#ifdef DISABLE_THREADS
   11.53  		RISCOS_BackgroundTasks();
   11.54 +#else
   11.55 +		/* For threaded build only run background tasks in event thread */
   11.56 +		if (is_event_thread) RISCOS_BackgroundTasks();
   11.57 +#endif
   11.58 +
   11.59  		/* Calculate the time interval left (in case of interrupt) */
   11.60  		now = SDL_GetTicks();
   11.61  		elapsed = (now-then);
   11.62 @@ -95,10 +122,18 @@
   11.63  			break;
   11.64  		}
   11.65  		ms -= elapsed;
   11.66 +#ifndef DISABLE_THREADS
   11.67 +            /* Need to yield to let other threads have a go */
   11.68 +            if (riscos_using_threads) pthread_yield();
   11.69 +#endif
   11.70  
   11.71  	} while ( 1 );
   11.72  }
   11.73  
   11.74 +#ifdef DISABLE_THREADS
   11.75 +
   11.76 +/* Non-threaded version of timer */
   11.77 +
   11.78  int SDL_SYS_TimerInit(void)
   11.79  {
   11.80  	return(0);
   11.81 @@ -144,3 +179,56 @@
   11.82  		if (SDL_alarm_interval) timerStart = SDL_GetTicks();
   11.83  	}
   11.84  }
   11.85 +
   11.86 +#else
   11.87 +
   11.88 +/* Threaded version of timer - based on code for linux */
   11.89 +
   11.90 +#include "SDL_thread.h"
   11.91 +
   11.92 +/* Data to handle a single periodic alarm */
   11.93 +static int timer_alive = 0;
   11.94 +static SDL_Thread *timer = NULL;
   11.95 +
   11.96 +static int RunTimer(void *unused)
   11.97 +{
   11.98 +	while ( timer_alive ) {
   11.99 +		if ( SDL_timer_running ) {
  11.100 +			SDL_ThreadedTimerCheck();
  11.101 +		}
  11.102 +		SDL_Delay(1);
  11.103 +	}
  11.104 +	return(0);
  11.105 +}
  11.106 +
  11.107 +/* This is only called if the event thread is not running */
  11.108 +int SDL_SYS_TimerInit(void)
  11.109 +{
  11.110 +	timer_alive = 1;
  11.111 +	timer = SDL_CreateThread(RunTimer, NULL);
  11.112 +	if ( timer == NULL )
  11.113 +		return(-1);
  11.114 +	return(SDL_SetTimerThreaded(1));
  11.115 +}
  11.116 +
  11.117 +void SDL_SYS_TimerQuit(void)
  11.118 +{
  11.119 +	timer_alive = 0;
  11.120 +	if ( timer ) {
  11.121 +		SDL_WaitThread(timer, NULL);
  11.122 +		timer = NULL;
  11.123 +	}
  11.124 +}
  11.125 +
  11.126 +int SDL_SYS_StartTimer(void)
  11.127 +{
  11.128 +	SDL_SetError("Internal logic error: RISCOS uses threaded timer");
  11.129 +	return(-1);
  11.130 +}
  11.131 +
  11.132 +void SDL_SYS_StopTimer(void)
  11.133 +{
  11.134 +	return;
  11.135 +}
  11.136 +
  11.137 +#endif /* DISABLE_THREADS */
    12.1 --- a/src/video/riscos/SDL_riscosevents.c	Sat Sep 11 18:00:41 2004 +0000
    12.2 +++ b/src/video/riscos/SDL_riscosevents.c	Fri Sep 17 13:20:10 2004 +0000
    12.3 @@ -76,18 +76,23 @@
    12.4  
    12.5  void RISCOS_PollMouseHelper(_THIS, int fullscreen);
    12.6  
    12.7 +#ifdef DISABLE_THREADS
    12.8  extern void DRenderer_FillBuffers();
    12.9  
   12.10  /* Timer running function */
   12.11  extern void RISCOS_CheckTimer();
   12.12  
   12.13 +#endif
   12.14 +
   12.15  void FULLSCREEN_PumpEvents(_THIS)
   12.16  {
   12.17      /* Current implementation requires keyboard and mouse polling */
   12.18  	RISCOS_PollKeyboard();
   12.19  	RISCOS_PollMouse(this);
   12.20 +#ifdef DISABLE_THREADS
   12.21  	DRenderer_FillBuffers();
   12.22  	if (SDL_timer_running) RISCOS_CheckTimer();
   12.23 +#endif
   12.24  }
   12.25  
   12.26  
   12.27 @@ -538,3 +543,4 @@
   12.28  }
   12.29  
   12.30  /* end of SDL_riscosevents.c ... */
   12.31 +
    13.1 --- a/src/video/riscos/SDL_riscostask.c	Sat Sep 11 18:00:41 2004 +0000
    13.2 +++ b/src/video/riscos/SDL_riscostask.c	Fri Sep 17 13:20:10 2004 +0000
    13.3 @@ -39,6 +39,11 @@
    13.4  
    13.5  #include "SDL_riscostask.h"
    13.6  
    13.7 +#ifndef DISABLE_THREADS
    13.8 +#include <pthread.h>
    13.9 +pthread_t main_thread;
   13.10 +#endif
   13.11 +
   13.12  /* RISCOS variables */
   13.13  
   13.14  static int task_handle = 0;
   13.15 @@ -108,6 +113,10 @@
   13.16  	   return 1;
   13.17     }
   13.18  
   13.19 +#ifndef DISABLE_THREADS
   13.20 +   main_thread = pthread_self();
   13.21 +#endif
   13.22 +
   13.23     return 0;
   13.24  }
   13.25  
    14.1 --- a/src/video/riscos/SDL_wimppoll.c	Sat Sep 11 18:00:41 2004 +0000
    14.2 +++ b/src/video/riscos/SDL_wimppoll.c	Fri Sep 17 13:20:10 2004 +0000
    14.3 @@ -43,6 +43,10 @@
    14.4  #include "swis.h"
    14.5  #include "unixlib/os.h"
    14.6  
    14.7 +#ifndef DISABLE_THREADS
    14.8 +#include <pthread.h>
    14.9 +#endif
   14.10 +
   14.11  /* Local functions */
   14.12  void WIMP_Poll(_THIS, int waitTime);
   14.13  void WIMP_SetFocus(int win);
   14.14 @@ -56,11 +60,16 @@
   14.15  extern void WIMP_PollMouse(_THIS);
   14.16  extern void RISCOS_PollKeyboard();
   14.17  
   14.18 +#ifdef DISABLE_THREADS
   14.19  extern void DRenderer_FillBuffers();
   14.20  
   14.21  /* Timer running function */
   14.22  extern void RISCOS_CheckTimer();
   14.23  
   14.24 +#else
   14.25 +extern int riscos_using_threads;
   14.26 +#endif
   14.27 +
   14.28  /* Mouse cursor handling */
   14.29  extern void WIMP_ReshowCursor(_THIS);
   14.30  
   14.31 @@ -75,8 +84,10 @@
   14.32  	WIMP_Poll(this, 0);
   14.33  	if (hasFocus) RISCOS_PollKeyboard();
   14.34  	if (mouseInWindow) WIMP_PollMouse(this);
   14.35 +#ifdef DISABLE_THREADS
   14.36  	DRenderer_FillBuffers();
   14.37  	if (SDL_timer_running) RISCOS_CheckTimer();
   14.38 +#endif
   14.39  }
   14.40  
   14.41  
   14.42 @@ -100,10 +111,15 @@
   14.43  
   14.44      while (doPoll)
   14.45      {
   14.46 +#ifndef DISABLE_THREADS
   14.47 +       /* Stop thread callbacks while program is paged out */
   14.48 +       if (riscos_using_threads) __pthread_stop_ticker();
   14.49 +#endif
   14.50 +
   14.51          if (waitTime <= 0)
   14.52          {
   14.53          	regs.r[0] = pollMask; /* Poll Mask */
   14.54 -        	 /* For no wait time mask out null event so we wait until something happens */
   14.55 +        	/* For no wait time mask out null event so we wait until something happens */
   14.56          	if (waitTime < 0) regs.r[0] |= 1;
   14.57          	regs.r[1] = (int)message;
   14.58          	_kernel_swi(Wimp_Poll, &regs, &regs);
   14.59 @@ -116,34 +132,34 @@
   14.60          }
   14.61  
   14.62  		/* Flag to specify if we post a SDL_SysWMEvent */
   14.63 -		sysEvent = 0;
   14.64 +	sysEvent = 0;
   14.65          
   14.66          code = (unsigned int)regs.r[0];
   14.67  
   14.68 -		switch(code)
   14.69 -		{
   14.70 -		case 0:  /* Null Event - drop out for standard processing*/
   14.71 -		   doPoll = 0;
   14.72 -		   break;
   14.73 +	switch(code)
   14.74 +	{
   14.75 +        case 0:  /* Null Event - drop out for standard processing*/
   14.76 +	   doPoll = 0;
   14.77 +	   break;
   14.78  
   14.79 -		case 1:     /* Redraw window */
   14.80 -        	_kernel_swi(Wimp_RedrawWindow, &regs,&regs);
   14.81 -			if (message[0] == sdlWindow)
   14.82 -			{
   14.83 -        		while (regs.r[0])
   14.84 -        		{
   14.85 -        			WIMP_PlotSprite(this, message[1], message[2]);
   14.86 -        			_kernel_swi(Wimp_GetRectangle, &regs, &regs);
   14.87 -        		}
   14.88 -			} else
   14.89 -			{
   14.90 -				/* TODO: Currently we just eat them - we may need to pass them on */
   14.91 -        		while (regs.r[0])
   14.92 -        		{
   14.93 -        			_kernel_swi(Wimp_GetRectangle, &regs, &regs);
   14.94 -        		}
   14.95 -			}
   14.96 -        	break;
   14.97 +	case 1:     /* Redraw window */
   14.98 +           _kernel_swi(Wimp_RedrawWindow, &regs,&regs);
   14.99 +	   if (message[0] == sdlWindow)
  14.100 +	   {
  14.101 +                 while (regs.r[0])
  14.102 +                 {
  14.103 +           	    WIMP_PlotSprite(this, message[1], message[2]);
  14.104 +           	    _kernel_swi(Wimp_GetRectangle, &regs, &regs);
  14.105 +                 }
  14.106 +	   } else
  14.107 +	  {
  14.108 +	/* TODO: Currently we just eat them - we may need to pass them on */
  14.109 +        	while (regs.r[0])
  14.110 +        	{
  14.111 +                        _kernel_swi(Wimp_GetRectangle, &regs, &regs);
  14.112 +        	}
  14.113 +	  }
  14.114 +          break;
  14.115          	
  14.116  		case 2:		/* Open window */
  14.117  		   if ( resizeOnOpen && message[0] == sdlWindow)
  14.118 @@ -277,7 +293,16 @@
  14.119  			/* Fall out of polling loop if message is successfully posted */
  14.120  			if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0;
  14.121  		}
  14.122 -
  14.123 +#ifndef DISABLE_THREADS
  14.124 +		if (riscos_using_threads)
  14.125 +		{
  14.126 +                   /* Restart ticker here so other thread can not interfere
  14.127 +                      with the Redraw processing */
  14.128 +		   if (riscos_using_threads) __pthread_start_ticker();
  14.129 +                   /* Give other threads a better chance of running */
  14.130 +		   pthread_yield();
  14.131 +		}
  14.132 +#endif
  14.133      }
  14.134  }
  14.135  
  14.136 @@ -303,7 +328,9 @@
  14.137  	{
  14.138  		WIMP_Poll(current_video, 0);
  14.139  	}
  14.140 +#ifdef DISABLE_THREADS
  14.141  	/* Keep sound buffers running */
  14.142  	DRenderer_FillBuffers();
  14.143  	if (SDL_timer_running) RISCOS_CheckTimer();
  14.144 +#endif
  14.145  }