mirror of
https://github.com/joel16/SDL2.git
synced 2025-01-31 16:54:34 +00:00
Added initial support for RISC OS (thanks Peter Naulls!)
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40631
This commit is contained in:
parent
35f9bbcbd6
commit
e8ce0bc197
2
README
2
README
@ -19,7 +19,7 @@ Objective C, Perl, PHP, Pike, Python, and Ruby.
|
||||
The current version supports Linux, Windows, BeOS, MacOS, MacOS X,
|
||||
FreeBSD, OpenBSD, BSD/OS, Solaris, and IRIX. The code contains support
|
||||
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
|
||||
found in the file "COPYING". This license allows you to use SDL
|
||||
|
@ -130,6 +130,23 @@ typedef struct {
|
||||
HGLRC hglrc; /* The OpenGL context, if any */
|
||||
} 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
|
||||
|
||||
/* The generic custom event structure */
|
||||
|
@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libaudio.la
|
||||
# Define which subdirectories need to be built
|
||||
SUBDIRS = @AUDIO_SUBDIRS@
|
||||
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@
|
||||
|
||||
|
@ -91,6 +91,9 @@ static AudioBootStrap *bootstrap[] = {
|
||||
#endif
|
||||
#ifdef ENABLE_DC
|
||||
&DCAUD_bootstrap,
|
||||
#endif
|
||||
#ifdef DRENDERER_SUPPORT
|
||||
&DRENDERER_bootstrap,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
@ -381,7 +384,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#ifdef macintosh
|
||||
#if defined(macintosh) || defined(__riscos__)
|
||||
/* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
|
||||
#else
|
||||
#if defined(__MINT__) && !defined(ENABLE_THREADS)
|
||||
|
@ -156,6 +156,9 @@ extern AudioBootStrap DISKAUD_bootstrap;
|
||||
#ifdef ENABLE_DC
|
||||
extern AudioBootStrap DCAUD_bootstrap;
|
||||
#endif
|
||||
#ifdef DRENDERER_SUPPORT
|
||||
extern AudioBootStrap DRENDERER_bootstrap;
|
||||
#endif
|
||||
|
||||
/* This is the current audio device */
|
||||
extern SDL_AudioDevice *current_audio;
|
||||
|
9
src/audio/riscos/Makefile.am
Normal file
9
src/audio/riscos/Makefile.am
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
## 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
|
293
src/audio/riscos/SDL_drenderer.c
Normal file
293
src/audio/riscos/SDL_drenderer.c
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
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, ®s, ®s) == 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, ®s, ®s);
|
||||
|
||||
#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, ®s, ®s);
|
||||
|
||||
} 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, ®s, ®s);
|
||||
}
|
||||
/* Check if we have enough buffers yet */
|
||||
_kernel_swi(DigitalRenderer_StreamStatistics, ®s, ®s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* 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, ®s, ®s) != 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, ®s, ®s) != 0)
|
||||
{
|
||||
SDL_SetError("Unable to activate digital renderer in 16 bit mode\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_kernel_swi(DigitalRenderer_GetFrequency, ®s, ®s) == 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, ®s, ®s);
|
||||
|
||||
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, ®s, ®s);
|
||||
|
||||
if (buffer != NULL) free(buffer);
|
||||
}
|
||||
|
36
src/audio/riscos/SDL_drenderer.h
Normal file
36
src/audio/riscos/SDL_drenderer.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
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
|
||||
|
||||
# Define which subdirectories need to be built
|
||||
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@
|
||||
|
||||
|
8
src/joystick/riscos/Makefile.am
Normal file
8
src/joystick/riscos/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
## 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
|
180
src/joystick/riscos/SDL_sysjoystick.c
Normal file
180
src/joystick/riscos/SDL_sysjoystick.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
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, ®s, ®s) == 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, ®s, ®s) == 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 \
|
||||
$(srcdir)/linux \
|
||||
$(srcdir)/macos \
|
||||
$(srcdir)/mint \
|
||||
$(srcdir)/riscos \
|
||||
$(srcdir)/win32
|
||||
|
||||
# Include the architecture-independent sources
|
||||
|
146
src/timer/riscos/SDL_systimer.c
Normal file
146
src/timer/riscos/SDL_systimer.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
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
|
||||
SUBDIRS = @VIDEO_SUBDIRS@
|
||||
DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \
|
||||
wincommon windib windx5 \
|
||||
maccommon macdsp macrom quartz \
|
||||
maccommon macdsp macrom riscos quartz \
|
||||
bwindow ps2gs photon cybergfx epoc picogui \
|
||||
ataricommon xbios gem dc qtopia XFree86
|
||||
|
||||
|
@ -409,6 +409,9 @@ extern VideoBootStrap PG_bootstrap;
|
||||
#ifdef ENABLE_DC
|
||||
extern VideoBootStrap DC_bootstrap;
|
||||
#endif
|
||||
#ifdef ENABLE_RISCOS
|
||||
extern VideoBootStrap RISCOS_bootstrap;
|
||||
#endif
|
||||
/* This is the current video device */
|
||||
extern SDL_VideoDevice *current_video;
|
||||
|
||||
|
@ -117,6 +117,9 @@ static VideoBootStrap *bootstrap[] = {
|
||||
#ifdef ENABLE_DC
|
||||
&DC_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_RISCOS
|
||||
&RISCOS_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_DUMMYVIDEO
|
||||
&DUMMY_bootstrap,
|
||||
#endif
|
||||
|
20
src/video/riscos/Makefile.am
Normal file
20
src/video/riscos/Makefile.am
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
## 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
|
594
src/video/riscos/SDL_riscosFullScreenVideo.c
Normal file
594
src/video/riscos/SDL_riscosFullScreenVideo.c
Normal file
@ -0,0 +1,594 @@
|
||||
/*
|
||||
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 RISCOS full screen display.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL.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"
|
||||
#include "unixlib/os.h"
|
||||
#include "unixlib/local.h"
|
||||
|
||||
/* Private structures */
|
||||
typedef struct tagScreenModeBlock
|
||||
{
|
||||
int flags; // mode selector flags, bit 0 = 1, bit 1-7 format specifier, 8-31 reserved
|
||||
int x_pixels;
|
||||
int y_pixels;
|
||||
int pixel_depth; // 2^pixel_depth = bpp,i.e. 0 = 1, 1 = 2, 4 = 16, 5 = 32
|
||||
int frame_rate; // -1 use first match
|
||||
int mode_vars[5]; // array of index, value pairs terminated by -1
|
||||
} SCREENMODEBLOCK;
|
||||
|
||||
|
||||
/* Helper functions */
|
||||
void FULLSCREEN_SetDeviceMode(_THIS);
|
||||
int FULLSCREEN_SetMode(int width, int height, int bpp);
|
||||
void FULLSCREEN_SetupBanks(_THIS);
|
||||
|
||||
/* SDL video device functions for fullscreen mode */
|
||||
static int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
|
||||
static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface);
|
||||
static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
|
||||
void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon);
|
||||
extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
|
||||
|
||||
/* Local helper functions */
|
||||
static int cmpmodes(const void *va, const void *vb);
|
||||
static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h);
|
||||
void FULLSCREEN_SetWriteBank(int bank);
|
||||
void FULLSCREEN_SetDisplayBank(int bank);
|
||||
static void FULLSCREEN_DisableEscape();
|
||||
static void FULLSCREEN_EnableEscape();
|
||||
void FULLSCREEN_BuildModeList(_THIS);
|
||||
|
||||
/* Following variable is set up in riskosTask.c */
|
||||
extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */
|
||||
|
||||
|
||||
|
||||
SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current,
|
||||
int width, int height, int bpp, Uint32 flags)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
Uint32 Rmask = 0;
|
||||
Uint32 Gmask = 0;
|
||||
Uint32 Bmask = 0;
|
||||
int create_back_buffer = riscos_backbuffer;
|
||||
|
||||
switch(bpp)
|
||||
{
|
||||
case 8:
|
||||
flags |= SDL_HWPALETTE;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
Bmask = 0x00007c00;
|
||||
Gmask = 0x000003e0;
|
||||
Rmask = 0x0000001f;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
Bmask = 0x00ff0000;
|
||||
Gmask = 0x0000ff00;
|
||||
Rmask = 0x000000ff;
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_SetError("Pixel depth not supported");
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FULLSCREEN_SetMode(width, height, bpp) == 0)
|
||||
{
|
||||
SDL_SetError("Couldn't set requested mode");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* printf("Setting mode %dx%d\n", width, height); */
|
||||
|
||||
/* Allocate the new pixel format for the screen */
|
||||
if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
|
||||
RISCOS_RestoreWimpMode();
|
||||
SDL_SetError("Couldn't allocate new pixel format for requested mode");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Set up the new mode framebuffer */
|
||||
current->w = width;
|
||||
this->hidden->height = current->h = height;
|
||||
|
||||
regs.r[0] = -1; /* -1 for current screen mode */
|
||||
|
||||
/* Get screen width in bytes */
|
||||
regs.r[1] = 6; // Screen Width in bytes
|
||||
_kernel_swi(OS_ReadModeVariable, ®s, ®s);
|
||||
|
||||
current->pitch = regs.r[2];
|
||||
|
||||
if (flags & SDL_DOUBLEBUF)
|
||||
{
|
||||
regs.r[0] = 2; /* Screen area */
|
||||
_kernel_swi(OS_ReadDynamicArea, ®s, ®s);
|
||||
|
||||
/* Reg 1 has amount of memory currently used for display */
|
||||
regs.r[0] = 2; /* Screen area */
|
||||
regs.r[1] = (current->pitch * height * 2) - regs.r[1];
|
||||
if (_kernel_swi(OS_ChangeDynamicArea, ®s, ®s) != NULL)
|
||||
{
|
||||
/* Can't allocate enough screen memory for double buffer */
|
||||
flags &= ~SDL_DOUBLEBUF;
|
||||
}
|
||||
}
|
||||
|
||||
current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | SDL_PREALLOC;
|
||||
|
||||
|
||||
/* Need to set display banks here for double buffering */
|
||||
if (flags & SDL_DOUBLEBUF)
|
||||
{
|
||||
FULLSCREEN_SetWriteBank(0);
|
||||
FULLSCREEN_SetDisplayBank(1);
|
||||
|
||||
create_back_buffer = 0; /* Don't need a back buffer for a double buffered display */
|
||||
}
|
||||
|
||||
FULLSCREEN_SetupBanks(this);
|
||||
|
||||
if (create_back_buffer)
|
||||
{
|
||||
/* If not double buffered we may need to create a memory
|
||||
** back buffer to simulate processing on other OS's.
|
||||
** This is turned on by setting the enviromental variable
|
||||
** SDL$<name>$BackBuffer to 1
|
||||
*/
|
||||
this->hidden->bank[0] = malloc(height * current->pitch);
|
||||
if (this->hidden->bank[0] == 0)
|
||||
{
|
||||
RISCOS_RestoreWimpMode();
|
||||
SDL_SetError("Couldnt allocate memory for back buffer");
|
||||
return (NULL);
|
||||
}
|
||||
/* Surface updated in programs is now a software surface */
|
||||
current->flags &= ~SDL_HWSURFACE;
|
||||
}
|
||||
|
||||
/* Store address of allocated screen bank to be freed later */
|
||||
if (this->hidden->alloc_bank) free(this->hidden->alloc_bank);
|
||||
if (create_back_buffer)
|
||||
{
|
||||
this->hidden->alloc_bank = this->hidden->bank[0];
|
||||
} else
|
||||
this->hidden->alloc_bank = 0;
|
||||
|
||||
// Clear both banks to black
|
||||
memset(this->hidden->bank[0], 0, height * current->pitch);
|
||||
memset(this->hidden->bank[1], 0, height * current->pitch);
|
||||
|
||||
this->hidden->current_bank = 0;
|
||||
current->pixels = this->hidden->bank[0];
|
||||
|
||||
/* Reset device functions for the wimp */
|
||||
FULLSCREEN_SetDeviceMode(this);
|
||||
|
||||
/* FULLSCREEN_DisableEscape(); */
|
||||
|
||||
/* We're done */
|
||||
return(current);
|
||||
}
|
||||
|
||||
/* Reset any device functions that have been changed because we have run in WIMP mode */
|
||||
void FULLSCREEN_SetDeviceMode(_THIS)
|
||||
{
|
||||
if (this->SetColors == FULLSCREEN_SetColors) return; /* Already set up */
|
||||
|
||||
this->SetColors = FULLSCREEN_SetColors;
|
||||
this->UpdateRects = FULLSCREEN_UpdateRects;
|
||||
|
||||
this->FlipHWSurface = FULLSCREEN_FlipHWSurface;
|
||||
|
||||
this->SetCaption = FULLSCREEN_SetWMCaption;
|
||||
this->SetIcon = NULL;
|
||||
this->IconifyWindow = NULL;
|
||||
|
||||
this->ShowWMCursor = RISCOS_ShowWMCursor;
|
||||
this->WarpWMCursor = FULLSCREEN_WarpWMCursor;
|
||||
|
||||
this->PumpEvents = FULLSCREEN_PumpEvents;
|
||||
}
|
||||
|
||||
/* Query for the list of available video modes */
|
||||
void FULLSCREEN_BuildModeList(_THIS)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
char *enumInfo = NULL;
|
||||
char *enum_ptr;
|
||||
int *blockInfo;
|
||||
int j;
|
||||
int num_modes;
|
||||
|
||||
/* Find out how much space we need */
|
||||
regs.r[0] = 2; /* Reason code */
|
||||
regs.r[2] = 0; /* Number of modes to skip */
|
||||
regs.r[6] = 0; /* pointer to block or 0 for count */
|
||||
regs.r[7] = 0; /* Size of block in bytes */
|
||||
_kernel_swi(OS_ScreenMode, ®s, ®s);
|
||||
|
||||
num_modes = -regs.r[2];
|
||||
|
||||
/* Video memory should be in r[5] */
|
||||
this->info.video_mem = regs.r[5]/1024;
|
||||
|
||||
enumInfo = (unsigned char *)malloc(-regs.r[7]);
|
||||
if (enumInfo == NULL)
|
||||
{
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
}
|
||||
/* Read mode information into block */
|
||||
regs.r[2] = 0;
|
||||
regs.r[6] = (int)enumInfo;
|
||||
regs.r[7] = -regs.r[7];
|
||||
_kernel_swi(OS_ScreenMode, ®s, ®s);
|
||||
|
||||
enum_ptr = enumInfo;
|
||||
|
||||
for (j =0; j < num_modes;j++)
|
||||
{
|
||||
blockInfo = (int *)enum_ptr;
|
||||
if ((blockInfo[1] & 255) == 1) /* We understand this format */
|
||||
{
|
||||
switch(blockInfo[4])
|
||||
{
|
||||
case 3: /* 8 bits per pixel */
|
||||
FULLSCREEN_AddMode(this, 8, blockInfo[2], blockInfo[3]);
|
||||
break;
|
||||
case 4: /* 15 bits per pixel */
|
||||
FULLSCREEN_AddMode(this, 15, blockInfo[2], blockInfo[3]);
|
||||
break;
|
||||
case 5: /* 32 bits per pixel */
|
||||
FULLSCREEN_AddMode(this, 32, blockInfo[2], blockInfo[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum_ptr += blockInfo[0];
|
||||
}
|
||||
|
||||
free(enumInfo);
|
||||
|
||||
/* Sort the mode lists */
|
||||
for ( j=0; j<NUM_MODELISTS; ++j ) {
|
||||
if ( SDL_nummodes[j] > 0 ) {
|
||||
qsort(SDL_modelist[j], SDL_nummodes[j], sizeof *SDL_modelist[j], cmpmodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[0] = 19;
|
||||
/* Wait for Vsync */
|
||||
_kernel_swi(OS_Byte, ®s, ®s);
|
||||
|
||||
FULLSCREEN_SetDisplayBank(this->hidden->current_bank);
|
||||
this->hidden->current_bank ^= 1;
|
||||
FULLSCREEN_SetWriteBank(this->hidden->current_bank);
|
||||
surface->pixels = this->hidden->bank[this->hidden->current_bank];
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
|
||||
{
|
||||
if (riscos_backbuffer && (this->screen->flags & SDL_DOUBLEBUF) == 0)
|
||||
{
|
||||
/* If not double buffered copy rectangles to main screen now */
|
||||
int j;
|
||||
char *to, *from;
|
||||
int pitch = this->screen->pitch;
|
||||
int row;
|
||||
int xmult = this->screen->format->BytesPerPixel;
|
||||
for (j = 0; j < numrects; j++)
|
||||
{
|
||||
from = this->hidden->bank[0] + rects->x * xmult + rects->y * pitch;
|
||||
to = this->hidden->bank[1] + rects->x * xmult + rects->y * pitch;
|
||||
for (row = 0; row < rects->h; row++)
|
||||
{
|
||||
memcpy(to, from, rects->w * xmult);
|
||||
from += pitch;
|
||||
to += pitch;
|
||||
}
|
||||
rects++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
int palette[256];
|
||||
|
||||
regs.r[0] = -1;
|
||||
regs.r[1] = -1;
|
||||
regs.r[2] = (int)palette;
|
||||
regs.r[3] = 1024;
|
||||
regs.r[4] = 0;
|
||||
_kernel_swi(ColourTrans_ReadPalette, ®s, ®s);
|
||||
|
||||
while(ncolors--)
|
||||
{
|
||||
palette[firstcolor] = ((colors->b) << 24) | ((colors->g) << 16) | ((colors->r) << 8);
|
||||
firstcolor++;
|
||||
colors++;
|
||||
}
|
||||
|
||||
regs.r[0] = -1;
|
||||
regs.r[1] = -1;
|
||||
regs.r[2] = (int)palette;
|
||||
regs.r[3] = 0;
|
||||
regs.r[4] = 0;
|
||||
_kernel_swi(ColourTrans_WritePalette, ®s, ®s);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int cmpmodes(const void *va, const void *vb)
|
||||
{
|
||||
SDL_Rect *a = *(SDL_Rect **)va;
|
||||
SDL_Rect *b = *(SDL_Rect **)vb;
|
||||
if(a->w > b->w)
|
||||
return -1;
|
||||
return b->h - a->h;
|
||||
}
|
||||
|
||||
static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h)
|
||||
{
|
||||
SDL_Rect *mode;
|
||||
int i, index;
|
||||
int next_mode;
|
||||
|
||||
/* Check to see if we already have this mode */
|
||||
if ( bpp < 8 ) { /* Not supported */
|
||||
return(0);
|
||||
}
|
||||
index = ((bpp+7)/8)-1;
|
||||
for ( i=0; i<SDL_nummodes[index]; ++i ) {
|
||||
mode = SDL_modelist[index][i];
|
||||
if ( (mode->w == w) && (mode->h == h) ) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the new video mode rectangle */
|
||||
mode = (SDL_Rect *)malloc(sizeof *mode);
|
||||
if ( mode == NULL ) {
|
||||
SDL_OutOfMemory();
|
||||
return(-1);
|
||||
}
|
||||
mode->x = 0;
|
||||
mode->y = 0;
|
||||
mode->w = w;
|
||||
mode->h = h;
|
||||
|
||||
/* Allocate the new list of modes, and fill in the new mode */
|
||||
next_mode = SDL_nummodes[index];
|
||||
SDL_modelist[index] = (SDL_Rect **)
|
||||
realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
|
||||
if ( SDL_modelist[index] == NULL ) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_nummodes[index] = 0;
|
||||
free(mode);
|
||||
return(-1);
|
||||
}
|
||||
SDL_modelist[index][next_mode] = mode;
|
||||
SDL_modelist[index][next_mode+1] = NULL;
|
||||
SDL_nummodes[index]++;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void FULLSCREEN_SetWriteBank(int bank)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[0] = 112;
|
||||
regs.r[1] = bank+1;
|
||||
_kernel_swi(OS_Byte, ®s, ®s);
|
||||
}
|
||||
|
||||
void FULLSCREEN_SetDisplayBank(int bank)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[0] = 113;
|
||||
regs.r[1] = bank+1;
|
||||
_kernel_swi(OS_Byte, ®s, ®s);
|
||||
}
|
||||
|
||||
|
||||
/** Disable special escape key processing */
|
||||
static void FULLSCREEN_DisableEscape()
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[0] = 229;
|
||||
regs.r[1] = 1;
|
||||
regs.r[2] = 0;
|
||||
_kernel_swi(OS_Byte, ®s, ®s);
|
||||
|
||||
}
|
||||
|
||||
/** Enable special escape key processing */
|
||||
static void FULLSCREEN_EnableEscape()
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[0] = 229;
|
||||
regs.r[1] = 0;
|
||||
regs.r[2] = 0;
|
||||
_kernel_swi(OS_Byte, ®s, ®s);
|
||||
|
||||
}
|
||||
|
||||
/** Store caption in case this is called before we create a window */
|
||||
void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon)
|
||||
{
|
||||
strncpy(this->hidden->title, title, 255);
|
||||
this->hidden->title[255] = 0;
|
||||
}
|
||||
|
||||
/* Set screen mode
|
||||
*
|
||||
* Returns 1 if mode is set ok, otherwise 0
|
||||
*/
|
||||
|
||||
int FULLSCREEN_SetMode(int width, int height, int bpp)
|
||||
{
|
||||
SCREENMODEBLOCK smb;
|
||||
_kernel_swi_regs regs;
|
||||
|
||||
smb.flags = 1;
|
||||
smb.x_pixels = width;
|
||||
smb.y_pixels = height;
|
||||
smb.mode_vars[0] = -1;
|
||||
|
||||
switch(bpp)
|
||||
{
|
||||
case 8:
|
||||
smb.pixel_depth = 3;
|
||||
/* Note: Need to set ModeFlags to 128 and NColour variables to 255 get full 8 bit palette */
|
||||
smb.mode_vars[0] = 0; smb.mode_vars[1] = 128; /* Mode flags */
|
||||
smb.mode_vars[2] = 3; smb.mode_vars[3] = 255; /* NColour (number of colours -1) */
|
||||
smb.mode_vars[4] = -1; /* End of list */
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
smb.pixel_depth = 4;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
smb.pixel_depth = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_SetError("Pixel depth not supported");
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
smb.frame_rate = -1;
|
||||
|
||||
regs.r[0] = 0;
|
||||
regs.r[1] = (int)&smb;
|
||||
|
||||
if (_kernel_swi(OS_ScreenMode, ®s, ®s) != 0)
|
||||
{
|
||||
SDL_SetError("Couldn't set requested mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Turn cursor off*/
|
||||
_kernel_oswrch(23);_kernel_oswrch(1);_kernel_oswrch(0);
|
||||
_kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
|
||||
_kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
|
||||
_kernel_oswrch(0);_kernel_oswrch(0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get Start addresses for the screen banks */
|
||||
void FULLSCREEN_SetupBanks(_THIS)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
int block[5];
|
||||
block[0] = 148; /* Write screen start */
|
||||
block[1] = 149; /* Display screen start */
|
||||
block[2] = 4; /* X eig factor */
|
||||
block[3] = 5; /* Y eig factor */
|
||||
block[4] = -1; /* End of list of variables to request */
|
||||
|
||||
regs.r[0] = (int)block;
|
||||
regs.r[1] = (int)block;
|
||||
_kernel_swi(OS_ReadVduVariables, ®s, ®s);
|
||||
|
||||
this->hidden->bank[0] = (void *)block[0];
|
||||
this->hidden->bank[1] = (void *)block[1];
|
||||
this->hidden->xeig = block[2];
|
||||
this->hidden->yeig = block[3];
|
||||
}
|
||||
|
||||
/* Toggle to full screen mode from the WIMP */
|
||||
|
||||
int FULLSCREEN_ToggleFromWimp(_THIS)
|
||||
{
|
||||
int width = this->screen->w;
|
||||
int height = this->screen->h;
|
||||
int bpp = this->screen->format->BitsPerPixel;
|
||||
|
||||
RISCOS_StoreWimpMode();
|
||||
if (FULLSCREEN_SetMode(width, height, bpp))
|
||||
{
|
||||
char *buffer = this->hidden->alloc_bank; /* This is start of sprite data */
|
||||
/* Support back buffer mode only */
|
||||
riscos_backbuffer = 1;
|
||||
|
||||
FULLSCREEN_SetupBanks(this);
|
||||
|
||||
this->hidden->bank[0] = buffer + 60; /* Start of sprite data */
|
||||
if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
|
||||
|
||||
this->hidden->current_bank = 0;
|
||||
this->screen->pixels = this->hidden->bank[0];
|
||||
|
||||
/* Copy back buffer to screen memory */
|
||||
memcpy(this->hidden->bank[1], this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel);
|
||||
|
||||
FULLSCREEN_SetDeviceMode(this);
|
||||
return 1;
|
||||
} else
|
||||
RISCOS_RestoreWimpMode();
|
||||
|
||||
return 0;
|
||||
}
|
458
src/video/riscos/SDL_riscosevents.c
Normal file
458
src/video/riscos/SDL_riscosevents.c
Normal file
@ -0,0 +1,458 @@
|
||||
/*
|
||||
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 keyboard setup, event pump and keyboard and mouse polling
|
||||
*/
|
||||
|
||||
|
||||
#include "SDL.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 "SDL_cursor_c.h"
|
||||
|
||||
#include "memory.h"
|
||||
#include "stdlib.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#include "kernel.h"
|
||||
#include "swis.h"
|
||||
|
||||
/* The translation table from a RISCOS internal key numbers to a SDL keysym */
|
||||
static SDLKey RO_keymap[SDLK_LAST];
|
||||
|
||||
/* RISCOS Key codes */
|
||||
#define ROKEY_SHIFT 0
|
||||
#define ROKEY_CTRL 1
|
||||
#define ROKEY_ALT 2
|
||||
/* Left shift is first key we will check for */
|
||||
#define ROKEY_LEFT_SHIFT 3
|
||||
|
||||
/* Need to ignore mouse buttons as they are processed separately */
|
||||
#define ROKEY_LEFT_MOUSE 9
|
||||
#define ROKEY_CENTRE_MOUSE 10
|
||||
#define ROKEY_RIGHT_MOUSE 11
|
||||
|
||||
/* No key has been pressed return value*/
|
||||
#define ROKEY_NONE 255
|
||||
|
||||
/* Id of last key in keyboard */
|
||||
#define ROKEY_LAST_KEY 124
|
||||
|
||||
/* Size of array for all keys */
|
||||
#define ROKEYBD_ARRAYSIZE 125
|
||||
|
||||
static char RO_pressed[ROKEYBD_ARRAYSIZE];
|
||||
|
||||
static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed);
|
||||
|
||||
|
||||
void RISCOS_PollMouse(_THIS);
|
||||
void RISCOS_PollKeyboard();
|
||||
|
||||
void RISCOS_PollMouseHelper(_THIS, int fullscreen);
|
||||
|
||||
extern void DRenderer_FillBuffers();
|
||||
|
||||
/* Timer running function */
|
||||
extern void RISCOS_CheckTimer();
|
||||
|
||||
void FULLSCREEN_PumpEvents(_THIS)
|
||||
{
|
||||
/* Current implementation requires keyboard and mouse polling */
|
||||
RISCOS_PollKeyboard();
|
||||
RISCOS_PollMouse(this);
|
||||
DRenderer_FillBuffers();
|
||||
if (SDL_timer_running) RISCOS_CheckTimer();
|
||||
}
|
||||
|
||||
|
||||
void RISCOS_InitOSKeymap(_THIS)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Map the VK keysyms */
|
||||
for ( i=0; i<SDL_TABLESIZE(RO_keymap); ++i )
|
||||
RO_keymap[i] = SDLK_UNKNOWN;
|
||||
|
||||
RO_keymap[3] = SDLK_LSHIFT;
|
||||
RO_keymap[4] = SDLK_LCTRL;
|
||||
RO_keymap[5] = SDLK_LALT;
|
||||
RO_keymap[6] = SDLK_RSHIFT;
|
||||
RO_keymap[7] = SDLK_RCTRL;
|
||||
RO_keymap[8] = SDLK_RALT;
|
||||
RO_keymap[16] = SDLK_q;
|
||||
RO_keymap[17] = SDLK_3;
|
||||
RO_keymap[18] = SDLK_4;
|
||||
RO_keymap[19] = SDLK_5;
|
||||
RO_keymap[20] = SDLK_F4;
|
||||
RO_keymap[21] = SDLK_8;
|
||||
RO_keymap[22] = SDLK_F7;
|
||||
RO_keymap[23] = SDLK_MINUS,
|
||||
RO_keymap[25] = SDLK_LEFT;
|
||||
RO_keymap[26] = SDLK_KP6;
|
||||
RO_keymap[27] = SDLK_KP7;
|
||||
RO_keymap[28] = SDLK_F11;
|
||||
RO_keymap[29] = SDLK_F12;
|
||||
RO_keymap[30] = SDLK_F10;
|
||||
RO_keymap[31] = SDLK_SCROLLOCK;
|
||||
RO_keymap[32] = SDLK_PRINT;
|
||||
RO_keymap[33] = SDLK_w;
|
||||
RO_keymap[34] = SDLK_e;
|
||||
RO_keymap[35] = SDLK_t;
|
||||
RO_keymap[36] = SDLK_7;
|
||||
RO_keymap[37] = SDLK_i;
|
||||
RO_keymap[38] = SDLK_9;
|
||||
RO_keymap[39] = SDLK_0;
|
||||
RO_keymap[41] = SDLK_DOWN;
|
||||
RO_keymap[42] = SDLK_KP8;
|
||||
RO_keymap[43] = SDLK_KP9;
|
||||
RO_keymap[44] = SDLK_BREAK;
|
||||
RO_keymap[45] = SDLK_BACKQUOTE;
|
||||
/* RO_keymap[46] = SDLK_currency; TODO: Figure out if this has a value */
|
||||
RO_keymap[47] = SDLK_BACKSPACE;
|
||||
RO_keymap[48] = SDLK_1;
|
||||
RO_keymap[49] = SDLK_2;
|
||||
RO_keymap[50] = SDLK_d;
|
||||
RO_keymap[51] = SDLK_r;
|
||||
RO_keymap[52] = SDLK_6;
|
||||
RO_keymap[53] = SDLK_u;
|
||||
RO_keymap[54] = SDLK_o;
|
||||
RO_keymap[55] = SDLK_p;
|
||||
RO_keymap[56] = SDLK_LEFTPAREN;
|
||||
RO_keymap[57] = SDLK_UP;
|
||||
RO_keymap[58] = SDLK_KP_PLUS;
|
||||
RO_keymap[59] = SDLK_KP_MINUS;
|
||||
RO_keymap[60] = SDLK_KP_ENTER;
|
||||
RO_keymap[61] = SDLK_INSERT;
|
||||
RO_keymap[62] = SDLK_HOME;
|
||||
RO_keymap[63] = SDLK_PAGEUP;
|
||||
RO_keymap[64] = SDLK_CAPSLOCK;
|
||||
RO_keymap[65] = SDLK_a;
|
||||
RO_keymap[66] = SDLK_x;
|
||||
RO_keymap[67] = SDLK_f;
|
||||
RO_keymap[68] = SDLK_y;
|
||||
RO_keymap[69] = SDLK_j;
|
||||
RO_keymap[70] = SDLK_k;
|
||||
RO_keymap[72] = SDLK_SEMICOLON;
|
||||
RO_keymap[73] = SDLK_RETURN;
|
||||
RO_keymap[74] = SDLK_KP_DIVIDE;
|
||||
RO_keymap[76] = SDLK_KP_PERIOD;
|
||||
RO_keymap[77] = SDLK_NUMLOCK;
|
||||
RO_keymap[78] = SDLK_PAGEDOWN;
|
||||
RO_keymap[79] = SDLK_QUOTE;
|
||||
RO_keymap[81] = SDLK_s;
|
||||
RO_keymap[82] = SDLK_c;
|
||||
RO_keymap[83] = SDLK_g;
|
||||
RO_keymap[84] = SDLK_h;
|
||||
RO_keymap[85] = SDLK_n;
|
||||
RO_keymap[86] = SDLK_l;
|
||||
RO_keymap[87] = SDLK_SEMICOLON;
|
||||
RO_keymap[88] = SDLK_RIGHTPAREN;
|
||||
RO_keymap[89] = SDLK_DELETE;
|
||||
RO_keymap[90] = SDLK_KP_MINUS;
|
||||
RO_keymap[91] = SDLK_KP_MULTIPLY;
|
||||
RO_keymap[93] = SDLK_EQUALS;
|
||||
RO_keymap[94] = SDLK_BACKSLASH;
|
||||
RO_keymap[96] = SDLK_TAB;
|
||||
RO_keymap[97] = SDLK_z;
|
||||
RO_keymap[98] = SDLK_SPACE;
|
||||
RO_keymap[99] = SDLK_v;
|
||||
RO_keymap[100] = SDLK_b;
|
||||
RO_keymap[101] = SDLK_m;
|
||||
RO_keymap[102] = SDLK_COMMA;
|
||||
RO_keymap[103] = SDLK_PERIOD;
|
||||
RO_keymap[104] = SDLK_SLASH;
|
||||
RO_keymap[105] = SDLK_END;
|
||||
RO_keymap[106] = SDLK_KP0;
|
||||
RO_keymap[107] = SDLK_KP1;
|
||||
RO_keymap[108] = SDLK_KP3;
|
||||
RO_keymap[112] = SDLK_ESCAPE;
|
||||
RO_keymap[113] = SDLK_F1;
|
||||
RO_keymap[114] = SDLK_F2;
|
||||
RO_keymap[115] = SDLK_F3;
|
||||
RO_keymap[116] = SDLK_F5;
|
||||
RO_keymap[117] = SDLK_F6;
|
||||
RO_keymap[118] = SDLK_F8;
|
||||
RO_keymap[119] = SDLK_F9;
|
||||
RO_keymap[120] = SDLK_HASH;
|
||||
RO_keymap[121] = SDLK_RIGHT;
|
||||
RO_keymap[122] = SDLK_KP4;
|
||||
RO_keymap[123] = SDLK_KP5;
|
||||
RO_keymap[124] = SDLK_KP2;
|
||||
|
||||
memset(RO_pressed, 0, ROKEYBD_ARRAYSIZE);
|
||||
}
|
||||
|
||||
|
||||
/* Variable for mouse relative processing */
|
||||
int mouse_relative = 0;
|
||||
|
||||
/* Check to see if we need to enter or leave mouse relative mode */
|
||||
|
||||
void RISCOS_CheckMouseMode(_THIS)
|
||||
{
|
||||
/* If the mouse is hidden and input is grabbed, we use relative mode */
|
||||
if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
|
||||
(this->input_grab != SDL_GRAB_OFF) ) {
|
||||
mouse_relative = 1;
|
||||
} else {
|
||||
mouse_relative = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RISCOS_PollMouse(_THIS)
|
||||
{
|
||||
RISCOS_PollMouseHelper(this, 1);
|
||||
}
|
||||
|
||||
extern int mouseInWindow;
|
||||
|
||||
void WIMP_PollMouse(_THIS)
|
||||
{
|
||||
/* Only poll when mouse is over the window */
|
||||
if (!mouseInWindow) return;
|
||||
|
||||
RISCOS_PollMouseHelper(this, 0);
|
||||
}
|
||||
|
||||
/* Static variables so only changes are reported */
|
||||
static Sint16 last_x = -1, last_y = -1;
|
||||
static int last_buttons = 0;
|
||||
|
||||
/* Share routine between WIMP and FULLSCREEN for polling mouse and
|
||||
passing on events */
|
||||
void RISCOS_PollMouseHelper(_THIS, int fullscreen)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
static int starting = 1;
|
||||
|
||||
if (_kernel_swi(OS_Mouse, ®s, ®s) == NULL)
|
||||
{
|
||||
Sint16 new_x = regs.r[0]; /* Initialy get as OS units */
|
||||
Sint16 new_y = regs.r[1];
|
||||
|
||||
/* Discard mouse events until the let go of the mouse after starting */
|
||||
if (starting && regs.r[2] != 0) return;
|
||||
else starting = 0;
|
||||
|
||||
if (new_x != last_x || new_y != last_y || last_buttons != regs.r[2])
|
||||
{
|
||||
/* Something changed so generate appropriate events */
|
||||
int topLeftX, topLeftY; /* Top left OS units */
|
||||
int x, y; /* Mouse position in SDL pixels */
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
topLeftX = 0;
|
||||
topLeftY = (this->hidden->height << this->hidden->yeig) - 1;
|
||||
} else
|
||||
{
|
||||
int window_state[9];
|
||||
|
||||
/* Get current window state */
|
||||
window_state[0] = this->hidden->window_handle;
|
||||
regs.r[1] = (unsigned int)window_state;
|
||||
_kernel_swi(Wimp_GetWindowState, ®s, ®s);
|
||||
|
||||
topLeftX = window_state[1];
|
||||
topLeftY = window_state[4];
|
||||
}
|
||||
|
||||
/* Convert co-ordinates to workspace */
|
||||
x = new_x - topLeftX;
|
||||
y = topLeftY - new_y; /* Y goes from top of window/screen */
|
||||
|
||||
/* Convert OS units to pixels */
|
||||
x >>= this->hidden->xeig;
|
||||
y >>= this->hidden->yeig;
|
||||
|
||||
if (last_x != new_x || last_y != new_y)
|
||||
{
|
||||
if (mouse_relative)
|
||||
{
|
||||
int centre_x = SDL_VideoSurface->w/2;
|
||||
int centre_y = SDL_VideoSurface->h/2;
|
||||
|
||||
if (centre_x != x || centre_y != y)
|
||||
{
|
||||
if (SDL_VideoSurface) SDL_PrivateMouseMotion(0,1,x - centre_x, y - centre_y);
|
||||
last_x = topLeftX + (centre_x << this->hidden->xeig);
|
||||
last_y = topLeftY - (centre_y << this->hidden->yeig);
|
||||
|
||||
/* Re-centre the mouse pointer, so we still get relative
|
||||
movement when the mouse is at the edge of the window
|
||||
or screen.
|
||||
*/
|
||||
{
|
||||
unsigned char block[5];
|
||||
|
||||
block[0] = 3; /* OSWORD move pointer sub-reason code */
|
||||
block[1] = last_x & 0xFF;
|
||||
block[2] = (last_x >> 8) & 0xFF;
|
||||
block[3] = last_y & 0xFF;
|
||||
block[4] = (last_y >> 8) & 0xFF;
|
||||
|
||||
regs.r[0] = 21; /* OSWORD pointer stuff code */
|
||||
regs.r[1] = (int)block;
|
||||
_kernel_swi(OS_Word, ®s, ®s);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
last_x = new_x;
|
||||
last_y = new_y;
|
||||
SDL_PrivateMouseMotion(0,0,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
if (last_buttons != regs.r[2])
|
||||
{
|
||||
int changed = last_buttons ^ regs.r[2];
|
||||
last_buttons = regs.r[2];
|
||||
if (changed & 4) SDL_PrivateMouseButton((last_buttons & 4) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT, x, y);
|
||||
if (changed & 2) SDL_PrivateMouseButton((last_buttons & 2) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE, x, y);
|
||||
if (changed & 1) SDL_PrivateMouseButton((last_buttons & 1) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RISCOS_PollKeyboard()
|
||||
{
|
||||
int which_key = ROKEY_LEFT_SHIFT;
|
||||
int j;
|
||||
int min_key, max_key;
|
||||
SDL_keysym key;
|
||||
|
||||
/* Scan the keyboard to see what is pressed */
|
||||
while (which_key <= ROKEY_LAST_KEY)
|
||||
{
|
||||
which_key = (_kernel_osbyte(121, which_key, 0) & 0xFF);
|
||||
if (which_key != ROKEY_NONE)
|
||||
{
|
||||
switch(which_key)
|
||||
{
|
||||
/* Skip over mouse keys */
|
||||
case ROKEY_LEFT_MOUSE:
|
||||
case ROKEY_CENTRE_MOUSE:
|
||||
case ROKEY_RIGHT_MOUSE:
|
||||
which_key = ROKEY_RIGHT_MOUSE;
|
||||
break;
|
||||
|
||||
/* Ignore keys that cause 2 internal number to be generated */
|
||||
case 71: case 24: case 87: case 40:
|
||||
break;
|
||||
|
||||
default:
|
||||
RO_pressed[which_key] += 2;
|
||||
break;
|
||||
}
|
||||
which_key++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate key released messages */
|
||||
min_key = ROKEY_LAST_KEY+1;
|
||||
max_key = ROKEY_LEFT_SHIFT;
|
||||
|
||||
for (j = ROKEY_LEFT_SHIFT; j <= ROKEY_LAST_KEY; j++)
|
||||
{
|
||||
if (RO_pressed[j])
|
||||
{
|
||||
if (RO_pressed[j] == 1)
|
||||
{
|
||||
RO_pressed[j] = 0;
|
||||
SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(j,&key,0));
|
||||
} else
|
||||
{
|
||||
if (j < min_key) min_key = j;
|
||||
if (j > max_key) max_key = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate key pressed messages */
|
||||
for (j = min_key; j <= max_key; j++)
|
||||
{
|
||||
if (RO_pressed[j])
|
||||
{
|
||||
if (RO_pressed[j] == 2)
|
||||
{
|
||||
SDL_PrivateKeyboard(SDL_PRESSED,TranslateKey(j,&key,1));
|
||||
}
|
||||
RO_pressed[j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed)
|
||||
{
|
||||
/* Set the keysym information */
|
||||
keysym->scancode = (unsigned char) intkey;
|
||||
keysym->sym = RO_keymap[intkey];
|
||||
keysym->mod = KMOD_NONE;
|
||||
keysym->unicode = 0;
|
||||
if ( pressed && SDL_TranslateUNICODE )
|
||||
{
|
||||
int state;
|
||||
int ch;
|
||||
|
||||
state = (_kernel_osbyte(202, 0, 255) & 0xFF);
|
||||
|
||||
/*TODO: better key to char mapping */
|
||||
|
||||
ch = keysym->sym; /* This should handle most keys */
|
||||
|
||||
if (intkey < 9)
|
||||
{
|
||||
ch = 0;
|
||||
|
||||
} else if (state & 64) /* Control on */
|
||||
{
|
||||
ch = ch & 31;
|
||||
|
||||
} else if ((state & 16) == 0) /* Caps lock is on */
|
||||
{
|
||||
if ((state & 128) == 0) /* Shift Enable off */
|
||||
{
|
||||
ch = toupper(ch);
|
||||
}
|
||||
} else if (state & 8) /* Shift on */
|
||||
{
|
||||
ch = toupper(ch);
|
||||
}
|
||||
|
||||
keysym->unicode = ch;
|
||||
}
|
||||
return(keysym);
|
||||
}
|
||||
|
||||
/* end of SDL_riscosevents.c ... */
|
||||
|
38
src/video/riscos/SDL_riscosevents_c.h
Normal file
38
src/video/riscos/SDL_riscosevents_c.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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 ... */
|
||||
|
301
src/video/riscos/SDL_riscosmouse.c
Normal file
301
src/video/riscos/SDL_riscosmouse.c
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
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, ®s, ®s);
|
||||
|
||||
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, ®s, ®s);
|
||||
|
||||
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, ®s, ®s);
|
||||
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, ®s, ®s);
|
||||
|
||||
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, ®s, ®s);
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
48
src/video/riscos/SDL_riscosmouse_c.h
Normal file
48
src/video/riscos/SDL_riscosmouse_c.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
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);
|
||||
|
263
src/video/riscos/SDL_riscossprite.c
Normal file
263
src/video/riscos/SDL_riscossprite.c
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
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, ®s, ®s);
|
||||
|
||||
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, ®s, ®s) == 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, ®s, ®s);
|
||||
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, ®s, ®s);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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, ®s, ®s)) != 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, ®s, ®s);
|
||||
|
||||
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, ®s, ®s);
|
||||
|
||||
/*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);
|
||||
}
|
356
src/video/riscos/SDL_riscostask.c
Normal file
356
src/video/riscos/SDL_riscostask.c
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
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
|
||||
|
||||
File includes routines for:
|
||||
Setting up as a WIMP Task
|
||||
Reading information about the current desktop
|
||||
Storing information before a switch to full screen
|
||||
Restoring desktop after switching to full screen
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "kernel.h"
|
||||
#include "swis.h"
|
||||
|
||||
#include "SDL_riscostask.h"
|
||||
|
||||
/* RISCOS variables */
|
||||
|
||||
static int task_handle = 0;
|
||||
static int wimp_version = 0;
|
||||
|
||||
/* RISC OS variables to help compatability with certain programs */
|
||||
int riscos_backbuffer = 0; /* Create a back buffer in system memory for full screen mode */
|
||||
int riscos_closeaction = 1; /* Close icon action */
|
||||
int riscos_audiobuffer = 0; /* Audio buffer size */
|
||||
|
||||
static int stored_mode = -1; /* -1 when in desktop, mode number or pointer when full screen */
|
||||
|
||||
extern int mouseInWindow; /* Mouse is in WIMP window */
|
||||
|
||||
/* Local function */
|
||||
|
||||
static int RISCOS_GetTaskName(char *task_name);
|
||||
|
||||
/* Uncomment next line to copy mode changes/restores to stderr */
|
||||
/* #define DUMP_MODE */
|
||||
#ifdef DUMP_MODE
|
||||
#include "stdio.h"
|
||||
static void dump_mode()
|
||||
{
|
||||
fprintf(stderr, "mode %d\n", stored_mode);
|
||||
if (stored_mode < -1 || stored_mode >= 256)
|
||||
{
|
||||
int blockSize = 0;
|
||||
int *storeBlock = (int *)stored_mode;
|
||||
|
||||
while(blockSize < 5 || storeBlock[blockSize] != -1)
|
||||
{
|
||||
fprintf(stderr, " %d\n", storeBlock[blockSize++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************
|
||||
|
||||
Initialise as RISCOS Wimp task
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
int RISCOS_InitTask()
|
||||
{
|
||||
char task_name[32];
|
||||
_kernel_swi_regs regs;
|
||||
int messages[4];
|
||||
|
||||
if (RISCOS_GetTaskName(task_name) == 0) return 0;
|
||||
|
||||
messages[0] = 9; /* Palette changed */
|
||||
messages[1] = 0x400c1; /* Mode changed */
|
||||
messages[2] = 8; /* Pre quit */
|
||||
messages[2] = 0;
|
||||
|
||||
regs.r[0] = (unsigned int)360; /* Minimum version 3.6 */
|
||||
regs.r[1] = (unsigned int)0x4b534154;
|
||||
regs.r[2] = (unsigned int)task_name;
|
||||
regs.r[3] = (unsigned int)messages;
|
||||
|
||||
if (_kernel_swi(Wimp_Initialise, ®s, ®s) == 0)
|
||||
{
|
||||
wimp_version = regs.r[0];
|
||||
task_handle = regs.r[1];
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
Close down application on exit.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
void RISCOS_ExitTask()
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
|
||||
if (stored_mode == -1)
|
||||
{
|
||||
/* Ensure cursor is put back to standard pointer shape if
|
||||
we have been running in a window */
|
||||
_kernel_osbyte(106,1,0);
|
||||
}
|
||||
|
||||
/* Ensure we end up back in the wimp */
|
||||
RISCOS_RestoreWimpMode();
|
||||
|
||||
/* Neatly exit the task */
|
||||
regs.r[0] = task_handle;
|
||||
regs.r[1] = (unsigned int)0x4b534154;
|
||||
_kernel_swi(Wimp_CloseDown, ®s, ®s);
|
||||
task_handle = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
Get the name of the task for the desktop.
|
||||
|
||||
Param: task_name - name of task 32 characters.
|
||||
|
||||
Returns: 1 is successful, otherwise 0
|
||||
|
||||
Notes: Works by getting using OS_GetEnv to get the command line
|
||||
used to run the program and then parsing a name from it
|
||||
as follows.
|
||||
|
||||
1. Use name after final period if not !RunImage
|
||||
2. If name is !RunImage then process item before the period
|
||||
in front of !RunImage.
|
||||
3. If directory name use that
|
||||
4. if in form <XXX$Dir> use the XXX.
|
||||
|
||||
Finally once this value has been retrieved use it unless
|
||||
there is a variable set up in the form SDL$<name>$TaskName
|
||||
in which case the value of this variable will be used.
|
||||
|
||||
Now also gets other riscos configuration varibles
|
||||
SDL$<name>$BackBuffer - set to 1 to use a system memory backbuffer in fullscreen mode
|
||||
so updates wait until a call to SDL_UpdateRects. (default 0)
|
||||
This is required for programmes where they have assumed this is
|
||||
always the case which is contrary to the documentation.
|
||||
SDL$<name>$CloseAction
|
||||
0 Don't show close icon
|
||||
1 Show close icon
|
||||
|
||||
SDL$<name>$AudioBuffer - set to number of samples to buffer
|
||||
in advance. Will default to a minimum of 1024 or twice
|
||||
amount requested by program whichever is largest.
|
||||
If not specified default is amount for 10 csecs.
|
||||
Time that will be pre-buffered can be calculated as
|
||||
sample to buffer * 1000 / freq milliseconds.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
int RISCOS_GetTaskName(char *task_name)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
|
||||
task_name[0] = 0;
|
||||
|
||||
/* Figure out a sensible task name */
|
||||
if (_kernel_swi(OS_GetEnv, ®s, ®s) == 0)
|
||||
{
|
||||
char *command_line = (char *)regs.r[0];
|
||||
char *buffer = malloc(strlen(command_line)+1);
|
||||
char *env_var;
|
||||
char *p;
|
||||
|
||||
strcpy(buffer, command_line);
|
||||
p = strchr(buffer, ' ');
|
||||
if (p) *p = 0;
|
||||
p = strrchr(buffer, '.');
|
||||
if (p == 0) p = buffer;
|
||||
if (stricmp(p+1,"!RunImage") == 0)
|
||||
{
|
||||
*p = 0;
|
||||
p = strrchr(buffer, '.');
|
||||
if (p == 0) p = buffer;
|
||||
}
|
||||
if (*p == '.') p++;
|
||||
if (*p == '!') p++; /* Skip "!" at beginning of application directories */
|
||||
|
||||
if (*p == '<')
|
||||
{
|
||||
// Probably in the form <appname$Dir>
|
||||
char *q = strchr(p, '$');
|
||||
if (q == 0) q = strchr(p,'>'); /* Use variable name if not */
|
||||
if (q) *q = 0;
|
||||
p++; /* Move over the < */
|
||||
}
|
||||
|
||||
if (*p)
|
||||
{
|
||||
/* Read variables that effect the RISCOS SDL engine for this task */
|
||||
env_var = malloc(strlen(p) + 18); /* 18 is larger than the biggest variable name */
|
||||
if (env_var)
|
||||
{
|
||||
char *env_val;
|
||||
|
||||
/* See if a variable of form SDL$<dirname>$TaskName exists */
|
||||
|
||||
strcpy(env_var, "SDL$");
|
||||
strcat(env_var, p);
|
||||
strcat(env_var, "$TaskName");
|
||||
|
||||
env_val = getenv(env_var);
|
||||
if (env_val) strncpy(task_name, env_val, 31);
|
||||
|
||||
strcpy(env_var, "SDL$");
|
||||
strcat(env_var, p);
|
||||
strcat(env_var, "$BackBuffer");
|
||||
|
||||
env_val = getenv(env_var);
|
||||
if (env_val && strcmp(env_val,"1") == 0) riscos_backbuffer = 1;
|
||||
|
||||
strcpy(env_var, "SDL$");
|
||||
strcat(env_var, p);
|
||||
strcat(env_var, "$CloseAction");
|
||||
|
||||
env_val = getenv(env_var);
|
||||
if (env_val && strcmp(env_val,"0") == 0) riscos_closeaction = 0;
|
||||
|
||||
strcpy(env_var, "SDL$");
|
||||
strcat(env_var, p);
|
||||
strcat(env_var, "$AudioBuffer");
|
||||
|
||||
env_val = getenv(env_var);
|
||||
riscos_audiobuffer = atoi(env_val);
|
||||
|
||||
free(env_var);
|
||||
}
|
||||
|
||||
if (task_name[0] == 0) strncpy(task_name, p, 31);
|
||||
task_name[31] = 0;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
if (task_name[0] == 0) strcpy(task_name, "SDL Task");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
|
||||
Store the current desktop screen mode if we are in the desktop.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
void RISCOS_StoreWimpMode()
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
|
||||
/* Don't store if in full screen mode */
|
||||
if (stored_mode != -1) return;
|
||||
|
||||
regs.r[0] = 1;
|
||||
_kernel_swi(OS_ScreenMode, ®s, ®s);
|
||||
if (regs.r[1] >= 0 && regs.r[1] < 256) stored_mode = regs.r[1];
|
||||
else
|
||||
{
|
||||
int blockSize = 0;
|
||||
int *retBlock = (int *)regs.r[1];
|
||||
int *storeBlock;
|
||||
int j;
|
||||
|
||||
while(blockSize < 5 || retBlock[blockSize] != -1) blockSize++;
|
||||
blockSize++;
|
||||
storeBlock = (int *)malloc(blockSize * sizeof(int));
|
||||
retBlock = (int *)regs.r[1];
|
||||
for ( j = 0; j < blockSize; j++)
|
||||
storeBlock[j] = retBlock[j];
|
||||
|
||||
stored_mode = (int)storeBlock;
|
||||
}
|
||||
#if DUMP_MODE
|
||||
fprintf(stderr, "Stored "); dump_mode();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
|
||||
Restore desktop screen mode if we are in full screen mode.
|
||||
|
||||
*****************************************************************/
|
||||
|
||||
void RISCOS_RestoreWimpMode()
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
|
||||
/* Only need to restore if we are in full screen mode */
|
||||
if (stored_mode == -1) return;
|
||||
|
||||
#if DUMP_MODE
|
||||
fprintf(stderr, "Restored"); dump_mode();
|
||||
#endif
|
||||
|
||||
regs.r[0] = stored_mode;
|
||||
_kernel_swi(Wimp_SetMode, ®s, ®s);
|
||||
if (stored_mode < 0 || stored_mode > 256)
|
||||
{
|
||||
free((int *)stored_mode);
|
||||
}
|
||||
stored_mode = -1;
|
||||
|
||||
/* Flush keyboard buffer to dump the keystrokes we've already polled */
|
||||
regs.r[0] = 21;
|
||||
regs.r[1] = 0; /* Keyboard buffer number */
|
||||
_kernel_swi(OS_Byte, ®s, ®s);
|
||||
|
||||
mouseInWindow = 0;
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
Get version of Wimp running when task was initialised.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
int RISCOS_GetWimpVersion()
|
||||
{
|
||||
return wimp_version;
|
||||
}
|
||||
|
||||
int RISCOS_GetTaskHandle()
|
||||
{
|
||||
return task_handle;
|
||||
}
|
38
src/video/riscos/SDL_riscostask.h
Normal file
38
src/video/riscos/SDL_riscostask.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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();
|
312
src/video/riscos/SDL_riscosvideo.c
Normal file
312
src/video/riscos/SDL_riscosvideo.c
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
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, ®s, ®s);
|
||||
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;
|
||||
}
|
||||
|
66
src/video/riscos/SDL_riscosvideo.h
Normal file
66
src/video/riscos/SDL_riscosvideo.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
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 */
|
309
src/video/riscos/SDL_wimppoll.c
Normal file
309
src/video/riscos/SDL_wimppoll.c
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
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, ®s, ®s);
|
||||
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, ®s, ®s);
|
||||
} else
|
||||
{
|
||||
regs.r[0] = pollMask;
|
||||
regs.r[1] = (int)message;
|
||||
regs.r[2] = waitTime;
|
||||
_kernel_swi(Wimp_PollIdle, ®s, ®s);
|
||||
}
|
||||
|
||||
/* 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, ®s,®s);
|
||||
if (message[0] == sdlWindow)
|
||||
{
|
||||
while (regs.r[0])
|
||||
{
|
||||
WIMP_PlotSprite(this, message[1], message[2]);
|
||||
_kernel_swi(Wimp_GetRectangle, ®s, ®s);
|
||||
}
|
||||
} else
|
||||
{
|
||||
/* TODO: Currently we just eat them - we may need to pass them on */
|
||||
while (regs.r[0])
|
||||
{
|
||||
_kernel_swi(Wimp_GetRectangle, ®s, ®s);
|
||||
}
|
||||
}
|
||||
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, ®s, ®s);
|
||||
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, ®s, ®s);
|
||||
** 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, ®s, ®s);
|
||||
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, ®s, ®s);
|
||||
}
|
||||
*/
|
||||
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, ®s, ®s);
|
||||
}
|
||||
|
||||
/** 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();
|
||||
}
|
492
src/video/riscos/SDL_wimpvideo.c
Normal file
492
src/video/riscos/SDL_wimpvideo.c
Normal file
@ -0,0 +1,492 @@
|
||||
/*
|
||||
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 RISCOS wimp display.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL.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"
|
||||
|
||||
/* Initialization/Query functions */
|
||||
SDL_Rect **WIMP_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
|
||||
SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
|
||||
int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
|
||||
void WIMP_SetWMCaption(_THIS, const char *title, const char *icon);
|
||||
|
||||
|
||||
extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp);
|
||||
extern void WIMP_PumpEvents(_THIS);
|
||||
extern void WIMP_PlotSprite(_THIS, int x, int y);
|
||||
extern void WIMP_SetupPlotInfo(_THIS);
|
||||
extern void WIMP_SetFocus(int win);
|
||||
|
||||
/* etc. */
|
||||
static void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
|
||||
|
||||
/* RISC OS Wimp handling helpers */
|
||||
void WIMP_ReadModeInfo(_THIS);
|
||||
unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface);
|
||||
void WIMP_SetDeviceMode(_THIS);
|
||||
void WIMP_DeleteWindow(_THIS);
|
||||
|
||||
/* FULLSCREEN function required for wimp/fullscreen toggling */
|
||||
extern int FULLSCREEN_SetMode(int width, int height, int bpp);
|
||||
|
||||
/* Currently need to set this up here as it only works if you
|
||||
start up in a Wimp mode */
|
||||
extern int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
|
||||
|
||||
extern int riscos_backbuffer;
|
||||
extern int mouseInWindow;
|
||||
extern int riscos_closeaction;
|
||||
|
||||
|
||||
SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current,
|
||||
int width, int height, int bpp, Uint32 flags)
|
||||
{
|
||||
Uint32 Rmask = 0;
|
||||
Uint32 Gmask = 0;
|
||||
Uint32 Bmask = 0;
|
||||
char *buffer = NULL;
|
||||
int bytesPerPixel = 1;
|
||||
|
||||
/* Don't support double buffering in Wimp mode */
|
||||
flags &= ~SDL_DOUBLEBUF;
|
||||
flags &= ~SDL_HWSURFACE;
|
||||
|
||||
switch(bpp)
|
||||
{
|
||||
case 8:
|
||||
/* Emulated palette using ColourTrans */
|
||||
flags |= SDL_HWPALETTE;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
Bmask = 0x00007c00;
|
||||
Gmask = 0x000003e0;
|
||||
Rmask = 0x0000001f;
|
||||
bytesPerPixel = 2;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
Bmask = 0x00ff0000;
|
||||
Gmask = 0x0000ff00;
|
||||
Rmask = 0x000000ff;
|
||||
bytesPerPixel = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_SetError("Pixel depth not supported");
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* printf("Setting mode %dx%d\n", width, height);*/
|
||||
|
||||
/* Allocate the new pixel format for the screen */
|
||||
if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
|
||||
SDL_SetError("Couldn't allocate new pixel format for requested mode");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Set up the new mode framebuffer */
|
||||
current->w = width;
|
||||
this->hidden->height = current->h = height;
|
||||
|
||||
if (bpp == 15) bpp = 16;
|
||||
buffer = WIMP_CreateBuffer(width, height, bpp);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
SDL_SetError("Couldn't create sprite for video memory");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
this->hidden->bank[0] = buffer + 60; /* Start of sprite data */
|
||||
if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
|
||||
|
||||
this->hidden->bank[1] = buffer; /* Start of buffer */
|
||||
|
||||
/* Remember sprite buffer so it can be freed later */
|
||||
if (this->hidden->alloc_bank) free(this->hidden->alloc_bank);
|
||||
this->hidden->alloc_bank = buffer;
|
||||
|
||||
current->pitch = width * bytesPerPixel;
|
||||
if ((current->pitch & 3))
|
||||
{
|
||||
/* Sprites are 32bit word aligned */
|
||||
current->pitch += (4 - (current->pitch & 3));
|
||||
}
|
||||
|
||||
current->flags = flags | SDL_PREALLOC;
|
||||
|
||||
WIMP_ReadModeInfo(this);
|
||||
|
||||
memset(this->hidden->bank[0], 0, height * current->pitch);
|
||||
|
||||
this->hidden->current_bank = 0;
|
||||
current->pixels = this->hidden->bank[0];
|
||||
|
||||
|
||||
if (WIMP_SetupWindow(this, current) == 0)
|
||||
{
|
||||
SDL_SetError("Unable to create window to display surface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Reset device functions for the wimp */
|
||||
WIMP_SetDeviceMode(this);
|
||||
|
||||
/* Needs to set up plot info after window has been created */
|
||||
/* Not sure why, but plots don't work if I do it earlier */
|
||||
WIMP_SetupPlotInfo(this);
|
||||
|
||||
/* We're done */
|
||||
return(current);
|
||||
}
|
||||
|
||||
|
||||
void WIMP_ReadModeInfo(_THIS)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
int vars[6];
|
||||
int vals[5];
|
||||
|
||||
vars[0] = 4; /* XEig */
|
||||
vars[1] = 5; /* YEig */
|
||||
vars[2] = 9; /* Log base 2 bpp */
|
||||
vars[3] = 11; /* Screen Width - 1 */
|
||||
vars[4] = 12; /* Screen Depth - 1 */
|
||||
vars[5] = -1; /* Terminate list */
|
||||
|
||||
regs.r[0] = (int)vars;
|
||||
regs.r[1] = (int)vals;
|
||||
_kernel_swi(OS_ReadVduVariables, ®s, ®s);
|
||||
this->hidden->xeig = vals[0];
|
||||
this->hidden->yeig = vals[1];
|
||||
this->hidden->screen_bpp = 1 << vals[2];
|
||||
this->hidden->screen_width = vals[3] + 1;
|
||||
this->hidden->screen_height = vals[4] + 1;
|
||||
}
|
||||
|
||||
/* Set device function to call the correct versions for running
|
||||
in a wimp window */
|
||||
|
||||
void WIMP_SetDeviceMode(_THIS)
|
||||
{
|
||||
if (this->UpdateRects == WIMP_UpdateRects) return; /* Already set up */
|
||||
|
||||
this->SetColors = WIMP_SetColors;
|
||||
this->UpdateRects = WIMP_UpdateRects;
|
||||
|
||||
this->FlipHWSurface = NULL;
|
||||
|
||||
this->SetCaption = WIMP_SetWMCaption;
|
||||
this->SetIcon = NULL;
|
||||
this->IconifyWindow = NULL;
|
||||
|
||||
this->ShowWMCursor = WIMP_ShowWMCursor;
|
||||
this->WarpWMCursor = WIMP_WarpWMCursor;
|
||||
|
||||
this->ToggleFullScreen = RISCOS_ToggleFullScreen;
|
||||
|
||||
this->PumpEvents = WIMP_PumpEvents;
|
||||
}
|
||||
|
||||
/* Setup the Window to display the surface */
|
||||
unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
int window_data[23];
|
||||
int *window_block = window_data+1;
|
||||
int x = (this->hidden->screen_width - surface->w) / 2;
|
||||
int y = (this->hidden->screen_height - surface->h) / 2;
|
||||
int xeig = this->hidden->xeig;
|
||||
int yeig = this->hidden->yeig;
|
||||
|
||||
mouseInWindow = 0;
|
||||
|
||||
/* Always delete the window and recreate on a change */
|
||||
if (this->hidden->window_handle) WIMP_DeleteWindow(this);
|
||||
|
||||
/* Setup window co-ordinates */
|
||||
window_block[0] = x << xeig;
|
||||
window_block[1] = y << yeig;
|
||||
window_block[2] = window_block[0] + (surface->w << xeig);
|
||||
window_block[3] = window_block[1] + (surface->h << yeig);
|
||||
|
||||
|
||||
window_block[4] = 0; /* Scroll offsets */
|
||||
window_block[5] = 0;
|
||||
window_block[6] = -1; /* Open on top of window stack */
|
||||
|
||||
window_block[7] = 0x85040042; /* Window flags */
|
||||
if (riscos_closeaction != 0) window_block[7] |= 0x2000000;
|
||||
|
||||
/* TODO: Take into account surface->flags */
|
||||
|
||||
window_block[8] = 0xff070207; /* Window colours */
|
||||
window_block[9] = 0x000c0103;
|
||||
window_block[10] = 0; /* Work area minimum */
|
||||
window_block[11] = -surface->h << yeig;
|
||||
window_block[12] = surface->w << xeig; /* Work area maximum */
|
||||
window_block[13] = 0;
|
||||
window_block[14] = 0x2700013d; /* Title icon flags */
|
||||
window_block[15] = 0x00003000; /* Work area flags - Mouse click down reported */
|
||||
window_block[16] = 1; /* Sprite area control block pointer */
|
||||
window_block[17] = 0x00100010; /* Minimum window size (width & height) (16x16)*/
|
||||
window_block[18] = (int)this->hidden->title; /* Title data */
|
||||
window_block[19] = -1;
|
||||
window_block[20] = 256;
|
||||
window_block[21] = 0; /* Number of icons */
|
||||
|
||||
regs.r[1] = (unsigned int)(window_block);
|
||||
|
||||
/* Create the window */
|
||||
if (_kernel_swi(Wimp_CreateWindow, ®s, ®s) == NULL)
|
||||
{
|
||||
this->hidden->window_handle = window_data[0] = regs.r[0];
|
||||
|
||||
/* Show the window on the screen */
|
||||
regs.r[1] = (unsigned int)window_data;
|
||||
if (_kernel_swi(Wimp_OpenWindow, ®s, ®s) == NULL)
|
||||
{
|
||||
WIMP_SetFocus(this->hidden->window_handle);
|
||||
} else
|
||||
{
|
||||
WIMP_DeleteWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
return this->hidden->window_handle;
|
||||
}
|
||||
|
||||
/* Destroy the Window */
|
||||
|
||||
void WIMP_DeleteWindow(_THIS)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[1] = (unsigned int)&(this->hidden->window_handle);
|
||||
_kernel_swi(Wimp_DeleteWindow, ®s, ®s);
|
||||
this->hidden->window_handle = 0;
|
||||
}
|
||||
|
||||
|
||||
void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
int update_block[12];
|
||||
int xeig = this->hidden->xeig;
|
||||
int yeig = this->hidden->yeig;
|
||||
int j;
|
||||
update_block[0] = this->hidden->window_handle;
|
||||
|
||||
for (j = 0; j < numrects; j++)
|
||||
{
|
||||
update_block[1] = rects[j].x << xeig; /* Min X */
|
||||
update_block[4] = -(rects[j].y << yeig);
|
||||
update_block[3] = update_block[1] + (rects[j].w << xeig);
|
||||
update_block[2] = update_block[4] - (rects[j].h << yeig);
|
||||
|
||||
regs.r[1] = (int)update_block;
|
||||
/* Update window can fail if called before first poll */
|
||||
if (_kernel_swi(Wimp_UpdateWindow, ®s, ®s) == 0)
|
||||
{
|
||||
while (regs.r[0])
|
||||
{
|
||||
WIMP_PlotSprite(this, update_block[1], update_block[2]);
|
||||
_kernel_swi(Wimp_GetRectangle, ®s, ®s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
|
||||
{
|
||||
unsigned int *pal = (unsigned int *)(this->hidden->bank[1]+60);
|
||||
int j;
|
||||
SDL_Rect update;
|
||||
|
||||
pal += firstcolor*2;
|
||||
for (j = 0; j < ncolors; j++)
|
||||
{
|
||||
*pal = (((unsigned int)colors->r) << 8)
|
||||
+ (((unsigned int)colors->g) << 16)
|
||||
+ (((unsigned int)colors->b) << 24);
|
||||
pal[1] = *pal;
|
||||
pal += 2;
|
||||
colors++;
|
||||
}
|
||||
|
||||
WIMP_SetupPlotInfo(this);
|
||||
|
||||
/* Need to refresh the window */
|
||||
update.x = 0;
|
||||
update.y = 0;
|
||||
update.w = SDL_VideoSurface->w;
|
||||
update.h = SDL_VideoSurface->h;
|
||||
WIMP_UpdateRects(this, 1, &update);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void WIMP_SetWMCaption(_THIS, const char *title, const char *icon)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
|
||||
strncpy(this->hidden->title, title, 255);
|
||||
this->hidden->title[255] = 0;
|
||||
|
||||
if (RISCOS_GetWimpVersion() < 380)
|
||||
{
|
||||
int block[6];
|
||||
|
||||
regs.r[1] = (int)block;
|
||||
_kernel_swi(Wimp_GetCaretPosition, ®s, ®s);
|
||||
if (block[0] == (int)this->hidden->window_handle)
|
||||
{
|
||||
regs.r[0] = -1;
|
||||
_kernel_swi(Wimp_SetCaretPosition, ®s,®s);
|
||||
} else
|
||||
{
|
||||
regs.r[0] = this->hidden->window_handle;
|
||||
regs.r[1] = -1;
|
||||
regs.r[2] = -1;
|
||||
regs.r[3] = -1;
|
||||
_kernel_swi(Wimp_SetCaretPosition, ®s,®s);
|
||||
}
|
||||
regs.r[0] = block[0];
|
||||
regs.r[1] = block[1];
|
||||
regs.r[2] = block[2];
|
||||
regs.r[3] = block[3];
|
||||
regs.r[4] = block[4];
|
||||
regs.r[5] = block[5];
|
||||
_kernel_swi(Wimp_SetCaretPosition, ®s,®s);
|
||||
} else
|
||||
{
|
||||
regs.r[0] = this->hidden->window_handle;
|
||||
regs.r[1] = 0x4b534154; /* "TASK" */
|
||||
regs.r[2] = 3; /* Redraw title */
|
||||
_kernel_swi(Wimp_ForceRedraw, ®s, ®s);
|
||||
}
|
||||
}
|
||||
|
||||
void WIMP_RefreshDesktop(_THIS)
|
||||
{
|
||||
int width = this->hidden->screen_width << this->hidden->xeig;
|
||||
int height = this->hidden->screen_height << this->hidden->yeig;
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[0] = -1; /* Whole screen */
|
||||
regs.r[1] = 0;
|
||||
regs.r[2] = 0;
|
||||
regs.r[3] = width;
|
||||
regs.r[4] = height;
|
||||
_kernel_swi(Wimp_ForceRedraw, ®s, ®s);
|
||||
}
|
||||
|
||||
/* Toggle to window from full screen */
|
||||
int WIMP_ToggleFromFullScreen(_THIS)
|
||||
{
|
||||
int width = this->screen->w;
|
||||
int height = this->screen->h;
|
||||
int bpp = this->screen->format->BitsPerPixel;
|
||||
char *buffer = NULL;
|
||||
char *old_bank[2];
|
||||
char *old_alloc_bank;
|
||||
|
||||
/* Ensure flags are OK */
|
||||
this->screen->flags &= ~(SDL_DOUBLEBUF|SDL_HWSURFACE);
|
||||
|
||||
if (this->hidden->bank[0] == this->hidden->alloc_bank || riscos_backbuffer == 0)
|
||||
{
|
||||
/* Need to create a sprite for the screen and copy the data to it */
|
||||
char *data;
|
||||
buffer = WIMP_CreateBuffer(width, height, bpp);
|
||||
data = buffer + 60; /* Start of sprite data */
|
||||
if (bpp == 8) data += 2048; /* 8bpp sprite have palette first */
|
||||
|
||||
if (buffer == NULL) return 0;
|
||||
memcpy(data, this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel);
|
||||
}
|
||||
/* else We've switch to full screen before so we already have a sprite */
|
||||
|
||||
old_bank[0] = this->hidden->bank[0];
|
||||
old_bank[1] = this->hidden->bank[1];
|
||||
old_alloc_bank = this->hidden->alloc_bank;
|
||||
|
||||
if (buffer != NULL) this->hidden->alloc_bank = buffer;
|
||||
|
||||
this->hidden->bank[1] = this->hidden->alloc_bank;
|
||||
this->hidden->bank[0] = this->hidden->bank[1] + 60; /* Start of sprite data */
|
||||
if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
|
||||
|
||||
this->hidden->current_bank = 0;
|
||||
this->screen->pixels = this->hidden->bank[0];
|
||||
|
||||
RISCOS_RestoreWimpMode();
|
||||
WIMP_ReadModeInfo(this);
|
||||
if (WIMP_SetupWindow(this, this->screen))
|
||||
{
|
||||
WIMP_SetDeviceMode(this);
|
||||
WIMP_SetupPlotInfo(this);
|
||||
|
||||
riscos_backbuffer = 1;
|
||||
|
||||
if (buffer && old_alloc_bank) free(old_alloc_bank);
|
||||
|
||||
return 1;
|
||||
} else
|
||||
{
|
||||
/* Drop back to full screen mode on failure */
|
||||
this->hidden->bank[0] = old_bank[0];
|
||||
this->hidden->bank[1] = old_bank[1];
|
||||
this->hidden->alloc_bank = old_alloc_bank;
|
||||
if (buffer) free(buffer);
|
||||
|
||||
RISCOS_StoreWimpMode();
|
||||
FULLSCREEN_SetMode(width, height, bpp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user