Commit e8ce0bc1 authored by Sam Lantinga's avatar Sam Lantinga

Added initial support for RISC OS (thanks Peter Naulls!)

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40631
parent 35f9bbcb
...@@ -19,7 +19,7 @@ Objective C, Perl, PHP, Pike, Python, and Ruby. ...@@ -19,7 +19,7 @@ Objective C, Perl, PHP, Pike, Python, and Ruby.
The current version supports Linux, Windows, BeOS, MacOS, MacOS X, The current version supports Linux, Windows, BeOS, MacOS, MacOS X,
FreeBSD, OpenBSD, BSD/OS, Solaris, and IRIX. The code contains support FreeBSD, OpenBSD, BSD/OS, Solaris, and IRIX. The code contains support
for Windows CE, AmigaOS, Dreamcast, Atari, QNX, NetBSD, AIX, OSF/Tru64, for Windows CE, AmigaOS, Dreamcast, Atari, QNX, NetBSD, AIX, OSF/Tru64,
and SymbianOS, but these are not officially supported. RISC OS, and SymbianOS, but these are not officially supported.
This library is distributed under GNU LGPL version 2, which can be This library is distributed under GNU LGPL version 2, which can be
found in the file "COPYING". This license allows you to use SDL found in the file "COPYING". This license allows you to use SDL
......
...@@ -130,6 +130,23 @@ typedef struct { ...@@ -130,6 +130,23 @@ typedef struct {
HGLRC hglrc; /* The OpenGL context, if any */ HGLRC hglrc; /* The OpenGL context, if any */
} SDL_SysWMinfo; } SDL_SysWMinfo;
#elif defined(__riscos__)
/* RISC OS custom event structure */
struct SDL_SysWMmsg {
SDL_version version;
int eventCode; /* The window for the message */
int pollBlock[64];
};
/* The RISCOS custom window manager information structure */
typedef struct {
SDL_version version;
int wimpVersion; /* Wimp version running under */
int taskHandle; /* The RISCOS task handle */
int window; /* The RISCOS display window */
} SDL_SysWMinfo;
#else #else
/* The generic custom event structure */ /* The generic custom event structure */
......
...@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libaudio.la ...@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libaudio.la
# Define which subdirectories need to be built # Define which subdirectories need to be built
SUBDIRS = @AUDIO_SUBDIRS@ SUBDIRS = @AUDIO_SUBDIRS@
DIST_SUBDIRS = alsa arts baudio dma dmedia dsp esd macrom nas nto openbsd \ DIST_SUBDIRS = alsa arts baudio dma dmedia dsp esd macrom nas nto openbsd \
paudio sun ums windib windx5 disk mint dc paudio riscos sun ums windib windx5 disk mint dc
DRIVERS = @AUDIO_DRIVERS@ DRIVERS = @AUDIO_DRIVERS@
......
...@@ -91,6 +91,9 @@ static AudioBootStrap *bootstrap[] = { ...@@ -91,6 +91,9 @@ static AudioBootStrap *bootstrap[] = {
#endif #endif
#ifdef ENABLE_DC #ifdef ENABLE_DC
&DCAUD_bootstrap, &DCAUD_bootstrap,
#endif
#ifdef DRENDERER_SUPPORT
&DRENDERER_bootstrap,
#endif #endif
NULL NULL
}; };
...@@ -381,7 +384,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) ...@@ -381,7 +384,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
return(-1); return(-1);
} }
#ifdef macintosh #if defined(macintosh) || defined(__riscos__)
/* 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)
......
...@@ -156,6 +156,9 @@ extern AudioBootStrap DISKAUD_bootstrap; ...@@ -156,6 +156,9 @@ extern AudioBootStrap DISKAUD_bootstrap;
#ifdef ENABLE_DC #ifdef ENABLE_DC
extern AudioBootStrap DCAUD_bootstrap; extern AudioBootStrap DCAUD_bootstrap;
#endif #endif
#ifdef DRENDERER_SUPPORT
extern AudioBootStrap DRENDERER_bootstrap;
#endif
/* This is the current audio device */ /* This is the current audio device */
extern SDL_AudioDevice *current_audio; extern SDL_AudioDevice *current_audio;
......
## Makefile.am for SDL using the RISC OS audio system
noinst_LTLIBRARIES = libaudio_riscos.la
libaudio_riscos_la_SOURCES = $(SRCS)
# The SDL audio driver sources
SRCS = SDL_drenderer.c \
SDL_drenderer.h
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <kernel.h>
#include "swis.h"
#include "SDL_endian.h"
#include "SDL_audio.h"
#include "SDL_audio_c.h"
#include "SDL_audiomem.h"
#include "SDL_sysaudio.h"
#include "SDL_drenderer.h"
#define DigitalRenderer_Activate 0x4F700
#define DigitalRenderer_Deactivate 0x4F701
#define DigitalRenderer_ReadState 0x4F705
#define DigitalRenderer_NewSample 0x4F706
#define DigitalRenderer_NumBuffers 0x4F709
#define DigitalRenderer_StreamSamples 0x4F70A
#define DigitalRenderer_Stream16BitSamples 0x4F70B
#define DigitalRenderer_StreamStatistics 0x4F70C
#define DigitalRenderer_StreamFlags 0x4F70D
#define DigitalRenderer_Activate16 0x4F70F
#define DigitalRenderer_GetFrequency 0x4F710
static int FillBuffer;
extern SDL_AudioDevice *current_audio;
extern int riscos_audiobuffer; /* Override for audio buffer size */
/* Audio driver functions */
static void DRenderer_CloseAudio(_THIS);
static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec);
/* Audio driver bootstrap functions */
/* Define following to dump stats to stdout */
/* #define DUMP_AUDIO */
static int Audio_Available(void)
{
_kernel_swi_regs regs;
int available = 0;
/* Use call to set buffers to also check if Module is loaded */
regs.r[0] = 0;
if (_kernel_swi(DigitalRenderer_NumBuffers, &regs, &regs) == 0) available = 1;
return(available);
}
static void Audio_DeleteDevice(SDL_AudioDevice *device)
{
free(device->hidden);
free(device);
}
static SDL_AudioDevice *Audio_CreateDevice(int devindex)
{
SDL_AudioDevice *this;
/* Initialize all variables that we clean on shutdown */
this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
if ( this ) {
memset(this, 0, (sizeof *this));
this->hidden = (struct SDL_PrivateAudioData *)
malloc((sizeof *this->hidden));
}
if ( (this == NULL) || (this->hidden == NULL) ) {
SDL_OutOfMemory();
if ( this ) {
free(this);
}
return(0);
}
memset(this->hidden, 0, (sizeof *this->hidden));
/* Set the function pointers */
this->OpenAudio = DRenderer_OpenAudio;
this->CloseAudio = DRenderer_CloseAudio;
this->free = Audio_DeleteDevice;
return this;
}
AudioBootStrap DRENDERER_bootstrap = {
"drenderer", "RiscOS Digital Renderer Module",
Audio_Available, Audio_CreateDevice
};
/* Routine called to check and fill audio buffers if necessary */
static Uint8 *buffer = NULL;
void DRenderer_FillBuffers()
{
SDL_AudioDevice *audio = current_audio;
if ( !audio || ! audio->enabled )
{
return;
}
if ( ! audio->paused )
{
_kernel_swi_regs regs;
/* Check filled buffers count */
_kernel_swi(DigitalRenderer_StreamStatistics, &regs, &regs);
#ifdef DUMP_AUDIO
if (regs.r[0] <= FillBuffer)
{
printf("Buffers in use %d\n", regs.r[0]);
}
#endif
while (regs.r[0] <= FillBuffer && !audio->paused)
{
if ( audio->convert.needed )
{
int silence;
if ( audio->convert.src_format == AUDIO_U8 )
{
silence = 0x80;
} else {
silence = 0;
}
memset(audio->convert.buf, silence, audio->convert.len);
audio->spec.callback(audio->spec.userdata,
(Uint8 *)audio->convert.buf,audio->convert.len);
SDL_ConvertAudio(&audio->convert);
#if 0
if ( audio->convert.len_cvt != audio->spec.size ) {
/* Uh oh... probably crashes here; */
}
#endif
regs.r[0] = (int)audio->convert.buf;
regs.r[1] = audio->spec.samples * audio->spec.channels;
_kernel_swi(DigitalRenderer_Stream16BitSamples, &regs, &regs);
} else
{
/* Fill buffer with silence */
memset (buffer, 0, audio->spec.size);
audio->spec.callback(audio->spec.userdata,
(Uint8 *)buffer, audio->spec.size);
regs.r[0] = (int)buffer;
regs.r[1] = audio->spec.samples * audio->spec.channels;
_kernel_swi(DigitalRenderer_Stream16BitSamples, &regs, &regs);
}
/* Check if we have enough buffers yet */
_kernel_swi(DigitalRenderer_StreamStatistics, &regs, &regs);
}
}
}
/* Size of DMA buffer to use */
#define DRENDERER_BUFFER_SIZE 512
/* Number of centiseconds of sound to buffer.
Hopefully more than the maximum time between calls to the
FillBuffers routine above
*/
#define DRENDERER_CSEC_TO_BUFFER 10
static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
_kernel_swi_regs regs;
int buffers_per_sample;
#ifdef DUMP_AUDIO
printf("Request format %d\n", spec->format);
printf("Request freq %d\n", spec->freq);
printf("Samples %d\n", spec->samples);
#endif
/* Only support signed 16bit format */
spec->format = AUDIO_S16LSB;
if (spec->samples < DRENDERER_BUFFER_SIZE) spec->samples = DRENDERER_BUFFER_SIZE;
SDL_CalculateAudioSpec(spec);
buffers_per_sample = spec->samples / DRENDERER_BUFFER_SIZE;
if ((spec->samples % DRENDERER_BUFFER_SIZE) != 0)
{
buffers_per_sample++;
spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE;
}
/* Set number of buffers to use - the following should give enough
data between calls to the sound polling.
*/
if (riscos_audiobuffer == 0)
{
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;
if (FillBuffer < buffers_per_sample) FillBuffer = buffers_per_sample;
regs.r[0] = FillBuffer + buffers_per_sample;
#ifdef DUMP_AUDIO
printf("Buffers per sample %d\n", buffers_per_sample);
printf("Fill buffer %d\n", FillBuffer);
printf("Time buffered (ms) %d\n",(int)((1000.0 * regs.r[0] * DRENDERER_BUFFER_SIZE)/(double)spec->freq));
#endif
if (_kernel_swi(DigitalRenderer_NumBuffers, &regs, &regs) != 0)
{
SDL_SetError("Can't set number of streaming sound buffers\n");
return -1;
}
/* Now initialise sound system */
regs.r[0] = spec->channels; /* Number of channels */
regs.r[1] = DRENDERER_BUFFER_SIZE; /* Samples length */
regs.r[2] = spec->freq; /* frequency */
regs.r[3] = 1; /* Restore previous handler on exit */
if (_kernel_swi(DigitalRenderer_Activate16, &regs, &regs) != 0)
{
SDL_SetError("Unable to activate digital renderer in 16 bit mode\n");
return -1;
}
if (_kernel_swi(DigitalRenderer_GetFrequency, &regs, &regs) == 0)
{
spec->freq = regs.r[0];
}
#ifdef DUMP_AUDIO
printf("Got format %d\n", spec->format);
printf("Frequency %d\n", spec->freq);
printf("Samples %d\n", spec->samples);
#endif
/* Set to fill buffer with zero if we don't get data to it fast enough */
regs.r[0] = 1;
regs.r[1] = ~1;
_kernel_swi(DigitalRenderer_StreamFlags, &regs, &regs);
buffer = (Uint8 *)malloc(sizeof(Uint8) * spec->size);
if (buffer == NULL)
{
SDL_OutOfMemory();
return -1;
}
/* Hopefully returning 2 will show success, but not start up an audio thread */
return 2;
}
static void DRenderer_CloseAudio(_THIS)
{
_kernel_swi_regs regs;
/* Close down the digital renderer */
_kernel_swi(DigitalRenderer_Deactivate, &regs, &regs);
if (buffer != NULL) free(buffer);
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
#ifndef _SDL_drenderer_h
#define _SDL_drenderer_h
#include "SDL_sysaudio.h"
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData {
unsigned char *audio_buf;
};
#endif /* _SDL_drenderer_h */
...@@ -5,7 +5,7 @@ noinst_LTLIBRARIES = libjoystick.la ...@@ -5,7 +5,7 @@ noinst_LTLIBRARIES = libjoystick.la
# Define which subdirectories need to be built # Define which subdirectories need to be built
SUBDIRS = @JOYSTICK_SUBDIRS@ SUBDIRS = @JOYSTICK_SUBDIRS@
DIST_SUBDIRS = dummy amigaos beos bsd darwin dc linux macos mint win32 DIST_SUBDIRS = dummy amigaos beos bsd darwin dc linux macos mint riscos win32
DRIVERS = @JOYSTICK_DRIVERS@ DRIVERS = @JOYSTICK_DRIVERS@
......
## Makefile.am for the RISC OS joystick driver for SDL
noinst_LTLIBRARIES = libjoystick_riscos.la
libjoystick_riscos_la_SOURCES = $(SRCS)
# The SDL joystick driver sources
SRCS = SDL_sysjoystick.c
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
/*
RISCOS - Joystick support by Alan Buckley (alan_baa@hotmail.com) - 10 April 2003
Note: Currently assumes joystick is present if joystick module is loaded
and that there is one joystick with four buttons.
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
/* This is the system specific header for the SDL joystick API */
#include <stdio.h> /* For the definition of NULL */
#include <stdlib.h>
#include "SDL_error.h"
#include "SDL_joystick.h"
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "kernel.h"
#define JOYSTICK_READ 0x43F40
struct joystick_hwdata
{
int joystate;
};
/* Function to scan the system for joysticks.
* This function should set SDL_numjoysticks to the number of available
* joysticks. Joystick 0 should be the system default joystick.
* It should return number of joysticks, or -1 on an unrecoverable fatal error.
*/
int SDL_SYS_JoystickInit(void)
{
_kernel_swi_regs regs;
/* Try to read joystick 0 */
regs.r[0] = 0;
if (_kernel_swi(JOYSTICK_READ, &regs, &regs) == NULL)
{
/* Switch works so assume we've got a joystick */
return 1;
}
/* Switch fails so it looks like there's no joystick here */
return(0);
}
/* Function to get the device-dependent name of a joystick */
const char *SDL_SYS_JoystickName(int index)
{
if (index == 0)
{
return "RISCOS Joystick 0";
}
SDL_SetError("No joystick available with that index");
return(NULL);
}
/* Function to open a joystick for use.
The joystick to open is specified by the index field of the joystick.
This should fill the nbuttons and naxes fields of the joystick structure.
It returns 0, or -1 if there is an error.
*/
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
{
_kernel_swi_regs regs;
if(!(joystick->hwdata=malloc(sizeof(struct joystick_hwdata))))
return -1;
regs.r[0] = joystick->index;
/* Don't know how to get exact count of buttons so assume max of 4 for now */
joystick->nbuttons=4;
joystick->nhats=0;
joystick->nballs=0;
joystick->naxes=2;
joystick->hwdata->joystate=0;
return 0;
}
/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
* and update joystick device state.
*/
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
{
_kernel_swi_regs regs;
regs.r[0] = joystick->index;
if (_kernel_swi(JOYSTICK_READ, &regs, &regs) == NULL)
{
int newstate = regs.r[0];
int oldstate = joystick->hwdata->joystate;
if (newstate != oldstate)
{
if ((newstate & 0xFF) != (oldstate & 0xFF))
{
int y = regs.r[0] & 0xFF;
/* Convert to signed values */
if (y >= 128) y -= 256;
SDL_PrivateJoystickAxis(joystick,1,-y * 256); /* Up and down opposite to result in SDL */
}
if ((newstate & 0xFF00) != (oldstate & 0xFF00))
{
int x = (regs.r[0] & 0xFF00) >> 8;
if (x >= 128) x -= 256;
SDL_PrivateJoystickAxis(joystick,0,x * 256);
}
if ((newstate & 0xFF0000) != (oldstate & 0xFF0000))
{
int buttons = (regs.r[0] & 0xFF0000) >> 16;
int oldbuttons = (oldstate & 0xFF0000) >> 16;
int i;
for (i = 0; i < joystick->nbuttons; i++)
{
if ((buttons & (1<<i)) != (oldbuttons & (1<<i)))
{
if (buttons & (1<<i)) SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
else SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
}
}
}
joystick->hwdata->joystate = newstate;
}
}
return;
}
/* Function to close a joystick after use */
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
{
if(joystick->hwdata)
free(joystick->hwdata);
return;
}
/* Function to perform any system-specific joystick related cleanup */
void SDL_SYS_JoystickQuit(void)
{
SDL_numjoysticks=0;
return;
}
...@@ -10,6 +10,7 @@ ARCH_SUBDIRS = $(srcdir)/amigaos \ ...@@ -10,6 +10,7 @@ ARCH_SUBDIRS = $(srcdir)/amigaos \
$(srcdir)/linux \ $(srcdir)/linux \
$(srcdir)/macos \ $(srcdir)/macos \
$(srcdir)/mint \ $(srcdir)/mint \
$(srcdir)/riscos \
$(srcdir)/win32 $(srcdir)/win32
# Include the architecture-independent sources # Include the architecture-independent sources
......
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "SDL_error.h"
#include "SDL_timer.h"
#include "SDL_timer_c.h"
/* Timer start/reset time */
static Uint32 timerStart;
/* Timer running function */
void RISCOS_CheckTimer();
extern void RISCOS_BackgroundTasks(void);
/* The first ticks value of the application */
clock_t start;
void SDL_StartTicks(void)
{
/* Set first ticks value */
start = clock();
}
Uint32 SDL_GetTicks (void)
{
clock_t ticks;
ticks=clock()-start;
#if CLOCKS_PER_SEC == 1000
return(ticks);
#elif CLOCKS_PER_SEC == 100
return (ticks * 10);
#else
return ticks*(1000/CLOCKS_PER_SEC);
#endif
}
extern void DRenderer_FillBuffers();
void SDL_Delay (Uint32 ms)
{
Uint32 now,then,elapsed;
/* Set the timeout interval - Linux only needs to do this once */
then = SDL_GetTicks();
do {
/* Do background tasks required while sleeping as we are not multithreaded */
RISCOS_BackgroundTasks();
/* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks();
elapsed = (now-then);
then = now;
if ( elapsed >= ms ) {
break;
}
ms -= elapsed;
} while ( 1 );
}
int SDL_SYS_TimerInit(void)
{
return(0);
}
void SDL_SYS_TimerQuit(void)
{
SDL_SetTimer(0, NULL);
}
int SDL_SYS_StartTimer(void)
{
timerStart = SDL_GetTicks();
return(0);
}
void SDL_SYS_StopTimer(void)
{
/* Don't need to do anything as we use SDL_timer_running
to detect if we need to check the timer */
}
void RISCOS_CheckTimer()
{
if (SDL_timer_running && SDL_GetTicks() - timerStart >= SDL_alarm_interval)
{
Uint32 ms;
ms = SDL_alarm_callback(SDL_alarm_interval);
if ( ms != SDL_alarm_interval )
{
if ( ms )
{
SDL_alarm_interval = ROUND_RESOLUTION(ms);
} else
{
SDL_alarm_interval = 0;
SDL_timer_running = 0;
}
}
if (SDL_alarm_interval) timerStart = SDL_GetTicks();
}
}
...@@ -7,7 +7,7 @@ noinst_LTLIBRARIES = libvideo.la ...@@ -7,7 +7,7 @@ noinst_LTLIBRARIES = libvideo.la
SUBDIRS = @VIDEO_SUBDIRS@ SUBDIRS = @VIDEO_SUBDIRS@
DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \ DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \
wincommon windib windx5 \ wincommon windib windx5 \
maccommon macdsp macrom quartz \ maccommon macdsp macrom riscos quartz \
bwindow ps2gs photon cybergfx epoc picogui \ bwindow ps2gs photon cybergfx epoc picogui \
ataricommon xbios gem dc qtopia XFree86 ataricommon xbios gem dc qtopia XFree86
......
...@@ -409,6 +409,9 @@ extern VideoBootStrap PG_bootstrap; ...@@ -409,6 +409,9 @@ extern VideoBootStrap PG_bootstrap;
#ifdef ENABLE_DC #ifdef ENABLE_DC
extern VideoBootStrap DC_bootstrap; extern VideoBootStrap DC_bootstrap;
#endif #endif
#ifdef ENABLE_RISCOS
extern VideoBootStrap RISCOS_bootstrap;
#endif
/* This is the current video device */ /* This is the current video device */
extern SDL_VideoDevice *current_video; extern SDL_VideoDevice *current_video;
......
...@@ -117,6 +117,9 @@ static VideoBootStrap *bootstrap[] = { ...@@ -117,6 +117,9 @@ static VideoBootStrap *bootstrap[] = {
#ifdef ENABLE_DC #ifdef ENABLE_DC
&DC_bootstrap, &DC_bootstrap,
#endif #endif
#ifdef ENABLE_RISCOS
&RISCOS_bootstrap,
#endif
#ifdef ENABLE_DUMMYVIDEO #ifdef ENABLE_DUMMYVIDEO
&DUMMY_bootstrap, &DUMMY_bootstrap,
#endif #endif
......
## Makefile.am for SDL using the RISC OS video driver
noinst_LTLIBRARIES = libvideo_riscos.la
libvideo_riscos_la_SOURCES = $(CGX_SRCS)
# The SDL RISC OS video driver sources
CGX_SRCS = \
SDL_riscosevents.c \
SDL_riscosevents_c.h \
SDL_riscosFullScreenVideo.c \
SDL_riscosmouse.c \
SDL_riscosmouse_c.h \
SDL_riscossprite.c \
SDL_riscostask.c \
SDL_riscostask.h \
SDL_riscosvideo.c \
SDL_riscosvideo.h \
SDL_wimppoll.c \
SDL_wimpvideo.c
This diff is collapsed.
This diff is collapsed.
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#include "SDL_riscosvideo.h"
/* Variables and functions exported by SDL_sysevents.c to other parts
of the native video subsystem (SDL_sysvideo.c)
*/
extern void RISCOS_InitOSKeymap(_THIS);
extern void FULLSCREEN_PumpEvents(_THIS);
extern void WIMP_PumpEvents(_THIS);
/* end of SDL_nullevents_c.h ... */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
/*
File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability
27 March 2003
Implements mouse cursor shape definitions and positioning
*/
#include <stdio.h>
#include <stdlib.h>
#include "SDL_error.h"
#include "SDL_mouse.h"
#include "SDL_events_c.h"
#include "SDL_riscosmouse_c.h"
#include "kernel.h"
#include "swis.h"
static WMcursor *current_cursor = NULL;
extern int mouseInWindow;
void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
{
free(cursor->data);
free(cursor);
}
WMcursor *RISCOS_CreateWMCursor(_THIS,
Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
{
WMcursor *cursor;
Uint8 *cursor_data;
Uint8 *ptr;
int i,j,k;
int data_byte, mask_byte;
/* Check to make sure the cursor size is okay */
if ( (w > 32) || (h > 32) ) {
SDL_SetError("Only with width and height <= 32 pixels are allowed");
return(NULL);
}
/* Allocate the cursor */
cursor = (WMcursor *)malloc(sizeof(*cursor));
if ( cursor == NULL ) {
SDL_SetError("Out of memory");
return(NULL);
}
/* Note: SDL says width must be a multiple of 8 */
cursor_data = malloc(w/4 * h);
if (cursor_data == NULL)
{
free(cursor);
SDL_SetError("Out of memory");
return(NULL);
}
cursor->w = w;
cursor->h = h;
cursor->hot_x = hot_x;
cursor->hot_y = hot_y;
cursor->data = cursor_data;
/* Data / Mask Resulting pixel on screen
0 / 1 White
1 / 1 Black
0 / 0 Transparent
1 / 0 Inverted color if possible, black if not.
*/
ptr = cursor_data;
for ( i=0; i<h; ++i )
{
for (j = 0; j < w/8; ++j)
{
data_byte = *data;
mask_byte = *mask;
*ptr++ = 0; /* Sets whole byte transparent */
*ptr = 0;
for (k = 0; k < 8; k++)
{
(*ptr) <<= 2;
if (data_byte & 1) *ptr |= 3; /* Black or inverted */
else if(mask_byte & 1) *ptr |= 1; /* White */
if ((k&3) == 3) ptr--;
data_byte >>= 1;
mask_byte >>= 1;
}
ptr+=3;
data++;
mask++;
}
}
return(cursor);
}
int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor)
{
if (cursor == NULL)
{
_kernel_osbyte(106,0,0);
current_cursor = NULL;
} else
{
if (current_cursor == NULL)
{
/* First time set up the mouse colours */
Uint8 block[5];
/* Set up colour 1 as white */
block[0] = 1; /* Colour to change 1 - 3 */
block[1] = 25; /* Set pointer colour */
block[2] = 255; /* red component*/
block[3] = 255; /* green component */
block[4] = 255; /* blue component*/
_kernel_osword(12, (int *)block);
/* Set colour 3 to back */
block[0] = 3; /* Colour to change 1 - 3 */
block[1] = 25; /* Set pointer colour*/
block[2] = 0; /* red component*/
block[3] = 0; /* green component */
block[4] = 0; /* blue component*/
_kernel_osword(12, (int *)block);
}
if (cursor != current_cursor)
{
Uint8 cursor_def[10];
cursor_def[0] = 0;
cursor_def[1] = 2; /* Use shape number 2 */
cursor_def[2] = cursor->w/4; /* Width in bytes */
cursor_def[3] = cursor->h; /* Height (h) in pixels */
cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */
cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */
cursor_def[6] = ((int)(cursor->data) & 0xFF); /* Least significant byte of pointer to data */
cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF; /* ... */
cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */
cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */
if (_kernel_osword(21, (int *)cursor_def) == 0)
{
SDL_SetError("RISCOS couldn't create the cursor to show");
return(0);
}
current_cursor = cursor;
}
if ((this->screen->flags & SDL_FULLSCREEN) || mouseInWindow) _kernel_osbyte(106, 2, 0);
}
return(1);
}
void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
{
Uint8 move_block[5];
int eig_block[3];
_kernel_swi_regs regs;
int os_x, os_y;
eig_block[0] = 4; /* X eig factor */
eig_block[1] = 5; /* Y eig factor */
eig_block[2] = -1; /* End of list of variables to request */
regs.r[0] = (int)eig_block;
regs.r[1] = (int)eig_block;
_kernel_swi(OS_ReadVduVariables, &regs, &regs);
os_x = x << eig_block[0];
os_y = y << eig_block[1];
move_block[0] = 3; /* Move cursor */
move_block[1] = os_x & 0xFF;
move_block[2] = (os_x >> 8) & 0xFF;
move_block[3] = os_y & 0xFF;
move_block[4] = (os_y >> 8) & 0xFF;
_kernel_osword(21, (int *)move_block);
SDL_PrivateMouseMotion(0, 0, x, y);
}
/* Reshow cursor when mouse re-enters the window */
void WIMP_ReshowCursor(_THIS)
{
WMcursor *cursor = current_cursor;
current_cursor = NULL;
RISCOS_ShowWMCursor(this, cursor);
}
extern int mouseInWindow;
void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
{
_kernel_swi_regs regs;
int window_state[9];
char block[5];
int osX, osY;
window_state[0] = this->hidden->window_handle;
regs.r[1] = (unsigned int)window_state;
_kernel_swi(Wimp_GetWindowState, &regs, &regs);
osX = (x << this->hidden->xeig) + window_state[1];
osY = window_state[4] - (y << this->hidden->yeig);
block[0] = 3;
block[1] = osX & 0xFF;
block[2] = (osX >> 8) & 0xFF;
block[3] = osY & 0xFF;
block[4] = (osY >> 8) & 0xFF;
regs.r[0] = 21;
regs.r[1] = (int)block;
_kernel_swi(OS_Word, &regs, &regs);
SDL_PrivateMouseMotion(0, 0, x, y);
}
int WIMP_ShowWMCursor(_THIS, WMcursor *cursor)
{
if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor);
return 1;
}
SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode)
{
/* In fullscreen mode we don't need to do anything */
if (mode < SDL_GRAB_FULLSCREEN)
{
_kernel_swi_regs regs;
unsigned char block[9];
block[0] = 1; /* Define mouse cursor bounding block */
if ( mode == SDL_GRAB_OFF )
{
/* Clip to whole screen */
int r = (this->hidden->screen_width << this->hidden->xeig) - 1;
int t = (this->hidden->screen_height << this->hidden->yeig) - 1;
block[1] = 0; block[2] = 0; /* Left*/
block[3] = 0; block[4] = 0; /* Bottom */
block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */
block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */
} else
{
/* Clip to window */
unsigned char window_state[36];
*((int *)window_state) = this->hidden->window_handle;
regs.r[1] = (unsigned int)window_state;
_kernel_swi(Wimp_GetWindowState, &regs, &regs);
block[1] = window_state[4];
block[2] = window_state[5];
block[3] = window_state[8];
block[4] = window_state[9];
block[5] = window_state[12];
block[6] = window_state[13];
block[7] = window_state[16];
block[8] = window_state[17];
}
regs.r[0] = 21; /* OS word code */
regs.r[1] = (int)block;
_kernel_swi(OS_Word, &regs, &regs);
}
return mode;
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#include "SDL_riscosvideo.h"
/* The implementation dependent data for the window manager cursor */
struct WMcursor {
int w;
int h;
int hot_x;
int hot_y;
Uint8 *data;
};
/* Functions to be exported */
void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor);
WMcursor *RISCOS_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor);
void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
int WIMP_ShowWMCursor(_THIS, WMcursor *cursor);
void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
/*
File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability
27 March 2003
Implements Sprite plotting code for wimp display.window
*/
#include <stdlib.h>
#include "kernel.h"
#include "swis.h"
#include "SDL_riscosvideo.h"
extern void WIMP_ReadModeInfo(_THIS);
void WIMP_PaletteChanged(_THIS);
/* Create sprite buffer for screen */
unsigned char *WIMP_CreateBuffer(int width, int height, int bpp)
{
int size;
char sprite_name[12] = "display";
unsigned char *buffer;
_kernel_swi_regs regs;
int bytesPerPixel;
int bytesPerRow;
int offsetToSpriteData = 60;
switch(bpp)
{
case 32: bytesPerPixel = 4; break;
case 16: bytesPerPixel = 2; break;
case 8:
bytesPerPixel = 1;
offsetToSpriteData += 2048; /* Add in size of palette */
break;
default:
return NULL;
break;
}
bytesPerRow = bytesPerPixel * width;
if ((bytesPerRow & 3) != 0)
{
bytesPerRow += 4 - (bytesPerRow & 3);
}
size = bytesPerRow * height;
buffer = malloc( (size_t) size + offsetToSpriteData );
if (!buffer) return NULL;
/* Initialise a sprite area */
*(unsigned int *)buffer = size + offsetToSpriteData;
*(unsigned int *)(buffer + 8) = 16;
regs.r[0] = 256+9;
regs.r[1] = (unsigned int)buffer;
_kernel_swi(OS_SpriteOp, &regs, &regs);
regs.r[0] = 256+15;
regs.r[1] = (unsigned int)buffer;
regs.r[2] = (unsigned int)&sprite_name;
regs.r[3] = 0; /* Palette flag: 0 = no palette */
regs.r[4] = width;
regs.r[5] = height;
if (bpp == 8)
{
/* Use old style mode number */
regs.r[6] = 28; /* 8bpp 90x90dpi */
} else
{
regs.r[6] = (((bpp == 16) ? 5 : 6) << 27) /* Type 6 = 32bpp sprite, 5 = 16bpp sprite */
| (90 << 14) /* Vertical dpi */
| (90 << 1) /* Horizontal dpi */
| 1; /* Marker to distinguish between mode selectors and sprite modes */
}
if (_kernel_swi(OS_SpriteOp, &regs, &regs) == NULL)
{
if (bpp == 8)
{
/* Modify sprite to take into account 256 colour palette */
int *sprite = (int *)(buffer + 16);
/* Adjust sprite offsets */
sprite[0] += 2048;
sprite[8] += 2048;
sprite[9] += 2048;
/* Adjust sprite area next free pointer */
(*(int *)(buffer+12)) += 2048;
/* Don't need to set up palette as SDL sets up the default
256 colour palette */
/* {
int *pal = sprite + 11;
unsigned int j;
unsigned int entry;
for (j = 0; j < 255; j++)
{
entry = (j << 24) | (j << 16) | (j << 8);
*pal++ = entry;
*pal++ = entry;
}
}
*/
}
} else
{
free(buffer);
buffer = NULL;
}
return buffer;
}
/* Setup translation buffers for the sprite plotting */
void WIMP_SetupPlotInfo(_THIS)
{
_kernel_swi_regs regs;
int *sprite = ((int *)this->hidden->bank[1])+4;
regs.r[0] = (unsigned int)this->hidden->bank[1];
regs.r[1] = (unsigned int)sprite;
regs.r[2] = -1; /* Current mode */
regs.r[3] = -1; /* Current palette */
regs.r[4] = 0; /* Get size of buffer */
regs.r[5] = 1|2|16; /* R1 - pointer to sprite and can use full palette words */
regs.r[6] = 0;
regs.r[7] = 0;
if (this->hidden->pixtrans) free(this->hidden->pixtrans);
this->hidden->pixtrans = 0;
/* Get the size required for the buffer */
_kernel_swi(ColourTrans_GenerateTable, &regs, &regs);
if (regs.r[4])
{
this->hidden->pixtrans = malloc(regs.r[4]);
regs.r[4] = (unsigned int)this->hidden->pixtrans;
/* Actually read the buffer */
_kernel_swi(ColourTrans_GenerateTable, &regs, &regs);
}
}
/* Plot the sprite in the given context */
void WIMP_PlotSprite(_THIS, int x, int y)
{
_kernel_swi_regs regs;
_kernel_oserror *err;
regs.r[0] = 52 + 512;
regs.r[1] = (unsigned int)this->hidden->bank[1];
regs.r[2] = (unsigned int)this->hidden->bank[1]+16;
regs.r[3] = x;
regs.r[4] = y;
regs.r[5] = 0|32; /* Overwrite screen and pixtrans contains wide colour entries */
regs.r[6] = 0; /* No scale factors i.e. 1:1 */
regs.r[7] = (int)this->hidden->pixtrans;
if ((err = _kernel_swi(OS_SpriteOp, &regs, &regs)) != 0)
{
int *p = (int *)this->hidden->pixtrans;
printf("OS_SpriteOp failed \n%s\n",err->errmess);
printf("pixtrans %d\n", (int)this->hidden->pixtrans);
printf("%x %x %x\n", p[0], p[1], p[2]);
}
}
/* Wimp mode has changes so update colour mapping and pixel sizes
of windows and the sprites they plot */
void WIMP_ModeChanged(_THIS)
{
int oldXeig = this->hidden->xeig;
int oldYeig = this->hidden->yeig;
WIMP_ReadModeInfo(this);
if (oldXeig == this->hidden->xeig && oldYeig == this->hidden->yeig)
{
/* Only need to update the palette */
WIMP_PaletteChanged(this);
} else
{
_kernel_swi_regs regs;
int window_state[9];
int extent[4];
int currWidth, currHeight;
int newWidth, newHeight;
/* Need to resize windows and update the palette */
WIMP_SetupPlotInfo(this);
window_state[0] = this->hidden->window_handle;
regs.r[1] = (unsigned int)window_state;
_kernel_swi(Wimp_GetWindowState, &regs, &regs);
currWidth = window_state[3] - window_state[1];
currHeight = window_state[4] - window_state[2];
newWidth = (currWidth >> oldXeig) << this->hidden->xeig;
newHeight = (currHeight >> oldYeig) << this->hidden->yeig;
/* Need to avoid extent getting too small for visible part
of window */
extent[0] = 0;
if (currHeight <= newHeight)
{
extent[1] = -newHeight;
} else
{
extent[1] = -currHeight;
}
if (currWidth <= newWidth)
{
extent[2] = newWidth;
} else
{
extent[2] = currWidth;
}
extent[3] = 0;
regs.r[0] = this->hidden->window_handle;
regs.r[1] = (int)extent;
_kernel_swi(Wimp_SetExtent, &regs, &regs);
/*TODO: May need to set flag to resize window on next open */
}
}
/* Palette has changed so update palettes used for windows sprites */
void WIMP_PaletteChanged(_THIS)
{
WIMP_SetupPlotInfo(this);
}
This diff is collapsed.
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
/*
This file added by Alan Buckley (alan_baa@hotmail.com) to support RISCOS
26 March 2003
*/
/* Task initialisation/Clean up */
extern int RISCOS_InitTask();
extern void RISCOS_ExitTask();
extern int RISCOS_GetWimpVersion();
extern int RISCOS_GetTaskHandle();
/* Wimp mode saveing/restoring */
extern void RISCOS_StoreWimpMode();
extern void RISCOS_RestoreWimpMode();
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
/*
File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability
23 March 2003
Implements RISCOS display device management.
Routines for full screen and wimp modes are split
into other source files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#include "SDL_syswm.h"
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_mouse.h"
#include "SDL_sysvideo.h"
#include "SDL_pixels_c.h"
#include "SDL_events_c.h"
#include "SDL_riscostask.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscosevents_c.h"
#include "SDL_riscosmouse_c.h"
#include "kernel.h"
#include "swis.h"
#define RISCOSVID_DRIVER_NAME "riscos"
/* Initialization/Query functions */
static int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
static void RISCOS_VideoQuit(_THIS);
static SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
/* Mouse checking */
void RISCOS_CheckMouseMode(_THIS);
extern SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode);
/* Fullscreen mode functions */
extern SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
extern void FULLSCREEN_BuildModeList(_THIS);
extern void FULLSCREEN_SetDeviceMode(_THIS);
extern int FULLSCREEN_ToggleFromWimp(_THIS);
/* Wimp mode functions */
extern SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
extern void WIMP_DeleteWindow(_THIS);
extern int WIMP_ToggleFromFullScreen(_THIS);
/* Hardware surface functions - common to WIMP and FULLSCREEN */
static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface);
static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface);
static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface);
/* RISCOS driver bootstrap functions */
static int RISCOS_Available(void)
{
return(1);
}
static void RISCOS_DeleteDevice(SDL_VideoDevice *device)
{
free(device->hidden);
free(device);
}
static SDL_VideoDevice *RISCOS_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
if ( device ) {
memset(device, 0, (sizeof *device));
device->hidden = (struct SDL_PrivateVideoData *)
malloc((sizeof *device->hidden));
}
if ( (device == NULL) || (device->hidden == NULL) ) {
SDL_OutOfMemory();
if ( device ) {
free(device);
}
return(0);
}
memset(device->hidden, 0, (sizeof *device->hidden));
/* Set the function pointers */
device->VideoInit = RISCOS_VideoInit;
device->VideoQuit = RISCOS_VideoQuit;
device->ListModes = RISCOS_ListModes;
device->SetVideoMode = RISCOS_SetVideoMode;
device->CreateYUVOverlay = NULL;
device->AllocHWSurface = RISCOS_AllocHWSurface;
device->CheckHWBlit = NULL;
device->FillHWRect = NULL;
device->SetHWColorKey = NULL;
device->SetHWAlpha = NULL;
device->LockHWSurface = RISCOS_LockHWSurface;
device->UnlockHWSurface = RISCOS_UnlockHWSurface;
device->FreeHWSurface = RISCOS_FreeHWSurface;
device->FreeWMCursor = RISCOS_FreeWMCursor;
device->CreateWMCursor = RISCOS_CreateWMCursor;
device->CheckMouseMode = RISCOS_CheckMouseMode;
device->GrabInput = RISCOS_GrabInput;
device->InitOSKeymap = RISCOS_InitOSKeymap;
device->GetWMInfo = RISCOS_GetWmInfo;
device->free = RISCOS_DeleteDevice;
/* Can't get Toggle screen to work if program starts up in Full screen mode so
disable it here and re-enable it when a wimp screen is chosen */
device->ToggleFullScreen = NULL; /*RISCOS_ToggleFullScreen;*/
/* Set other entries for fullscreen mode */
FULLSCREEN_SetDeviceMode(device);
/* Turn off unixlib file name translation - we hope people have initialised
the video system before they try to read any files */
/* __riscosify_control = __RISCOSIFY_NO_PROCESS;
*//* We may be able to eventually replace our processing of filenames with the correct flags above*/
return device;
}
VideoBootStrap RISCOS_bootstrap = {
RISCOSVID_DRIVER_NAME, "RISCOS video driver",
RISCOS_Available, RISCOS_CreateDevice
};
int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
_kernel_swi_regs regs;
if (RISCOS_InitTask() == 0)
{
SDL_SetError("Unable to start task");
return 0;
}
regs.r[0] = -1; /* Current mode */
regs.r[1] = 9; /* Log base 2 bpp */
_kernel_swi(OS_ReadVduVariables, &regs, &regs);
vformat->BitsPerPixel = (1 << regs.r[0]);
/* Minimum bpp for SDL is 8 */
if (vformat->BitsPerPixel < 8) vformat->BitsPerPixel = 8;
switch (vformat->BitsPerPixel)
{
case 15:
case 16:
vformat->Bmask = 0x00007c00;
vformat->Gmask = 0x000003e0;
vformat->Rmask = 0x0000001f;
vformat->BitsPerPixel = 15; /* SDL wants actual number of bits used */
vformat->BytesPerPixel = 2;
break;
case 24:
case 32:
vformat->Bmask = 0x00ff0000;
vformat->Gmask = 0x0000ff00;
vformat->Rmask = 0x000000ff;
vformat->BytesPerPixel = 4;
break;
default:
vformat->Bmask = 0;
vformat->Gmask = 0;
vformat->Rmask = 0;
vformat->BytesPerPixel = 1;
break;
}
/* Fill in some window manager capabilities */
this->info.wm_available = 1;
/* We're done! */
return(0);
}
/* Note: If we are terminated, this could be called in the middle of
another SDL video routine -- notably UpdateRects.
*/
void RISCOS_VideoQuit(_THIS)
{
RISCOS_ExitTask();
if (this->hidden->alloc_bank) free(this->hidden->alloc_bank);
this->hidden->alloc_bank = 0;
}
SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
if (flags & SDL_FULLSCREEN)
{
/* Build mode list when first required. */
if (SDL_nummodes[0] == 0) FULLSCREEN_BuildModeList(this);
return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
} else
return (SDL_Rect **)-1;
}
/* Set up video mode */
SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags)
{
if (flags & SDL_FULLSCREEN)
{
RISCOS_StoreWimpMode();
/* Dump wimp window on switch to full screen */
if (this->hidden->window_handle) WIMP_DeleteWindow(this);
return FULLSCREEN_SetVideoMode(this, current, width, height, bpp, flags);
} else
{
RISCOS_RestoreWimpMode();
return WIMP_SetVideoMode(this, current, width, height, bpp, flags);
}
}
/* We don't actually allow hardware surfaces other than the main one */
static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface)
{
return(-1);
}
static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface)
{
return;
}
/* We need to wait for vertical retrace on page flipped displays */
static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface)
{
return(0);
}
static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
return;
}
int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info)
{
SDL_VERSION(&(info->version));
info->wimpVersion = RISCOS_GetWimpVersion();
info->taskHandle = RISCOS_GetTaskHandle();
info->window = this->hidden->window_handle;
return 1;
}
/* Toggle full screen mode.
Returns 1 if successful otherwise 0
*/
int RISCOS_ToggleFullScreen(_THIS, int fullscreen)
{
if (fullscreen)
{
return FULLSCREEN_ToggleFromWimp(this);
} else
{
return WIMP_ToggleFromFullScreen(this);
}
return 0;
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif
#ifndef _SDL_riscosvideo_h
#define _SDL_riscosvideo_h
#include "SDL_mouse.h"
#include "SDL_sysvideo.h"
#include "SDL_mutex.h"
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *this
/* Private display data */
struct SDL_PrivateVideoData {
unsigned char *bank[2];
int current_bank;
unsigned char *alloc_bank;
int height;
int xeig;
int yeig;
int screen_bpp;
int screen_width;
int screen_height;
char *pixtrans;
/* Wimp variables */
unsigned int window_handle;
char title[256];
#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
int SDL_nummodes[NUM_MODELISTS];
SDL_Rect **SDL_modelist[NUM_MODELISTS];
};
/* Old variable names */
#define SDL_nummodes (this->hidden->SDL_nummodes)
#define SDL_modelist (this->hidden->SDL_modelist)
#endif /* _SDL_risosvideo_h */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
*/
/*
File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability
27 March 2003
Implements Pumping of events and WIMP polling
*/
#include "SDL.h"
#include "SDL_syswm.h"
#include "SDL_sysevents.h"
#include "SDL_events_c.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscosevents_c.h"
#include "SDL_timer_c.h"
#include "memory.h"
#include "stdlib.h"
#include "ctype.h"
#include "kernel.h"
#include "swis.h"
#include "unixlib/os.h"
/* Local functions */
void WIMP_Poll(_THIS, int waitTime);
void WIMP_SetFocus(int win);
/* SDL_riscossprite functions */
void WIMP_PlotSprite(_THIS, int x, int y);
void WIMP_ModeChanged(_THIS);
void WIMP_PaletteChanged(_THIS);
extern void WIMP_PollMouse(_THIS);
extern void RISCOS_PollKeyboard();
extern void DRenderer_FillBuffers();
/* Timer running function */
extern void RISCOS_CheckTimer();
/* Mouse cursor handling */
extern void WIMP_ReshowCursor(_THIS);
int hasFocus = 0;
int mouseInWindow = 0;
/* Flag to ensure window is correct size after a mode change */
static int resizeOnOpen = 0;
void WIMP_PumpEvents(_THIS)
{
WIMP_Poll(this, 0);
if (hasFocus) RISCOS_PollKeyboard();
if (mouseInWindow) WIMP_PollMouse(this);
DRenderer_FillBuffers();
if (SDL_timer_running) RISCOS_CheckTimer();
}
void WIMP_Poll(_THIS, int waitTime)
{
_kernel_swi_regs regs;
int message[64];
unsigned int code;
int pollMask = 0;
int doPoll = 1;
int sysEvent;
int sdlWindow = this->hidden->window_handle;
if (this->PumpEvents != WIMP_PumpEvents) return;
if (waitTime > 0)
{
_kernel_swi(OS_ReadMonotonicTime, &regs, &regs);
waitTime += regs.r[0];
}
while (doPoll)
{
if (waitTime <= 0)
{
regs.r[0] = pollMask; /* Poll Mask */
/* For no wait time mask out null event so we wait until something happens */
if (waitTime < 0) regs.r[0] |= 1;
regs.r[1] = (int)message;
_kernel_swi(Wimp_Poll, &regs, &regs);
} else
{
regs.r[0] = pollMask;
regs.r[1] = (int)message;
regs.r[2] = waitTime;
_kernel_swi(Wimp_PollIdle, &regs, &regs);
}
/* Flag to specify if we post a SDL_SysWMEvent */
sysEvent = 0;
code = (unsigned int)regs.r[0];
switch(code)
{
case 0: /* Null Event - drop out for standard processing*/
doPoll = 0;
break;
case 1: /* Redraw window */
_kernel_swi(Wimp_RedrawWindow, &regs,&regs);
if (message[0] == sdlWindow)
{
while (regs.r[0])
{
WIMP_PlotSprite(this, message[1], message[2]);
_kernel_swi(Wimp_GetRectangle, &regs, &regs);
}
} else
{
/* TODO: Currently we just eat them - we may need to pass them on */
while (regs.r[0])
{
_kernel_swi(Wimp_GetRectangle, &regs, &regs);
}
}
break;
case 2: /* Open window */
if ( resizeOnOpen && message[0] == sdlWindow)
{
/* Ensure window is correct size */
resizeOnOpen = 0;
message[3] = message[1] + (this->screen->w << this->hidden->xeig);
message[4] = message[2] + (this->screen->h << this->hidden->yeig);
}
_kernel_swi(Wimp_OpenWindow, &regs, &regs);
break;
case 3: /* Close window */
if (message[0] == sdlWindow)
{
/* Documentation makes it looks as if the following line is correct:
** if (SDL_PrivateQuit() == 1) _kernel_swi(Wimp_CloseWindow, &regs, &regs);
** However some programs don't process this message and so sit there invisibly
** in the background so I just post the quit message and hope the application
** does the correct thing.
*/
SDL_PrivateQuit();
} else
sysEvent = 1;
doPoll = 0;
break;
case 4: /* Pointer_Leaving_Window */
if (message[0] == sdlWindow)
{
mouseInWindow = 0;
//TODO: Lose buttons / dragging
/* Reset to default pointer */
regs.r[0] = 106;
regs.r[1] = 1;
regs.r[2] = 0;
_kernel_swi(OS_Byte, &regs, &regs);
SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
} else
sysEvent = 1;
break;
case 5: /* Pointer_Entering_Window */
if (message[0] == sdlWindow)
{
mouseInWindow = 1;
WIMP_ReshowCursor(this);
SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
} else sysEvent = 1;
break;
case 6: /* Mouse_Click */
if (hasFocus == 0)
{
/* First click gives focus if it's not a menu */
/* we only count non-menu clicks on a window that has the focus */
WIMP_SetFocus(message[3]);
} else
doPoll = 0; // So PollMouse gets a chance to pick it up
break;
case 7: /* User_Drag_Box - Used for mouse release */
//TODO: May need to implement this in the future
sysEvent = 1;
break;
case 8: /* Keypressed */
doPoll = 0; /* PollKeyboard should pick it up */
if (message[0] != sdlWindow) sysEvent = 1;
/*TODO: May want to always pass F12 etc to the wimp
{
regs.r[0] = message[6];
_kernel_swi(Wimp_ProcessKey, &regs, &regs);
}
*/
break;
case 11: /* Lose Caret */
hasFocus = 0;
if (message[0] == sdlWindow) SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
else sysEvent = 1;
break;
case 12: /* Gain Caret */
hasFocus = 1;
if (message[0] == sdlWindow) SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
else sysEvent = 1;
break;
case 17:
case 18:
sysEvent = 1; /* All messages are passed on */
switch(message[4])
{
case 0: /* Quit Event */
/* No choice - have to quit */
SDL_Quit();
exit(0);
break;
case 8: /* Pre Quit */
SDL_PrivateQuit();
break;
case 0x400c1: /* Mode change */
WIMP_ModeChanged(this);
resizeOnOpen = 1;
break;
case 9: /* Palette changed */
WIMP_PaletteChanged(this);
break;
}
break;
default:
/* Pass unknown events on */
sysEvent = 1;
break;
}
if (sysEvent)
{
SDL_SysWMmsg wmmsg;
SDL_VERSION(&wmmsg.version);
wmmsg.eventCode = code;
memcpy(wmmsg.pollBlock, message, 64 * sizeof(int));
/* Fall out of polling loop if message is successfully posted */
if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0;
}
}
}
/* Set focus to specified window */
void WIMP_SetFocus(int win)
{
_kernel_swi_regs regs;
regs.r[0] = win;
regs.r[1] = -1; /* Icon handle */
regs.r[2] = 0; /* X-offset we just put it at position 0 */
regs.r[3] = 0; /* Y-offset as above */
regs.r[4] = 1 << 25; /* Caret is invisible */
regs.r[5] = 0; /* index into string */
_kernel_swi(Wimp_SetCaretPosition, &regs, &regs);
}
/** Run background task while in a sleep command */
void RISCOS_BackgroundTasks(void)
{
if (current_video && current_video->hidden->window_handle)
{
WIMP_Poll(current_video, 0);
}
/* Keep sound buffers running */
DRenderer_FillBuffers();
if (SDL_timer_running) RISCOS_CheckTimer();
}
This diff is collapsed.
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