comparison src/video/riscos/SDL_riscostask.c @ 630:550bccdf04bd

Added initial support for RISC OS (thanks Peter Naulls!)
author Sam Lantinga <slouken@libsdl.org>
date Thu, 29 May 2003 04:44:13 +0000
parents
children b8d311d90021
comparison
equal deleted inserted replaced
629:3fa401bb4bb5 630:550bccdf04bd
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 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 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@devolution.com
21 */
22
23 /*
24 This file added by Alan Buckley (alan_baa@hotmail.com) to support RISCOS
25 26 March 2003
26
27 File includes routines for:
28 Setting up as a WIMP Task
29 Reading information about the current desktop
30 Storing information before a switch to full screen
31 Restoring desktop after switching to full screen
32 */
33
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "kernel.h"
38 #include "swis.h"
39
40 #include "SDL_riscostask.h"
41
42 /* RISCOS variables */
43
44 static int task_handle = 0;
45 static int wimp_version = 0;
46
47 /* RISC OS variables to help compatability with certain programs */
48 int riscos_backbuffer = 0; /* Create a back buffer in system memory for full screen mode */
49 int riscos_closeaction = 1; /* Close icon action */
50 int riscos_audiobuffer = 0; /* Audio buffer size */
51
52 static int stored_mode = -1; /* -1 when in desktop, mode number or pointer when full screen */
53
54 extern int mouseInWindow; /* Mouse is in WIMP window */
55
56 /* Local function */
57
58 static int RISCOS_GetTaskName(char *task_name);
59
60 /* Uncomment next line to copy mode changes/restores to stderr */
61 /* #define DUMP_MODE */
62 #ifdef DUMP_MODE
63 #include "stdio.h"
64 static void dump_mode()
65 {
66 fprintf(stderr, "mode %d\n", stored_mode);
67 if (stored_mode < -1 || stored_mode >= 256)
68 {
69 int blockSize = 0;
70 int *storeBlock = (int *)stored_mode;
71
72 while(blockSize < 5 || storeBlock[blockSize] != -1)
73 {
74 fprintf(stderr, " %d\n", storeBlock[blockSize++]);
75 }
76 }
77 }
78 #endif
79
80 /******************************************************************
81
82 Initialise as RISCOS Wimp task
83
84 *******************************************************************/
85
86 int RISCOS_InitTask()
87 {
88 char task_name[32];
89 _kernel_swi_regs regs;
90 int messages[4];
91
92 if (RISCOS_GetTaskName(task_name) == 0) return 0;
93
94 messages[0] = 9; /* Palette changed */
95 messages[1] = 0x400c1; /* Mode changed */
96 messages[2] = 8; /* Pre quit */
97 messages[2] = 0;
98
99 regs.r[0] = (unsigned int)360; /* Minimum version 3.6 */
100 regs.r[1] = (unsigned int)0x4b534154;
101 regs.r[2] = (unsigned int)task_name;
102 regs.r[3] = (unsigned int)messages;
103
104 if (_kernel_swi(Wimp_Initialise, &regs, &regs) == 0)
105 {
106 wimp_version = regs.r[0];
107 task_handle = regs.r[1];
108 return 1;
109 }
110
111 return 0;
112 }
113
114 /*********************************************************************
115
116 Close down application on exit.
117
118 **********************************************************************/
119
120 void RISCOS_ExitTask()
121 {
122 _kernel_swi_regs regs;
123
124 if (stored_mode == -1)
125 {
126 /* Ensure cursor is put back to standard pointer shape if
127 we have been running in a window */
128 _kernel_osbyte(106,1,0);
129 }
130
131 /* Ensure we end up back in the wimp */
132 RISCOS_RestoreWimpMode();
133
134 /* Neatly exit the task */
135 regs.r[0] = task_handle;
136 regs.r[1] = (unsigned int)0x4b534154;
137 _kernel_swi(Wimp_CloseDown, &regs, &regs);
138 task_handle = 0;
139 }
140
141 /**************************************************************************
142
143 Get the name of the task for the desktop.
144
145 Param: task_name - name of task 32 characters.
146
147 Returns: 1 is successful, otherwise 0
148
149 Notes: Works by getting using OS_GetEnv to get the command line
150 used to run the program and then parsing a name from it
151 as follows.
152
153 1. Use name after final period if not !RunImage
154 2. If name is !RunImage then process item before the period
155 in front of !RunImage.
156 3. If directory name use that
157 4. if in form <XXX$Dir> use the XXX.
158
159 Finally once this value has been retrieved use it unless
160 there is a variable set up in the form SDL$<name>$TaskName
161 in which case the value of this variable will be used.
162
163 Now also gets other riscos configuration varibles
164 SDL$<name>$BackBuffer - set to 1 to use a system memory backbuffer in fullscreen mode
165 so updates wait until a call to SDL_UpdateRects. (default 0)
166 This is required for programmes where they have assumed this is
167 always the case which is contrary to the documentation.
168 SDL$<name>$CloseAction
169 0 Don't show close icon
170 1 Show close icon
171
172 SDL$<name>$AudioBuffer - set to number of samples to buffer
173 in advance. Will default to a minimum of 1024 or twice
174 amount requested by program whichever is largest.
175 If not specified default is amount for 10 csecs.
176 Time that will be pre-buffered can be calculated as
177 sample to buffer * 1000 / freq milliseconds.
178
179 ***************************************************************************/
180
181 int RISCOS_GetTaskName(char *task_name)
182 {
183 _kernel_swi_regs regs;
184
185 task_name[0] = 0;
186
187 /* Figure out a sensible task name */
188 if (_kernel_swi(OS_GetEnv, &regs, &regs) == 0)
189 {
190 char *command_line = (char *)regs.r[0];
191 char *buffer = malloc(strlen(command_line)+1);
192 char *env_var;
193 char *p;
194
195 strcpy(buffer, command_line);
196 p = strchr(buffer, ' ');
197 if (p) *p = 0;
198 p = strrchr(buffer, '.');
199 if (p == 0) p = buffer;
200 if (stricmp(p+1,"!RunImage") == 0)
201 {
202 *p = 0;
203 p = strrchr(buffer, '.');
204 if (p == 0) p = buffer;
205 }
206 if (*p == '.') p++;
207 if (*p == '!') p++; /* Skip "!" at beginning of application directories */
208
209 if (*p == '<')
210 {
211 // Probably in the form <appname$Dir>
212 char *q = strchr(p, '$');
213 if (q == 0) q = strchr(p,'>'); /* Use variable name if not */
214 if (q) *q = 0;
215 p++; /* Move over the < */
216 }
217
218 if (*p)
219 {
220 /* Read variables that effect the RISCOS SDL engine for this task */
221 env_var = malloc(strlen(p) + 18); /* 18 is larger than the biggest variable name */
222 if (env_var)
223 {
224 char *env_val;
225
226 /* See if a variable of form SDL$<dirname>$TaskName exists */
227
228 strcpy(env_var, "SDL$");
229 strcat(env_var, p);
230 strcat(env_var, "$TaskName");
231
232 env_val = getenv(env_var);
233 if (env_val) strncpy(task_name, env_val, 31);
234
235 strcpy(env_var, "SDL$");
236 strcat(env_var, p);
237 strcat(env_var, "$BackBuffer");
238
239 env_val = getenv(env_var);
240 if (env_val && strcmp(env_val,"1") == 0) riscos_backbuffer = 1;
241
242 strcpy(env_var, "SDL$");
243 strcat(env_var, p);
244 strcat(env_var, "$CloseAction");
245
246 env_val = getenv(env_var);
247 if (env_val && strcmp(env_val,"0") == 0) riscos_closeaction = 0;
248
249 strcpy(env_var, "SDL$");
250 strcat(env_var, p);
251 strcat(env_var, "$AudioBuffer");
252
253 env_val = getenv(env_var);
254 riscos_audiobuffer = atoi(env_val);
255
256 free(env_var);
257 }
258
259 if (task_name[0] == 0) strncpy(task_name, p, 31);
260 task_name[31] = 0;
261 }
262
263 free(buffer);
264 }
265
266 if (task_name[0] == 0) strcpy(task_name, "SDL Task");
267
268 return 1;
269 }
270
271 /*****************************************************************
272
273 Store the current desktop screen mode if we are in the desktop.
274
275 ******************************************************************/
276
277 void RISCOS_StoreWimpMode()
278 {
279 _kernel_swi_regs regs;
280
281 /* Don't store if in full screen mode */
282 if (stored_mode != -1) return;
283
284 regs.r[0] = 1;
285 _kernel_swi(OS_ScreenMode, &regs, &regs);
286 if (regs.r[1] >= 0 && regs.r[1] < 256) stored_mode = regs.r[1];
287 else
288 {
289 int blockSize = 0;
290 int *retBlock = (int *)regs.r[1];
291 int *storeBlock;
292 int j;
293
294 while(blockSize < 5 || retBlock[blockSize] != -1) blockSize++;
295 blockSize++;
296 storeBlock = (int *)malloc(blockSize * sizeof(int));
297 retBlock = (int *)regs.r[1];
298 for ( j = 0; j < blockSize; j++)
299 storeBlock[j] = retBlock[j];
300
301 stored_mode = (int)storeBlock;
302 }
303 #if DUMP_MODE
304 fprintf(stderr, "Stored "); dump_mode();
305 #endif
306 }
307
308 /*****************************************************************
309
310 Restore desktop screen mode if we are in full screen mode.
311
312 *****************************************************************/
313
314 void RISCOS_RestoreWimpMode()
315 {
316 _kernel_swi_regs regs;
317
318 /* Only need to restore if we are in full screen mode */
319 if (stored_mode == -1) return;
320
321 #if DUMP_MODE
322 fprintf(stderr, "Restored"); dump_mode();
323 #endif
324
325 regs.r[0] = stored_mode;
326 _kernel_swi(Wimp_SetMode, &regs, &regs);
327 if (stored_mode < 0 || stored_mode > 256)
328 {
329 free((int *)stored_mode);
330 }
331 stored_mode = -1;
332
333 /* Flush keyboard buffer to dump the keystrokes we've already polled */
334 regs.r[0] = 21;
335 regs.r[1] = 0; /* Keyboard buffer number */
336 _kernel_swi(OS_Byte, &regs, &regs);
337
338 mouseInWindow = 0;
339
340 }
341
342 /*********************************************************************
343
344 Get version of Wimp running when task was initialised.
345
346 *********************************************************************/
347
348 int RISCOS_GetWimpVersion()
349 {
350 return wimp_version;
351 }
352
353 int RISCOS_GetTaskHandle()
354 {
355 return task_handle;
356 }