146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*
246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    SDL - Simple DirectMedia Layer
346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Copyright (C) 1997-2006 Sam Lantinga
446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    This library is free software; you can redistribute it and/or
646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    modify it under the terms of the GNU Lesser General Public
746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    License as published by the Free Software Foundation; either
846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    version 2.1 of the License, or (at your option) any later version.
946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    This library is distributed in the hope that it will be useful,
1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    but WITHOUT ANY WARRANTY; without even the implied warranty of
1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Lesser General Public License for more details.
1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    You should have received a copy of the GNU Lesser General Public
1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    License along with this library; if not, write to the Free Software
1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Sam Lantinga
2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    slouken@libsdl.org
2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/
2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h"
2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef SDL_JOYSTICK_RISCOS
2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*
2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner   RISC OS - Joystick support by Alan Buckley (alan_baa@hotmail.com) - 10 April 2003
2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner   Note: Currently assumes joystick is present if joystick module is loaded
3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner   and that there is one joystick with four buttons.
3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/
3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* This is the system specific header for the SDL joystick API */
3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_events.h"
3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_joystick.h"
3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_sysjoystick.h"
3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_joystick_c.h"
3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "kernel.h"
4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define JOYSTICK_READ 0x43F40
4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstruct joystick_hwdata
4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	int joystate;
4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner};
4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Function to scan the system for joysticks.
5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * This function should set SDL_numjoysticks to the number of available
5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * joysticks.  Joystick 0 should be the system default joystick.
5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * It should return number of joysticks, or -1 on an unrecoverable fatal error.
5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */
5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SYS_JoystickInit(void)
5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	_kernel_swi_regs regs;
5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	 /* Try to read joystick 0 */
6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	regs.r[0] = 0;
6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if (_kernel_swi(JOYSTICK_READ, &regs, &regs) == NULL)
6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	{
6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		/* Switch works so assume we've got a joystick */
6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		return 1;
6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	/* Switch fails so it looks like there's no joystick here */
6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return(0);
6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Function to get the device-dependent name of a joystick */
7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerconst char *SDL_SYS_JoystickName(int index)
7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if (index == 0)
7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	{
7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		return "RISC OS Joystick 0";
7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_SetError("No joystick available with that index");
8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return(NULL);
8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Function to open a joystick for use.
8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner   The joystick to open is specified by the index field of the joystick.
8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner   This should fill the nbuttons and naxes fields of the joystick structure.
8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner   It returns 0, or -1 if there is an error.
8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */
8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	_kernel_swi_regs regs;
9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if(!(joystick->hwdata=SDL_malloc(sizeof(struct joystick_hwdata))))
9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		return -1;
9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	regs.r[0] = joystick->index;
9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	/* Don't know how to get exact count of buttons so assume max of 4 for now */
9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	joystick->nbuttons=4;
9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	joystick->nhats=0;
10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	joystick->nballs=0;
10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	joystick->naxes=2;
10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	joystick->hwdata->joystate=0;
10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return 0;
10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Function to update the state of a joystick - called as a device poll.
11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * This function shouldn't update the joystick structure directly,
11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * but instead should call SDL_PrivateJoystick*() to deliver events
11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * and update joystick device state.
11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */
11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	_kernel_swi_regs regs;
11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	regs.r[0] = joystick->index;
11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if (_kernel_swi(JOYSTICK_READ, &regs, &regs) == NULL)
12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	{
12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		int newstate = regs.r[0];
12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		int oldstate = joystick->hwdata->joystate;
12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if (newstate != oldstate)
12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		{
12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			if ((newstate & 0xFF) != (oldstate & 0xFF))
12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			{
12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				int y = regs.r[0] & 0xFF;
12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				/* Convert to signed values */
12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				if (y >= 128) y -= 256;
13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				SDL_PrivateJoystickAxis(joystick,1,-y * 256); /* Up and down opposite to result in SDL */
13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			}
13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			if ((newstate & 0xFF00) != (oldstate & 0xFF00))
13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			{
13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				int x = (regs.r[0] & 0xFF00) >> 8;
13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				if (x >= 128) x -= 256;
13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				SDL_PrivateJoystickAxis(joystick,0,x * 256);
13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			}
13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			if ((newstate & 0xFF0000) != (oldstate & 0xFF0000))
14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			{
14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				int buttons = (regs.r[0] & 0xFF0000) >> 16;
14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				int oldbuttons = (oldstate & 0xFF0000) >> 16;
14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				int i;
14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				for (i = 0; i < joystick->nbuttons; i++)
14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				{
14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					if ((buttons & (1<<i)) != (oldbuttons & (1<<i)))
14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					{
14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner						if (buttons & (1<<i)) SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner						else SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					}
15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				}
15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			}
15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			joystick->hwdata->joystate = newstate;
15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return;
15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Function to close a joystick after use */
16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_JoystickClose(SDL_Joystick *joystick)
16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	if(joystick->hwdata)
16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		SDL_free(joystick->hwdata);
16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return;
16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Function to perform any system-specific joystick related cleanup */
16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_JoystickQuit(void)
17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_numjoysticks=0;
17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return;
17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* SDL_JOYSTICK_RISCOS */
177