Mercurial > sdl-ios-xcode
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, ®s, ®s) == 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, ®s, ®s); | |
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, ®s, ®s) == 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, ®s, ®s); | |
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, ®s, ®s); | |
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, ®s, ®s); | |
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 } |