1/*
2    SDL - Simple DirectMedia Layer
3    Copyright (C) 1997-2006 Sam Lantinga
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19    Sam Lantinga
20    slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24#ifdef SDL_JOYSTICK_AMIGA
25
26/* This is the system specific header for the SDL joystick API */
27
28#include <libraries/lowlevel.h>
29#if defined(__SASC) || defined(STORMC4_WOS)
30#include <proto/exec.h>
31#include <proto/lowlevel.h>
32#include <proto/graphics.h>
33#else
34#include <inline/exec.h>
35#include <inline/lowlevel.h>
36#include <inline/graphics.h>
37#endif
38#include "mydebug.h"
39
40extern struct ExecBase *SysBase;
41extern struct GfxBase *GfxBase;
42
43#include "SDL_joystick.h"
44#include "../SDL_sysjoystick.h"
45#include "../SDL_joystick_c.h"
46
47/* Function to scan the system for joysticks.
48 * This function should set SDL_numjoysticks to the number of available
49 * joysticks.  Joystick 0 should be the system default joystick.
50 * It should return 0, or -1 on an unrecoverable fatal error.
51 */
52
53
54/* Amiga specific datas */
55struct Library *LowLevelBase=NULL;
56
57ULONG joybut[]=
58{
59	JPF_BUTTON_RED,
60	JPF_BUTTON_BLUE,
61	JPF_BUTTON_PLAY,
62	JPF_BUTTON_YELLOW,
63	JPF_BUTTON_GREEN,
64	JPF_BUTTON_FORWARD,
65	JPF_BUTTON_REVERSE,
66};
67
68struct joystick_hwdata
69{
70	ULONG joystate;
71};
72
73int SDL_SYS_JoystickInit(void)
74{
75	if(!LowLevelBase)
76	{
77		if(LowLevelBase=OpenLibrary("lowlevel.library",37))
78			return 2;
79	}
80	else
81		return 2;
82
83	D(bug("%ld joysticks available.\n",SDL_numjoysticks));
84
85	return 0;
86}
87
88/* Function to get the device-dependent name of a joystick */
89const char *SDL_SYS_JoystickName(int index)
90{
91	if(index<2&&LowLevelBase)
92	{
93		switch(index)
94		{
95			case 0:
96				return "Port 1 Amiga Joystick/Joypad";
97			case 1:
98				return "Port 2 Amiga Joystick/Joypad";
99		}
100	}
101
102	SDL_SetError("No joystick available with that index");
103	return(NULL);
104}
105
106/* Function to open a joystick for use.
107   The joystick to open is specified by the index field of the joystick.
108   This should fill the nbuttons and naxes fields of the joystick structure.
109   It returns 0, or -1 if there is an error.
110 */
111
112int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
113{
114	ULONG temp,i;
115	D(bug("Opening joystick %ld\n",joystick->index));
116
117	if(!(joystick->hwdata=SDL_malloc(sizeof(struct joystick_hwdata))))
118		return -1;
119
120/* This loop is to check if the controller is a joypad */
121
122	for(i=0;i<20;i++)
123	{
124		temp=ReadJoyPort(joystick->index^1); // fix to invert amiga joyports
125		WaitTOF();
126	}
127
128	if((temp&JP_TYPE_MASK)==JP_TYPE_GAMECTLR)
129		joystick->nbuttons=7;
130	else
131		joystick->nbuttons=3;
132
133	joystick->nhats=0;
134	joystick->nballs=0;
135	joystick->naxes=2;
136	joystick->hwdata->joystate=0L;
137
138	return 0;
139}
140
141/* Function to update the state of a joystick - called as a device poll.
142 * This function shouldn't update the joystick structure directly,
143 * but instead should call SDL_PrivateJoystick*() to deliver events
144 * and update joystick device state.
145 */
146void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
147{
148	ULONG data;
149	int i;
150
151	if(joystick->index<2)
152	{
153		data=ReadJoyPort(joystick->index);
154
155		if(data&JP_DIRECTION_MASK)
156		{
157			if(data&JPF_JOY_DOWN)
158			{
159				if(!(joystick->hwdata->joystate&JPF_JOY_DOWN))
160					SDL_PrivateJoystickAxis(joystick,0,127);
161			}
162			else if(data&JPF_JOY_UP)
163			{
164				if(!(joystick->hwdata->joystate&JPF_JOY_UP))
165					SDL_PrivateJoystickAxis(joystick,0,-127);
166			}
167			else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN))
168				SDL_PrivateJoystickAxis(joystick,0,0);
169
170			if(data&JPF_JOY_LEFT)
171			{
172				if(!(joystick->hwdata->joystate&JPF_JOY_LEFT))
173					SDL_PrivateJoystickAxis(joystick,1,-127);
174			}
175			else if(data&JPF_JOY_RIGHT)
176			{
177				if(!(joystick->hwdata->joystate&JPF_JOY_RIGHT))
178					SDL_PrivateJoystickAxis(joystick,1,127);
179			}
180			else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT))
181				SDL_PrivateJoystickAxis(joystick,1,0);
182		}
183		else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT))
184		{
185				SDL_PrivateJoystickAxis(joystick,1,0);
186		}
187		else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN))
188		{
189				SDL_PrivateJoystickAxis(joystick,0,0);
190		}
191
192		for(i=0;i<joystick->nbuttons;i++)
193		{
194			if( (data&joybut[i]) )
195			{
196				if(i==1)
197					data&=(~(joybut[2]));
198
199				if(!(joystick->hwdata->joystate&joybut[i]))
200					SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
201			}
202			else if(joystick->hwdata->joystate&joybut[i])
203				SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
204		}
205
206		joystick->hwdata->joystate=data;
207	}
208
209	return;
210}
211
212/* Function to close a joystick after use */
213void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
214{
215	if(joystick->hwdata)
216		SDL_free(joystick->hwdata);
217	return;
218}
219
220/* Function to perform any system-specific joystick related cleanup */
221
222void SDL_SYS_JoystickQuit(void)
223{
224	if(LowLevelBase)
225	{
226		CloseLibrary(LowLevelBase);
227		LowLevelBase=NULL;
228		SDL_numjoysticks=0;
229	}
230	return;
231}
232
233#endif /* SDL_JOYSTICK_AMIGA */
234