Commit c52f363a authored by Sam Lantinga's avatar Sam Lantinga

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.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40956
parent a5a84be7
Readme for RISC OS port of SDL
==============================
This document last updated on 25th June 2004
This is a RISC OS port of the Simple Direct Media Layer (SDL) by Alan Buckley.
Details of the SDL can be found at http://www.libsdl.org.
The source code including the RISC OS version can be obtained from http://www.libsdl.org.
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.
This is released under the LGPL see the file COPYING for details.
RISCOS port of SDL runtime information
======================================
Runtime requirements
--------------------
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.
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:
http://home.t-online.de/~zarquon
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.
RISCOS runtime parameters
-------------------------
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).
They are all defined on an application basis.
The <appname> used below is found as follows:
1. Use the name of the program unless it is !RunImage
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.
The variables are:
SDL$<appname>$TaskName - The name of the task for RISCOS. If omitted then <appname> is used for the task name,
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.
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.
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.
RISCOS SDL port API notes
=========================
Current level of implementation
-------------------------------
The following list is an overview of how much of the SDL is implemented. The areas match the main areas of the SDL.
video - Mostly done. Doesn't cover gamma, YUV-overlay or open gl.
Window Manager - Mostly done. SetIcon/IconifyWindow not implemented.
Events - Mostly done. Resize and some joystick events missing.
Joystick - Currently assumes a single joystick with 4 buttons.
Audio - Requires Digital Renderer module.
CDROM - Not implemented.
Threads - Done
Timers - Done
Thread support can be removed by defining DISABLE_THREADS and recompiling the library.
SDL API notes
-------------
This section contains additional notes on some specific commands.
SDL_SetVideoMode
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.
Open GL is not supported so SDL_OPENGL and SDL_OPENGLBLIT flags fail.
SDL_RESIZEABLE and SDL_NOFRAME flags are not supported.
SDL_SetColors
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.
SDL_CreateCursor
Inverted colour is not supported.
SDL_WM_ToggleFullScreen
Currently this won't work if the application starts up in Fullscreen mode.
Toggling to fullscreen will only work if the monitor is set up to support the exact screen size requested.
SDL_EnableUNICODE
Unicode translation used here is only really accurate for 7 bit characters.
SDL_NumJoysticks/JoystickName etc.
Hardcoded to expect only 1 joystick with 4 buttons if the Joystick module is loaded.
SDL_GetTicks
Timer used has only a centisecond accuracy. This applies to other time related functions.
SDL_Delay
Modified to poll keyboard/mouse during the delay on the event thread.
Notes on current implementation
-------------------------------
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.
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.
...@@ -2605,20 +2605,45 @@ case "$target" in ...@@ -2605,20 +2605,45 @@ case "$target" in
;; ;;
*-*-riscos) *-*-riscos)
ARCH=riscos ARCH=riscos
JOYSTICK_SUBDIRS="$JOYSTICK_SUBDIRS riscos" # Set up files for the video library
JOYSTICK_DRIVERS="$JOYSTICK_DRIVERS riscos/libjoystick_riscos.la" if test x$enable_video = xyes; then
COPY_ARCH_SRC(src/timer, riscos, SDL_systimer.c) VIDEO_SUBDIRS="$VIDEO_SUBDIRS riscos"
VIDEO_SUBDIRS="$VIDEO_SUBDIRS riscos" VIDEO_DRIVERS="$VIDEO_DRIVERS riscos/libvideo_riscos.la"
VIDEO_DRIVERS="$VIDEO_DRIVERS riscos/libvideo_riscos.la" fi
AUDIO_SUBDIRS="$AUDIO_SUBDIRS riscos" # Set up files for the audio library
AUDIO_DRIVERS="$AUDIO_DRIVERS riscos/libaudio_riscos.la" if test x$enable_audio = xyes; then
AUDIO_SUBDIRS="$AUDIO_SUBDIRS riscos"
AUDIO_DRIVERS="$AUDIO_DRIVERS riscos/libaudio_riscos.la"
fi
# Set up files for the joystick library
if test x$enable_joystick = xyes; then
JOYSTICK_SUBDIRS="$JOYSTICK_SUBDIRS riscos"
JOYSTICK_DRIVERS="$JOYSTICK_DRIVERS riscos/libjoystick_riscos.la"
fi
# Set up files for the cdrom library
if test x$enable_cdrom = xyes; then if test x$enable_cdrom = xyes; then
CDROM_SUBDIRS="$CDROM_SUBDIRS dummy" CDROM_SUBDIRS="$CDROM_SUBDIRS dummy"
CDROM_DRIVERS="$CDROM_DRIVERS dummy/libcdrom_dummy.la" CDROM_DRIVERS="$CDROM_DRIVERS dummy/libcdrom_dummy.la"
fi fi
# Set up files for the thread library
if test x$enable_threads = xyes; then
COPY_ARCH_SRC(src/thread, riscos, SDL_systhread.c)
COPY_ARCH_SRC(src/thread, riscos, SDL_systhread_c.h)
COPY_ARCH_SRC(src/thread, riscos, SDL_sysmutex.c)
COPY_ARCH_SRC(src/thread, riscos, SDL_sysmutex_c.h)
COPY_ARCH_SRC(src/thread, riscos, SDL_syssem.c)
COPY_ARCH_SRC(src/thread, generic, SDL_syssem_c.h)
COPY_ARCH_SRC(src/thread, riscos, SDL_syscond.c)
COPY_ARCH_SRC(src/thread, generic, SDL_syscond_c.h)
else
CFLAGS="$CFLAGS -DDISABLE_THREADS"
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then
COPY_ARCH_SRC(src/timer, riscos, SDL_systimer.c)
fi
CFLAGS="$CFLAGS -DDISABLE_THREADS -DENABLE_RISCOS -DDRENDERER_SUPPORT" CFLAGS="$CFLAGS -DENABLE_RISCOS -DDRENDERER_SUPPORT"
SYSTEM_LIBS="$SYSTEM_LIBS -ljpeg -ltiff -lpng -lz" SYSTEM_LIBS="$SYSTEM_LIBS -ljpeg -ltiff -lpng -lz"
;; ;;
......
...@@ -399,7 +399,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) ...@@ -399,7 +399,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
return(-1); return(-1);
} }
#if defined(macintosh) || defined(__riscos__) #if defined(macintosh) || (defined(__riscos__) && !defined(DISABLE_THREADS))
/* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */ /* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
#else #else
#if defined(__MINT__) && !defined(ENABLE_THREADS) #if defined(__MINT__) && !defined(ENABLE_THREADS)
......
...@@ -35,6 +35,10 @@ ...@@ -35,6 +35,10 @@
#include "SDL_sysaudio.h" #include "SDL_sysaudio.h"
#include "SDL_drenderer.h" #include "SDL_drenderer.h"
#ifndef DISABLE_THREADS
#include <pthread.h>
#endif
#define DigitalRenderer_Activate 0x4F700 #define DigitalRenderer_Activate 0x4F700
#define DigitalRenderer_Deactivate 0x4F701 #define DigitalRenderer_Deactivate 0x4F701
#define DigitalRenderer_ReadState 0x4F705 #define DigitalRenderer_ReadState 0x4F705
...@@ -57,6 +61,12 @@ extern int riscos_audiobuffer; /* Override for audio buffer size */ ...@@ -57,6 +61,12 @@ extern int riscos_audiobuffer; /* Override for audio buffer size */
static void DRenderer_CloseAudio(_THIS); static void DRenderer_CloseAudio(_THIS);
static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec); static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec);
#ifndef DISABLE_THREADS
static void DRenderer_WaitAudio(_THIS);
static Uint8 *DRenderer_GetAudioBuf(_THIS);
static void DRenderer_PlayAudio(_THIS);
#endif
/* Audio driver bootstrap functions */ /* Audio driver bootstrap functions */
/* Define following to dump stats to stdout */ /* Define following to dump stats to stdout */
...@@ -104,6 +114,11 @@ static SDL_AudioDevice *Audio_CreateDevice(int devindex) ...@@ -104,6 +114,11 @@ static SDL_AudioDevice *Audio_CreateDevice(int devindex)
/* Set the function pointers */ /* Set the function pointers */
this->OpenAudio = DRenderer_OpenAudio; this->OpenAudio = DRenderer_OpenAudio;
this->CloseAudio = DRenderer_CloseAudio; this->CloseAudio = DRenderer_CloseAudio;
#ifndef DISABLE_THREADS
this->GetAudioBuf = DRenderer_GetAudioBuf;
this->PlayAudio = DRenderer_PlayAudio;
this->WaitAudio = DRenderer_WaitAudio;
#endif
this->free = Audio_DeleteDevice; this->free = Audio_DeleteDevice;
return this; return this;
...@@ -117,6 +132,9 @@ AudioBootStrap DRENDERER_bootstrap = { ...@@ -117,6 +132,9 @@ AudioBootStrap DRENDERER_bootstrap = {
/* Routine called to check and fill audio buffers if necessary */ /* Routine called to check and fill audio buffers if necessary */
static Uint8 *buffer = NULL; static Uint8 *buffer = NULL;
#ifdef DISABLE_THREADS
/* Buffer fill routine called during polling */
void DRenderer_FillBuffers() void DRenderer_FillBuffers()
{ {
SDL_AudioDevice *audio = current_audio; SDL_AudioDevice *audio = current_audio;
...@@ -182,15 +200,33 @@ void DRenderer_FillBuffers() ...@@ -182,15 +200,33 @@ void DRenderer_FillBuffers()
} }
} }
#endif
/* Size of DMA buffer to use */ /* Size of DMA buffer to use */
#define DRENDERER_BUFFER_SIZE 512 #define DRENDERER_BUFFER_SIZE 512
/* Number of centiseconds of sound to buffer. /* Number of centiseconds of sound to buffer.
Hopefully more than the maximum time between calls to the Hopefully more than the maximum time between calls to the
FillBuffers routine above FillBuffers routine above (non-threaded) or the PlayAudio
routine below (threaded).
*/ */
#define DRENDERER_CSEC_TO_BUFFER 10 #define DRENDERER_CSEC_TO_BUFFER 10
static void DeactivateAudio()
{
_kernel_swi_regs regs;
/* Close down the digital renderer */
_kernel_swi(DigitalRenderer_Deactivate, &regs, &regs);
if (buffer != NULL)
{
free(buffer);
buffer = NULL;
}
}
static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
{ {
_kernel_swi_regs regs; _kernel_swi_regs regs;
...@@ -200,6 +236,7 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -200,6 +236,7 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
printf("Request format %d\n", spec->format); printf("Request format %d\n", spec->format);
printf("Request freq %d\n", spec->freq); printf("Request freq %d\n", spec->freq);
printf("Samples %d\n", spec->samples); printf("Samples %d\n", spec->samples);
printf("Channels %d\n", spec->channels);
#endif #endif
/* Only support signed 16bit format */ /* Only support signed 16bit format */
...@@ -207,9 +244,6 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -207,9 +244,6 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
if (spec->samples < DRENDERER_BUFFER_SIZE) spec->samples = DRENDERER_BUFFER_SIZE; if (spec->samples < DRENDERER_BUFFER_SIZE) spec->samples = DRENDERER_BUFFER_SIZE;
SDL_CalculateAudioSpec(spec);
buffers_per_sample = spec->samples / DRENDERER_BUFFER_SIZE; buffers_per_sample = spec->samples / DRENDERER_BUFFER_SIZE;
if ((spec->samples % DRENDERER_BUFFER_SIZE) != 0) if ((spec->samples % DRENDERER_BUFFER_SIZE) != 0)
...@@ -217,6 +251,7 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -217,6 +251,7 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
buffers_per_sample++; buffers_per_sample++;
spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE; spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE;
} }
/* Set number of buffers to use - the following should give enough /* Set number of buffers to use - the following should give enough
data between calls to the sound polling. data between calls to the sound polling.
...@@ -227,7 +262,19 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -227,7 +262,19 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
FillBuffer = (int)((double)DRENDERER_CSEC_TO_BUFFER / ((double)DRENDERER_BUFFER_SIZE * 100.0 / (double)spec->freq)) + 1; FillBuffer = (int)((double)DRENDERER_CSEC_TO_BUFFER / ((double)DRENDERER_BUFFER_SIZE * 100.0 / (double)spec->freq)) + 1;
} else FillBuffer = riscos_audiobuffer/DRENDERER_BUFFER_SIZE - buffers_per_sample; } else FillBuffer = riscos_audiobuffer/DRENDERER_BUFFER_SIZE - buffers_per_sample;
if (FillBuffer < buffers_per_sample) FillBuffer = buffers_per_sample; if (FillBuffer < buffers_per_sample) FillBuffer = buffers_per_sample;
#ifndef DISABLE_THREADS
if (buffers_per_sample < FillBuffer)
{
/* For the threaded version we are only called once per cycle
so the callback needs to give us the full data we need in
one go, rather than multiple calls as it the case for the
non threaded version */
buffers_per_sample = FillBuffer;
spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE;
}
#endif
SDL_CalculateAudioSpec(spec);
regs.r[0] = FillBuffer + buffers_per_sample; regs.r[0] = FillBuffer + buffers_per_sample;
#ifdef DUMP_AUDIO #ifdef DUMP_AUDIO
...@@ -259,6 +306,9 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -259,6 +306,9 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
spec->freq = regs.r[0]; spec->freq = regs.r[0];
} }
/* Ensure sound is deactivated if we exit without calling SDL_Quit */
atexit(DeactivateAudio);
#ifdef DUMP_AUDIO #ifdef DUMP_AUDIO
printf("Got format %d\n", spec->format); printf("Got format %d\n", spec->format);
printf("Frequency %d\n", spec->freq); printf("Frequency %d\n", spec->freq);
...@@ -277,17 +327,56 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) ...@@ -277,17 +327,56 @@ static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
return -1; return -1;
} }
#ifdef DISABLE_THREADS
/* Hopefully returning 2 will show success, but not start up an audio thread */ /* Hopefully returning 2 will show success, but not start up an audio thread */
return 2; return 2;
#else
/* Success and start audio thread */
return 0;
#endif
} }
static void DRenderer_CloseAudio(_THIS) static void DRenderer_CloseAudio(_THIS)
{ {
_kernel_swi_regs regs; DeactivateAudio();
}
/* Close down the digital renderer */ #ifndef DISABLE_THREADS
_kernel_swi(DigitalRenderer_Deactivate, &regs, &regs);
/* Routines for threaded version of audio */
if (buffer != NULL) free(buffer); void DRenderer_WaitAudio(_THIS)
{
_kernel_swi_regs regs;
int waiting = 1;
while (waiting)
{
/* Check filled buffers count */
_kernel_swi(DigitalRenderer_StreamStatistics, &regs, &regs);
#if 0
if (regs.r[0] <= FillBuffer)
{
printf("Buffers in use %d\n", regs.r[0]);
}
#endif
if (regs.r[0] <= FillBuffer) waiting = 0;
else pthread_yield();
}
}
Uint8 *DRenderer_GetAudioBuf(_THIS)
{
return buffer;
} }
void DRenderer_PlayAudio(_THIS)
{
_kernel_swi_regs regs;
regs.r[0] = (int)buffer;
regs.r[1] = current_audio->spec.samples * current_audio->spec.channels;
_kernel_swi(DigitalRenderer_Stream16BitSamples, &regs, &regs);
}
#endif
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
/* RISC OS implementations uses pthreads based on linux code */
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#ifdef DISABLE_THREADS
#include "../generic/SDL_syscond.c"
#else
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_sysmutex_c.h"
struct SDL_cond
{
pthread_cond_t cond;
};
/* Create a condition variable */
SDL_cond * SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) malloc(sizeof(SDL_cond));
if ( cond ) {
if ( pthread_cond_init(&cond->cond, NULL) < 0 ) {
SDL_SetError("pthread_cond_init() failed");
free(cond);
cond = NULL;
}
}
return(cond);
}
/* Destroy a condition variable */
void SDL_DestroyCond(SDL_cond *cond)
{
if ( cond ) {
pthread_cond_destroy(&cond->cond);
free(cond);
}
}
/* Restart one of the threads that are waiting on the condition variable */
int SDL_CondSignal(SDL_cond *cond)
{
int retval;
if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if ( pthread_cond_signal(&cond->cond) != 0 ) {
SDL_SetError("pthread_cond_signal() failed");
retval = -1;
}
return retval;
}
/* Restart all threads that are waiting on the condition variable */
int SDL_CondBroadcast(SDL_cond *cond)
{
int retval;
if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if ( pthread_cond_broadcast(&cond->cond) != 0 ) {
SDL_SetError("pthread_cond_broadcast() failed");
retval = -1;
}
return retval;
}
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
int retval;
struct timeval delta;
struct timespec abstime;
if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
gettimeofday(&delta, NULL);
abstime.tv_sec = delta.tv_sec + (ms/1000);
abstime.tv_nsec = (delta.tv_usec + (ms%1000) * 1000) * 1000;
if ( abstime.tv_nsec > 1000000000 ) {
abstime.tv_sec += 1;
abstime.tv_nsec -= 1000000000;
}
tryagain:
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
switch (retval) {
case EINTR:
goto tryagain;
break;
case ETIMEDOUT:
retval = SDL_MUTEX_TIMEDOUT;
break;
case 0:
break;
default:
SDL_SetError("pthread_cond_timedwait() failed");
retval = -1;
break;
}
return retval;
}
/* Wait on the condition variable, unlocking the provided mutex.
The mutex must be locked before entering this function!
*/
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
int retval;
if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) {
SDL_SetError("pthread_cond_wait() failed");
retval = -1;
}
return retval;
}
#endif
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
/* RISC OS implementations uses pthreads based on linux code */
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#ifdef DISABLE_THREADS
#include "../generic/SDL_sysmutex.c"
#else
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include "SDL_error.h"
#include "SDL_thread.h"
struct SDL_mutex {
pthread_mutex_t id;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
int recursive;
pthread_t owner;
#endif
};
SDL_mutex *SDL_CreateMutex (void)
{
SDL_mutex *mutex;
pthread_mutexattr_t attr;
/* Allocate the structure */
mutex = (SDL_mutex *)calloc(1, sizeof(*mutex));
if ( mutex ) {
pthread_mutexattr_init(&attr);
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
/* No extra attributes necessary */
#else
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#endif /* PTHREAD_NO_RECURSIVE_MUTEX */
if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) {
SDL_SetError("pthread_mutex_init() failed");
free(mutex);
mutex = NULL;
}
} else {
SDL_OutOfMemory();
}
return(mutex);
}
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if ( mutex ) {
pthread_mutex_destroy(&mutex->id);
free(mutex);
}
}
/* Lock the mutex */
int SDL_mutexP(SDL_mutex *mutex)
{
int retval;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
retval = 0;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
this_thread = pthread_self();
if ( mutex->owner == this_thread ) {
++mutex->recursive;
} else {
/* The order of operations is important.
We set the locking thread id after we obtain the lock
so unlocks from other threads will fail.
*/
if ( pthread_mutex_lock(&mutex->id) == 0 ) {
mutex->owner = this_thread;
mutex->recursive = 0;
} else {
SDL_SetError("pthread_mutex_lock() failed");
retval = -1;
}
}
#else
if ( pthread_mutex_lock(&mutex->id) < 0 ) {
SDL_SetError("pthread_mutex_lock() failed");
retval = -1;
}
#endif
return retval;
}
int SDL_mutexV(SDL_mutex *mutex)
{
int retval;
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
retval = 0;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
/* We can only unlock the mutex if we own it */
if ( pthread_self() == mutex->owner ) {
if ( mutex->recursive ) {
--mutex->recursive;
} else {
/* The order of operations is important.
First reset the owner so another thread doesn't lock
the mutex and set the ownership before we reset it,
then release the lock semaphore.
*/
mutex->owner = 0;
pthread_mutex_unlock(&mutex->id);
}
} else {
SDL_SetError("mutex not owned by this thread");
retval = -1;
}
#else
if ( pthread_mutex_unlock(&mutex->id) < 0 ) {
SDL_SetError("pthread_mutex_unlock() failed");
retval = -1;
}
#endif /* PTHREAD_NO_RECURSIVE_MUTEX */
return retval;
}
#endif
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#ifndef _SDL_mutex_c_h
#define _SDL_mutex_c_h
#ifndef DISABLE_THREADS
struct SDL_mutex {
pthread_mutex_t id;
};
#endif
#endif /* _SDL_mutex_c_h */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
/* RISC OS doesn't have semiphores so use code based on generic implementation */
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
/* An implementation of semaphores using mutexes and condition variables */
#include <stdlib.h>
#include "SDL_error.h"
#include "SDL_timer.h"
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
#ifdef DISABLE_THREADS
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_SetError("SDL not configured with thread support");
return (SDL_sem *)0;
}
void SDL_DestroySemaphore(SDL_sem *sem)
{
return;
}
int SDL_SemTryWait(SDL_sem *sem)
{
SDL_SetError("SDL not configured with thread support");
return -1;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
SDL_SetError("SDL not configured with thread support");
return -1;
}
int SDL_SemWait(SDL_sem *sem)
{
SDL_SetError("SDL not configured with thread support");
return -1;
}
Uint32 SDL_SemValue(SDL_sem *sem)
{
return 0;
}
int SDL_SemPost(SDL_sem *sem)
{
SDL_SetError("SDL not configured with thread support");
return -1;
}
#else
struct SDL_semaphore
{
Uint32 count;
Uint32 waiters_count;
SDL_mutex *count_lock;
SDL_cond *count_nonzero;
};
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;
sem = (SDL_sem *)malloc(sizeof(*sem));
if ( ! sem ) {
SDL_OutOfMemory();
return(0);
}
sem->count = initial_value;
sem->waiters_count = 0;
sem->count_lock = SDL_CreateMutex();
sem->count_nonzero = SDL_CreateCond();
if ( ! sem->count_lock || ! sem->count_nonzero ) {
SDL_DestroySemaphore(sem);
return(0);
}
return(sem);
}
/* WARNING:
You cannot call this function when another thread is using the semaphore.
*/
void SDL_DestroySemaphore(SDL_sem *sem)
{
if ( sem ) {
sem->count = 0xFFFFFFFF;
while ( sem->waiters_count > 0) {
SDL_CondSignal(sem->count_nonzero);
SDL_Delay(10);
}
SDL_DestroyCond(sem->count_nonzero);
SDL_mutexP(sem->count_lock);
SDL_mutexV(sem->count_lock);
SDL_DestroyMutex(sem->count_lock);
free(sem);
}
}
int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = SDL_MUTEX_TIMEDOUT;
SDL_LockMutex(sem->count_lock);
if ( sem->count > 0 ) {
--sem->count;
retval = 0;
}
SDL_UnlockMutex(sem->count_lock);
return retval;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
/* A timeout of 0 is an easy case */
if ( timeout == 0 ) {
return SDL_SemTryWait(sem);
}
SDL_LockMutex(sem->count_lock);
++sem->waiters_count;
retval = 0;
while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
retval = SDL_CondWaitTimeout(sem->count_nonzero,
sem->count_lock, timeout);
}
--sem->waiters_count;
--sem->count;
SDL_UnlockMutex(sem->count_lock);
return retval;
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32 SDL_SemValue(SDL_sem *sem)
{
Uint32 value;
value = 0;
if ( sem ) {
SDL_LockMutex(sem->count_lock);
value = sem->count;
SDL_UnlockMutex(sem->count_lock);
}
return value;
}
int SDL_SemPost(SDL_sem *sem)
{
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
SDL_LockMutex(sem->count_lock);
if ( sem->waiters_count > 0 ) {
SDL_CondSignal(sem->count_nonzero);
}
++sem->count;
SDL_UnlockMutex(sem->count_lock);
return 0;
}
#endif /* DISABLE_THREADS */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
/* RISC OS version based on pthreads linux source */
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_systhread.h"
#ifdef DISABLE_THREADS
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
SDL_SetError("Threads have not been compiled into this version of the library");
return(-1);
}
void SDL_SYS_SetupThread(void)
{
return;
}
Uint32 SDL_ThreadID(void)
{
return(0);
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
return;
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
return;
}
#else
#include <signal.h>
/* List of signals to mask in the subthreads */
static int sig_list[] = {
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
SIGVTALRM, SIGPROF, 0
};
#include <pthread.h>
int riscos_using_threads = 0;
Uint32 riscos_main_thread = 0; /* Thread running events */
static void *RunThread(void *data)
{
SDL_RunThread(data);
pthread_exit((void*)0);
return((void *)0); /* Prevent compiler warning */
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
pthread_attr_t type;
/* Set the thread attributes */
if ( pthread_attr_init(&type) != 0 ) {
SDL_SetError("Couldn't initialize pthread attributes");
return(-1);
}
pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
/* Create the thread and go! */
if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) {
SDL_SetError("Not enough resources to create thread");
return(-1);
}
if (riscos_using_threads == 0)
{
riscos_using_threads = 1;
riscos_main_thread = SDL_ThreadID();
}
return(0);
}
void SDL_SYS_SetupThread(void)
{
int i;
sigset_t mask;
/* Mask asynchronous signals for this thread */
sigemptyset(&mask);
for ( i=0; sig_list[i]; ++i ) {
sigaddset(&mask, sig_list[i]);
}
pthread_sigmask(SIG_BLOCK, &mask, 0);
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
/* Allow ourselves to be asynchronously cancelled */
{ int oldstate;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
}
#endif
}
Uint32 SDL_ThreadID(void)
{
return((Uint32)pthread_self());
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
pthread_join(thread->handle, 0);
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
pthread_cancel(thread->handle);
#else
pthread_kill(thread->handle, SIGKILL);
#endif
}
#endif
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#ifdef DISABLE_THREADS
typedef int SYS_ThreadHandle;
#else
#include <pthread.h>
typedef pthread_t SYS_ThreadHandle;
#endif
...@@ -36,10 +36,19 @@ static char rcsid = ...@@ -36,10 +36,19 @@ static char rcsid =
#include "SDL_timer.h" #include "SDL_timer.h"
#include "SDL_timer_c.h" #include "SDL_timer_c.h"
#ifdef DISABLE_THREADS
/* Timer start/reset time */ /* Timer start/reset time */
static Uint32 timerStart; static Uint32 timerStart;
/* Timer running function */ /* Timer running function */
void RISCOS_CheckTimer(); void RISCOS_CheckTimer();
#else
#include <pthread.h>
extern Uint32 riscos_main_thread;
extern int riscos_using_threads;
extern Uint32 SDL_ThreadID();
extern Uint32 SDL_EventThreadID(void);
#endif
extern void RISCOS_BackgroundTasks(void); extern void RISCOS_BackgroundTasks(void);
...@@ -75,18 +84,36 @@ Uint32 SDL_GetTicks (void) ...@@ -75,18 +84,36 @@ Uint32 SDL_GetTicks (void)
} }
extern void DRenderer_FillBuffers();
void SDL_Delay (Uint32 ms) void SDL_Delay (Uint32 ms)
{ {
Uint32 now,then,elapsed; Uint32 now,then,elapsed;
#ifndef DISABLE_THREADS
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 */ /* Set the timeout interval - Linux only needs to do this once */
then = SDL_GetTicks(); then = SDL_GetTicks();
do { do {
/* Do background tasks required while sleeping as we are not multithreaded */ /* Do background tasks required while sleeping as we are not multithreaded */
#ifdef DISABLE_THREADS
RISCOS_BackgroundTasks(); 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) */ /* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks(); now = SDL_GetTicks();
elapsed = (now-then); elapsed = (now-then);
...@@ -95,10 +122,18 @@ void SDL_Delay (Uint32 ms) ...@@ -95,10 +122,18 @@ void SDL_Delay (Uint32 ms)
break; break;
} }
ms -= elapsed; ms -= elapsed;
#ifndef DISABLE_THREADS
/* Need to yield to let other threads have a go */
if (riscos_using_threads) pthread_yield();
#endif
} while ( 1 ); } while ( 1 );
} }
#ifdef DISABLE_THREADS
/* Non-threaded version of timer */
int SDL_SYS_TimerInit(void) int SDL_SYS_TimerInit(void)
{ {
return(0); return(0);
...@@ -144,3 +179,56 @@ void RISCOS_CheckTimer() ...@@ -144,3 +179,56 @@ void RISCOS_CheckTimer()
if (SDL_alarm_interval) timerStart = SDL_GetTicks(); 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: RISCOS uses threaded timer");
return(-1);
}
void SDL_SYS_StopTimer(void)
{
return;
}
#endif /* DISABLE_THREADS */
...@@ -76,18 +76,23 @@ void RISCOS_PollKeyboard(); ...@@ -76,18 +76,23 @@ void RISCOS_PollKeyboard();
void RISCOS_PollMouseHelper(_THIS, int fullscreen); void RISCOS_PollMouseHelper(_THIS, int fullscreen);
#ifdef DISABLE_THREADS
extern void DRenderer_FillBuffers(); extern void DRenderer_FillBuffers();
/* Timer running function */ /* Timer running function */
extern void RISCOS_CheckTimer(); extern void RISCOS_CheckTimer();
#endif
void FULLSCREEN_PumpEvents(_THIS) void FULLSCREEN_PumpEvents(_THIS)
{ {
/* Current implementation requires keyboard and mouse polling */ /* Current implementation requires keyboard and mouse polling */
RISCOS_PollKeyboard(); RISCOS_PollKeyboard();
RISCOS_PollMouse(this); RISCOS_PollMouse(this);
#ifdef DISABLE_THREADS
DRenderer_FillBuffers(); DRenderer_FillBuffers();
if (SDL_timer_running) RISCOS_CheckTimer(); if (SDL_timer_running) RISCOS_CheckTimer();
#endif
} }
...@@ -538,3 +543,4 @@ static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed) ...@@ -538,3 +543,4 @@ static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed)
} }
/* end of SDL_riscosevents.c ... */ /* end of SDL_riscosevents.c ... */
...@@ -39,6 +39,11 @@ ...@@ -39,6 +39,11 @@
#include "SDL_riscostask.h" #include "SDL_riscostask.h"
#ifndef DISABLE_THREADS
#include <pthread.h>
pthread_t main_thread;
#endif
/* RISCOS variables */ /* RISCOS variables */
static int task_handle = 0; static int task_handle = 0;
...@@ -108,6 +113,10 @@ int RISCOS_InitTask() ...@@ -108,6 +113,10 @@ int RISCOS_InitTask()
return 1; return 1;
} }
#ifndef DISABLE_THREADS
main_thread = pthread_self();
#endif
return 0; return 0;
} }
......
...@@ -43,6 +43,10 @@ ...@@ -43,6 +43,10 @@
#include "swis.h" #include "swis.h"
#include "unixlib/os.h" #include "unixlib/os.h"
#ifndef DISABLE_THREADS
#include <pthread.h>
#endif
/* Local functions */ /* Local functions */
void WIMP_Poll(_THIS, int waitTime); void WIMP_Poll(_THIS, int waitTime);
void WIMP_SetFocus(int win); void WIMP_SetFocus(int win);
...@@ -56,11 +60,16 @@ void WIMP_PaletteChanged(_THIS); ...@@ -56,11 +60,16 @@ void WIMP_PaletteChanged(_THIS);
extern void WIMP_PollMouse(_THIS); extern void WIMP_PollMouse(_THIS);
extern void RISCOS_PollKeyboard(); extern void RISCOS_PollKeyboard();
#ifdef DISABLE_THREADS
extern void DRenderer_FillBuffers(); extern void DRenderer_FillBuffers();
/* Timer running function */ /* Timer running function */
extern void RISCOS_CheckTimer(); extern void RISCOS_CheckTimer();
#else
extern int riscos_using_threads;
#endif
/* Mouse cursor handling */ /* Mouse cursor handling */
extern void WIMP_ReshowCursor(_THIS); extern void WIMP_ReshowCursor(_THIS);
...@@ -75,8 +84,10 @@ void WIMP_PumpEvents(_THIS) ...@@ -75,8 +84,10 @@ void WIMP_PumpEvents(_THIS)
WIMP_Poll(this, 0); WIMP_Poll(this, 0);
if (hasFocus) RISCOS_PollKeyboard(); if (hasFocus) RISCOS_PollKeyboard();
if (mouseInWindow) WIMP_PollMouse(this); if (mouseInWindow) WIMP_PollMouse(this);
#ifdef DISABLE_THREADS
DRenderer_FillBuffers(); DRenderer_FillBuffers();
if (SDL_timer_running) RISCOS_CheckTimer(); if (SDL_timer_running) RISCOS_CheckTimer();
#endif
} }
...@@ -100,10 +111,15 @@ void WIMP_Poll(_THIS, int waitTime) ...@@ -100,10 +111,15 @@ void WIMP_Poll(_THIS, int waitTime)
while (doPoll) while (doPoll)
{ {
#ifndef DISABLE_THREADS
/* Stop thread callbacks while program is paged out */
if (riscos_using_threads) __pthread_stop_ticker();
#endif
if (waitTime <= 0) if (waitTime <= 0)
{ {
regs.r[0] = pollMask; /* Poll Mask */ regs.r[0] = pollMask; /* Poll Mask */
/* For no wait time mask out null event so we wait until something happens */ /* For no wait time mask out null event so we wait until something happens */
if (waitTime < 0) regs.r[0] |= 1; if (waitTime < 0) regs.r[0] |= 1;
regs.r[1] = (int)message; regs.r[1] = (int)message;
_kernel_swi(Wimp_Poll, &regs, &regs); _kernel_swi(Wimp_Poll, &regs, &regs);
...@@ -116,34 +132,34 @@ void WIMP_Poll(_THIS, int waitTime) ...@@ -116,34 +132,34 @@ void WIMP_Poll(_THIS, int waitTime)
} }
/* Flag to specify if we post a SDL_SysWMEvent */ /* Flag to specify if we post a SDL_SysWMEvent */
sysEvent = 0; sysEvent = 0;
code = (unsigned int)regs.r[0]; code = (unsigned int)regs.r[0];
switch(code) switch(code)
{ {
case 0: /* Null Event - drop out for standard processing*/ case 0: /* Null Event - drop out for standard processing*/
doPoll = 0; doPoll = 0;
break; break;
case 1: /* Redraw window */ case 1: /* Redraw window */
_kernel_swi(Wimp_RedrawWindow, &regs,&regs); _kernel_swi(Wimp_RedrawWindow, &regs,&regs);
if (message[0] == sdlWindow) if (message[0] == sdlWindow)
{ {
while (regs.r[0]) while (regs.r[0])
{ {
WIMP_PlotSprite(this, message[1], message[2]); WIMP_PlotSprite(this, message[1], message[2]);
_kernel_swi(Wimp_GetRectangle, &regs, &regs); _kernel_swi(Wimp_GetRectangle, &regs, &regs);
} }
} else } else
{ {
/* TODO: Currently we just eat them - we may need to pass them on */ /* TODO: Currently we just eat them - we may need to pass them on */
while (regs.r[0]) while (regs.r[0])
{ {
_kernel_swi(Wimp_GetRectangle, &regs, &regs); _kernel_swi(Wimp_GetRectangle, &regs, &regs);
} }
} }
break; break;
case 2: /* Open window */ case 2: /* Open window */
if ( resizeOnOpen && message[0] == sdlWindow) if ( resizeOnOpen && message[0] == sdlWindow)
...@@ -277,7 +293,16 @@ void WIMP_Poll(_THIS, int waitTime) ...@@ -277,7 +293,16 @@ void WIMP_Poll(_THIS, int waitTime)
/* Fall out of polling loop if message is successfully posted */ /* Fall out of polling loop if message is successfully posted */
if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0; if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0;
} }
#ifndef DISABLE_THREADS
if (riscos_using_threads)
{
/* Restart ticker here so other thread can not interfere
with the Redraw processing */
if (riscos_using_threads) __pthread_start_ticker();
/* Give other threads a better chance of running */
pthread_yield();
}
#endif
} }
} }
...@@ -303,7 +328,9 @@ void RISCOS_BackgroundTasks(void) ...@@ -303,7 +328,9 @@ void RISCOS_BackgroundTasks(void)
{ {
WIMP_Poll(current_video, 0); WIMP_Poll(current_video, 0);
} }
#ifdef DISABLE_THREADS
/* Keep sound buffers running */ /* Keep sound buffers running */
DRenderer_FillBuffers(); DRenderer_FillBuffers();
if (SDL_timer_running) RISCOS_CheckTimer(); if (SDL_timer_running) RISCOS_CheckTimer();
#endif
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment