diff options
author | Franklin Wei <git@fwei.tk> | 2017-01-21 15:18:31 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2017-12-23 21:01:26 -0500 |
commit | a855d6202536ff28e5aae4f22a0f31d8f5b325d0 (patch) | |
tree | 8c75f224dd64ed360505afa8843d016b0d75000b /apps/plugins/sdl/src/video/riscos | |
parent | 01c6dcf6c7b9bb1ad2fa0450f99bacc5f3d3e04b (diff) | |
download | rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.tar.gz rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.zip |
Port of Duke Nukem 3D
This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL
for Rockbox.
Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9
Diffstat (limited to 'apps/plugins/sdl/src/video/riscos')
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S | 116 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c | 777 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c | 549 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosevents_c.h | 34 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c | 371 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosmouse_c.h | 44 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscossprite.c | 265 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscostask.c | 350 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscostask.h | 39 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.c | 316 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.h | 62 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c | 330 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c | 501 |
13 files changed, 3754 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S b/apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S new file mode 100644 index 0000000000..fae32f84d6 --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S | |||
@@ -0,0 +1,116 @@ | |||
1 | ; | ||
2 | ; SDL - Simple DirectMedia Layer | ||
3 | ; Copyright (C) 1997-2012 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@libsdl.org | ||
21 | ; | ||
22 | ; Assembler routines for RISC OS display | ||
23 | ; | ||
24 | |||
25 | AREA |C$$CODE| | ||
26 | |||
27 | EXPORT |RISCOS_Put32| | ||
28 | |||
29 | ; Display 32bpp to 32bpp, 1:1 | ||
30 | ; | ||
31 | ; Code provided by Adrain Lees | ||
32 | ; | ||
33 | ; entry a1 -> destination | ||
34 | ; a2 = dest width in pixels | ||
35 | ; a3 = dest line length in bytes | ||
36 | ; a4 = dest height in scanlines | ||
37 | ; arg5 -> source | ||
38 | ; arg6 = byte offset from end of source line to start of next | ||
39 | |||
40 | Arg5 * 10*4 | ||
41 | Arg6 * Arg5+4 | ||
42 | |||
43 | RISCOS_Put32 ROUT | ||
44 | STMFD sp!,{a2,v1-v6,sl,fp,lr} | ||
45 | LDR ip,[sp,#Arg5] | ||
46 | MOV lr,a1 | ||
47 | B ucp64lp | ||
48 | |||
49 | 00 ;tail strip of 1-15 pixels | ||
50 | |||
51 | LDR v1,[ip],#4 | ||
52 | 01 SUBS a2,a2,#1 | ||
53 | STR v1,[lr],#4 | ||
54 | LDRHI v1,[ip],#4 | ||
55 | BHI %01 | ||
56 | B %02 | ||
57 | |||
58 | ucp64end ADDS a2,a2,#16 | ||
59 | BNE %00 | ||
60 | |||
61 | 02 SUBS a4,a4,#1 ;height-- | ||
62 | LDRHI v1,[sp,#Arg6] | ||
63 | LDRHI a2,[sp] ;reload width | ||
64 | BLS %03 | ||
65 | |||
66 | ;move to start of next scanline | ||
67 | |||
68 | ADD lr,a1,a3 | ||
69 | ADD a1,a1,a3 | ||
70 | ADD ip,ip,v1 | ||
71 | |||
72 | ucp64lp SUBS a2,a2,#16 | ||
73 | BLO ucp64end | ||
74 | |||
75 | PLD [ip,#64] | ||
76 | |||
77 | LDR v1,[ip],#4 | ||
78 | LDR v2,[ip],#4 | ||
79 | LDR v3,[ip],#4 | ||
80 | LDR v4,[ip],#4 | ||
81 | LDR v5,[ip],#4 | ||
82 | LDR v6,[ip],#4 | ||
83 | LDR sl,[ip],#4 | ||
84 | LDR fp,[ip],#4 | ||
85 | STR v1,[lr],#4 | ||
86 | STR v2,[lr],#4 | ||
87 | STR v3,[lr],#4 | ||
88 | STR v4,[lr],#4 | ||
89 | STR v5,[lr],#4 | ||
90 | STR v6,[lr],#4 | ||
91 | STR sl,[lr],#4 | ||
92 | STR fp,[lr],#4 | ||
93 | |||
94 | PLD [ip,#64] | ||
95 | |||
96 | LDR v1,[ip],#4 | ||
97 | LDR v2,[ip],#4 | ||
98 | LDR v3,[ip],#4 | ||
99 | LDR v4,[ip],#4 | ||
100 | LDR v5,[ip],#4 | ||
101 | LDR v6,[ip],#4 | ||
102 | LDR sl,[ip],#4 | ||
103 | LDR fp,[ip],#4 | ||
104 | STR v1,[lr],#4 | ||
105 | STR v2,[lr],#4 | ||
106 | STR v3,[lr],#4 | ||
107 | STR v4,[lr],#4 | ||
108 | STR v5,[lr],#4 | ||
109 | STR v6,[lr],#4 | ||
110 | STR sl,[lr],#4 | ||
111 | STR fp,[lr],#4 | ||
112 | |||
113 | B ucp64lp | ||
114 | |||
115 | 03 LDMFD sp!,{a2,v1-v6,sl,fp,pc} | ||
116 | |||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c b/apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c new file mode 100644 index 0000000000..b8c3cf786b --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c | |||
@@ -0,0 +1,777 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 27 March 2003 | ||
27 | |||
28 | Implements RISC OS full screen display. | ||
29 | */ | ||
30 | |||
31 | #include "SDL_video.h" | ||
32 | #include "SDL_mouse.h" | ||
33 | #include "../SDL_sysvideo.h" | ||
34 | #include "../SDL_pixels_c.h" | ||
35 | #include "../../events/SDL_events_c.h" | ||
36 | |||
37 | #include "SDL_riscostask.h" | ||
38 | #include "SDL_riscosvideo.h" | ||
39 | #include "SDL_riscosevents_c.h" | ||
40 | #include "SDL_riscosmouse_c.h" | ||
41 | |||
42 | #include "kernel.h" | ||
43 | #include "swis.h" | ||
44 | #include "unixlib/os.h" | ||
45 | #include "unixlib/local.h" | ||
46 | |||
47 | /* Private structures */ | ||
48 | typedef struct tagScreenModeBlock | ||
49 | { | ||
50 | int flags; // mode selector flags, bit 0 = 1, bit 1-7 format specifier, 8-31 reserved | ||
51 | int x_pixels; | ||
52 | int y_pixels; | ||
53 | int pixel_depth; // 2^pixel_depth = bpp,i.e. 0 = 1, 1 = 2, 4 = 16, 5 = 32 | ||
54 | int frame_rate; // -1 use first match | ||
55 | int mode_vars[5]; // array of index, value pairs terminated by -1 | ||
56 | } SCREENMODEBLOCK; | ||
57 | |||
58 | |||
59 | /* Helper functions */ | ||
60 | void FULLSCREEN_SetDeviceMode(_THIS); | ||
61 | int FULLSCREEN_SetMode(int width, int height, int bpp); | ||
62 | void FULLSCREEN_SetupBanks(_THIS); | ||
63 | |||
64 | /* SDL video device functions for fullscreen mode */ | ||
65 | static int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | ||
66 | static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface); | ||
67 | void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon); | ||
68 | extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info); | ||
69 | |||
70 | /* UpdateRects variants */ | ||
71 | static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | ||
72 | static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects); | ||
73 | static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects); | ||
74 | static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects); | ||
75 | static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects); | ||
76 | static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects); | ||
77 | |||
78 | /* Local helper functions */ | ||
79 | static int cmpmodes(const void *va, const void *vb); | ||
80 | static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h); | ||
81 | void FULLSCREEN_SetWriteBank(int bank); | ||
82 | void FULLSCREEN_SetDisplayBank(int bank); | ||
83 | static void FULLSCREEN_DisableEscape(); | ||
84 | static void FULLSCREEN_EnableEscape(); | ||
85 | void FULLSCREEN_BuildModeList(_THIS); | ||
86 | |||
87 | /* Following variable is set up in riskosTask.c */ | ||
88 | extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */ | ||
89 | |||
90 | /* Following is used to create a sprite back buffer */ | ||
91 | extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp); | ||
92 | |||
93 | /* Fast assembler copy */ | ||
94 | extern void RISCOS_Put32(void *to, int pixels, int pitch, int rows, void *from, int src_skip_bytes); | ||
95 | |||
96 | SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, | ||
97 | int width, int height, int bpp, Uint32 flags) | ||
98 | { | ||
99 | _kernel_swi_regs regs; | ||
100 | Uint32 Rmask = 0; | ||
101 | Uint32 Gmask = 0; | ||
102 | Uint32 Bmask = 0; | ||
103 | int create_back_buffer = riscos_backbuffer; | ||
104 | |||
105 | switch(bpp) | ||
106 | { | ||
107 | case 8: | ||
108 | flags |= SDL_HWPALETTE; | ||
109 | break; | ||
110 | |||
111 | case 15: | ||
112 | case 16: | ||
113 | Bmask = 0x00007c00; | ||
114 | Gmask = 0x000003e0; | ||
115 | Rmask = 0x0000001f; | ||
116 | break; | ||
117 | |||
118 | case 32: | ||
119 | Bmask = 0x00ff0000; | ||
120 | Gmask = 0x0000ff00; | ||
121 | Rmask = 0x000000ff; | ||
122 | break; | ||
123 | |||
124 | default: | ||
125 | SDL_SetError("Pixel depth not supported"); | ||
126 | return NULL; | ||
127 | break; | ||
128 | } | ||
129 | |||
130 | if (FULLSCREEN_SetMode(width, height, bpp) == 0) | ||
131 | { | ||
132 | SDL_SetError("Couldn't set requested mode"); | ||
133 | return (NULL); | ||
134 | } | ||
135 | |||
136 | /* printf("Setting mode %dx%d\n", width, height); */ | ||
137 | |||
138 | /* Allocate the new pixel format for the screen */ | ||
139 | if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) { | ||
140 | RISCOS_RestoreWimpMode(); | ||
141 | SDL_SetError("Couldn't allocate new pixel format for requested mode"); | ||
142 | return(NULL); | ||
143 | } | ||
144 | |||
145 | /* Set up the new mode framebuffer */ | ||
146 | current->w = width; | ||
147 | this->hidden->height = current->h = height; | ||
148 | |||
149 | regs.r[0] = -1; /* -1 for current screen mode */ | ||
150 | |||
151 | /* Get screen width in bytes */ | ||
152 | regs.r[1] = 6; // Screen Width in bytes | ||
153 | _kernel_swi(OS_ReadModeVariable, ®s, ®s); | ||
154 | |||
155 | current->pitch = regs.r[2]; | ||
156 | |||
157 | if (flags & SDL_DOUBLEBUF) | ||
158 | { | ||
159 | regs.r[0] = 2; /* Screen area */ | ||
160 | _kernel_swi(OS_ReadDynamicArea, ®s, ®s); | ||
161 | |||
162 | /* Reg 1 has amount of memory currently used for display */ | ||
163 | regs.r[0] = 2; /* Screen area */ | ||
164 | regs.r[1] = (current->pitch * height * 2) - regs.r[1]; | ||
165 | if (_kernel_swi(OS_ChangeDynamicArea, ®s, ®s) != NULL) | ||
166 | { | ||
167 | /* Can't allocate enough screen memory for double buffer */ | ||
168 | flags &= ~SDL_DOUBLEBUF; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | SDL_PREALLOC; | ||
173 | |||
174 | |||
175 | /* Need to set display banks here for double buffering */ | ||
176 | if (flags & SDL_DOUBLEBUF) | ||
177 | { | ||
178 | FULLSCREEN_SetWriteBank(0); | ||
179 | FULLSCREEN_SetDisplayBank(1); | ||
180 | |||
181 | create_back_buffer = 0; /* Don't need a back buffer for a double buffered display */ | ||
182 | } | ||
183 | |||
184 | FULLSCREEN_SetupBanks(this); | ||
185 | |||
186 | if (create_back_buffer) | ||
187 | { | ||
188 | /* If not double buffered we may need to create a memory | ||
189 | ** back buffer to simulate processing on other OSes. | ||
190 | ** This is turned on by setting the enviromental variable | ||
191 | ** SDL$<name>$BackBuffer >= 1 | ||
192 | */ | ||
193 | if (riscos_backbuffer == 3) | ||
194 | this->hidden->bank[0] = WIMP_CreateBuffer(width, height, bpp); | ||
195 | else | ||
196 | this->hidden->bank[0] = SDL_malloc(height * current->pitch); | ||
197 | if (this->hidden->bank[0] == 0) | ||
198 | { | ||
199 | RISCOS_RestoreWimpMode(); | ||
200 | SDL_SetError("Couldnt allocate memory for back buffer"); | ||
201 | return (NULL); | ||
202 | } | ||
203 | /* Surface updated in programs is now a software surface */ | ||
204 | current->flags &= ~SDL_HWSURFACE; | ||
205 | } | ||
206 | |||
207 | /* Store address of allocated screen bank to be freed later */ | ||
208 | if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank); | ||
209 | if (create_back_buffer) | ||
210 | { | ||
211 | this->hidden->alloc_bank = this->hidden->bank[0]; | ||
212 | if (riscos_backbuffer == 3) | ||
213 | { | ||
214 | this->hidden->bank[0] += 60; /* Start of sprite data */ | ||
215 | if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ | ||
216 | } | ||
217 | } else | ||
218 | this->hidden->alloc_bank = 0; | ||
219 | |||
220 | // Clear both banks to black | ||
221 | SDL_memset(this->hidden->bank[0], 0, height * current->pitch); | ||
222 | SDL_memset(this->hidden->bank[1], 0, height * current->pitch); | ||
223 | |||
224 | this->hidden->current_bank = 0; | ||
225 | current->pixels = this->hidden->bank[0]; | ||
226 | |||
227 | /* Have to set the screen here, so SetDeviceMode will pick it up */ | ||
228 | this->screen = current; | ||
229 | |||
230 | /* Reset device functions for the wimp */ | ||
231 | FULLSCREEN_SetDeviceMode(this); | ||
232 | |||
233 | /* FULLSCREEN_DisableEscape(); */ | ||
234 | |||
235 | /* We're done */ | ||
236 | return(current); | ||
237 | } | ||
238 | |||
239 | /* Reset any device functions that have been changed because we have run in WIMP mode */ | ||
240 | void FULLSCREEN_SetDeviceMode(_THIS) | ||
241 | { | ||
242 | /* Update rects is different if we have a backbuffer */ | ||
243 | |||
244 | if (riscos_backbuffer && (this->screen->flags & SDL_DOUBLEBUF) == 0) | ||
245 | { | ||
246 | switch(riscos_backbuffer) | ||
247 | { | ||
248 | case 2: /* ARM code full word copy */ | ||
249 | switch(this->screen->format->BytesPerPixel) | ||
250 | { | ||
251 | case 1: /* 8bpp modes */ | ||
252 | this->UpdateRects = FULLSCREEN_UpdateRects8bpp; | ||
253 | break; | ||
254 | case 2: /* 15/16bpp modes */ | ||
255 | this->UpdateRects = FULLSCREEN_UpdateRects16bpp; | ||
256 | break; | ||
257 | case 4: /* 32 bpp modes */ | ||
258 | this->UpdateRects = FULLSCREEN_UpdateRects32bpp; | ||
259 | break; | ||
260 | |||
261 | default: /* Just default to the memcpy routine */ | ||
262 | this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy; | ||
263 | break; | ||
264 | } | ||
265 | break; | ||
266 | |||
267 | case 3: /* Use OS sprite plot routine */ | ||
268 | this->UpdateRects = FULLSCREEN_UpdateRectsOS; | ||
269 | break; | ||
270 | |||
271 | default: /* Old but safe memcpy */ | ||
272 | this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy; | ||
273 | break; | ||
274 | } | ||
275 | } else | ||
276 | this->UpdateRects = FULLSCREEN_UpdateRects; /* Default do nothing implementation */ | ||
277 | |||
278 | this->SetColors = FULLSCREEN_SetColors; | ||
279 | |||
280 | this->FlipHWSurface = FULLSCREEN_FlipHWSurface; | ||
281 | |||
282 | this->SetCaption = FULLSCREEN_SetWMCaption; | ||
283 | this->SetIcon = NULL; | ||
284 | this->IconifyWindow = NULL; | ||
285 | |||
286 | this->ShowWMCursor = RISCOS_ShowWMCursor; | ||
287 | this->WarpWMCursor = FULLSCREEN_WarpWMCursor; | ||
288 | |||
289 | this->PumpEvents = FULLSCREEN_PumpEvents; | ||
290 | } | ||
291 | |||
292 | /* Query for the list of available video modes */ | ||
293 | void FULLSCREEN_BuildModeList(_THIS) | ||
294 | { | ||
295 | _kernel_swi_regs regs; | ||
296 | char *enumInfo = NULL; | ||
297 | char *enum_ptr; | ||
298 | int *blockInfo; | ||
299 | int j; | ||
300 | int num_modes; | ||
301 | |||
302 | /* Find out how much space we need */ | ||
303 | regs.r[0] = 2; /* Reason code */ | ||
304 | regs.r[2] = 0; /* Number of modes to skip */ | ||
305 | regs.r[6] = 0; /* pointer to block or 0 for count */ | ||
306 | regs.r[7] = 0; /* Size of block in bytes */ | ||
307 | _kernel_swi(OS_ScreenMode, ®s, ®s); | ||
308 | |||
309 | num_modes = -regs.r[2]; | ||
310 | |||
311 | /* Video memory should be in r[5] */ | ||
312 | this->info.video_mem = regs.r[5]/1024; | ||
313 | |||
314 | enumInfo = (unsigned char *)SDL_malloc(-regs.r[7]); | ||
315 | if (enumInfo == NULL) | ||
316 | { | ||
317 | SDL_OutOfMemory(); | ||
318 | return; | ||
319 | } | ||
320 | /* Read mode information into block */ | ||
321 | regs.r[2] = 0; | ||
322 | regs.r[6] = (int)enumInfo; | ||
323 | regs.r[7] = -regs.r[7]; | ||
324 | _kernel_swi(OS_ScreenMode, ®s, ®s); | ||
325 | |||
326 | enum_ptr = enumInfo; | ||
327 | |||
328 | for (j =0; j < num_modes;j++) | ||
329 | { | ||
330 | blockInfo = (int *)enum_ptr; | ||
331 | if ((blockInfo[1] & 255) == 1) /* We understand this format */ | ||
332 | { | ||
333 | switch(blockInfo[4]) | ||
334 | { | ||
335 | case 3: /* 8 bits per pixel */ | ||
336 | FULLSCREEN_AddMode(this, 8, blockInfo[2], blockInfo[3]); | ||
337 | break; | ||
338 | case 4: /* 15 bits per pixel */ | ||
339 | FULLSCREEN_AddMode(this, 15, blockInfo[2], blockInfo[3]); | ||
340 | break; | ||
341 | case 5: /* 32 bits per pixel */ | ||
342 | FULLSCREEN_AddMode(this, 32, blockInfo[2], blockInfo[3]); | ||
343 | break; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | enum_ptr += blockInfo[0]; | ||
348 | } | ||
349 | |||
350 | SDL_free(enumInfo); | ||
351 | |||
352 | /* Sort the mode lists */ | ||
353 | for ( j=0; j<NUM_MODELISTS; ++j ) { | ||
354 | if ( SDL_nummodes[j] > 0 ) { | ||
355 | SDL_qsort(SDL_modelist[j], SDL_nummodes[j], sizeof *SDL_modelist[j], cmpmodes); | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface) | ||
361 | { | ||
362 | _kernel_swi_regs regs; | ||
363 | regs.r[0] = 19; | ||
364 | |||
365 | FULLSCREEN_SetDisplayBank(this->hidden->current_bank); | ||
366 | this->hidden->current_bank ^= 1; | ||
367 | FULLSCREEN_SetWriteBank(this->hidden->current_bank); | ||
368 | surface->pixels = this->hidden->bank[this->hidden->current_bank]; | ||
369 | |||
370 | /* Wait for Vsync */ | ||
371 | _kernel_swi(OS_Byte, ®s, ®s); | ||
372 | |||
373 | return(0); | ||
374 | } | ||
375 | |||
376 | /* Nothing to do if we are writing direct to hardware */ | ||
377 | static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects) | ||
378 | { | ||
379 | } | ||
380 | |||
381 | /* Safe but slower Memory copy from our allocated back buffer */ | ||
382 | static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects) | ||
383 | { | ||
384 | int j; | ||
385 | char *to, *from; | ||
386 | int pitch = this->screen->pitch; | ||
387 | int row; | ||
388 | int xmult = this->screen->format->BytesPerPixel; | ||
389 | for (j = 0; j < numrects; j++) | ||
390 | { | ||
391 | from = this->hidden->bank[0] + rects->x * xmult + rects->y * pitch; | ||
392 | to = this->hidden->bank[1] + rects->x * xmult + rects->y * pitch; | ||
393 | for (row = 0; row < rects->h; row++) | ||
394 | { | ||
395 | SDL_memcpy(to, from, rects->w * xmult); | ||
396 | from += pitch; | ||
397 | to += pitch; | ||
398 | } | ||
399 | rects++; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | /* Use optimized assembler memory copy. Deliberately copies extra columns if | ||
404 | necessary to ensure the rectangle is word aligned. */ | ||
405 | static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects) | ||
406 | { | ||
407 | int j; | ||
408 | char *to, *from; | ||
409 | int pitch = this->screen->pitch; | ||
410 | int width_bytes; | ||
411 | int src_skip_bytes; | ||
412 | |||
413 | for (j = 0; j < numrects; j++) | ||
414 | { | ||
415 | from = this->hidden->bank[0] + rects->x + rects->y * pitch; | ||
416 | to = this->hidden->bank[1] + rects->x + rects->y * pitch; | ||
417 | width_bytes = rects->w; | ||
418 | if ((int)from & 3) | ||
419 | { | ||
420 | int extra = ((int)from & 3); | ||
421 | from -= extra; | ||
422 | to -= extra; | ||
423 | width_bytes += extra; | ||
424 | } | ||
425 | if (width_bytes & 3) width_bytes += 4 - (width_bytes & 3); | ||
426 | src_skip_bytes = pitch - width_bytes; | ||
427 | |||
428 | RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes); | ||
429 | rects++; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | /* Use optimized assembler memory copy. Deliberately copies extra columns if | ||
434 | necessary to ensure the rectangle is word aligned. */ | ||
435 | static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects) | ||
436 | { | ||
437 | int j; | ||
438 | char *to, *from; | ||
439 | int pitch = this->screen->pitch; | ||
440 | int width_bytes; | ||
441 | int src_skip_bytes; | ||
442 | |||
443 | for (j = 0; j < numrects; j++) | ||
444 | { | ||
445 | from = this->hidden->bank[0] + (rects->x << 1) + rects->y * pitch; | ||
446 | to = this->hidden->bank[1] + (rects->x << 1) + rects->y * pitch; | ||
447 | width_bytes = (((int)rects->w) << 1); | ||
448 | if ((int)from & 3) | ||
449 | { | ||
450 | from -= 2; | ||
451 | to -= 2; | ||
452 | width_bytes += 2; | ||
453 | } | ||
454 | if (width_bytes & 3) width_bytes += 2; | ||
455 | src_skip_bytes = pitch - width_bytes; | ||
456 | |||
457 | RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes); | ||
458 | rects++; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | /* Use optimized assembler memory copy. 32 bpp modes are always word aligned */ | ||
463 | static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects) | ||
464 | { | ||
465 | int j; | ||
466 | char *to, *from; | ||
467 | int pitch = this->screen->pitch; | ||
468 | int width; | ||
469 | |||
470 | for (j = 0; j < numrects; j++) | ||
471 | { | ||
472 | from = this->hidden->bank[0] + (rects->x << 2) + rects->y * pitch; | ||
473 | to = this->hidden->bank[1] + (rects->x << 2) + rects->y * pitch; | ||
474 | width = (int)rects->w ; | ||
475 | |||
476 | RISCOS_Put32(to, width, pitch, (int)rects->h, from, pitch - (width << 2)); | ||
477 | rects++; | ||
478 | } | ||
479 | } | ||
480 | |||
481 | /* Use operating system sprite plots. Currently this is much slower than the | ||
482 | other variants however accelerated sprite plotting can be seen on the horizon | ||
483 | so this prepares for it. */ | ||
484 | static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects) | ||
485 | { | ||
486 | _kernel_swi_regs regs; | ||
487 | _kernel_oserror *err; | ||
488 | int j; | ||
489 | int y; | ||
490 | |||
491 | regs.r[0] = 28 + 512; | ||
492 | regs.r[1] = (unsigned int)this->hidden->alloc_bank; | ||
493 | regs.r[2] = (unsigned int)this->hidden->alloc_bank+16; | ||
494 | regs.r[5] = 0; | ||
495 | |||
496 | for (j = 0; j < numrects; j++) | ||
497 | { | ||
498 | y = this->screen->h - rects->y; /* top of clipping region */ | ||
499 | _kernel_oswrch(24); /* Set graphics clip region */ | ||
500 | _kernel_oswrch((rects->x << this->hidden->xeig) & 0xFF); /* left */ | ||
501 | _kernel_oswrch(((rects->x << this->hidden->xeig) >> 8) & 0xFF); | ||
502 | _kernel_oswrch(((y - rects->h) << this->hidden->yeig) & 0xFF); /* bottom */ | ||
503 | _kernel_oswrch((((y - rects->h) << this->hidden->yeig)>> 8) & 0xFF); | ||
504 | _kernel_oswrch(((rects->x + rects->w - 1) << this->hidden->xeig) & 0xFF); /* right */ | ||
505 | _kernel_oswrch((((rects->x + rects->w - 1)<< this->hidden->xeig) >> 8) & 0xFF); | ||
506 | _kernel_oswrch(((y-1) << this->hidden->yeig) & 0xFF); /* top */ | ||
507 | _kernel_oswrch((((y-1) << this->hidden->yeig) >> 8) & 0xFF); | ||
508 | |||
509 | regs.r[3] = 0; | ||
510 | regs.r[4] = 0; | ||
511 | |||
512 | if ((err = _kernel_swi(OS_SpriteOp, ®s, ®s)) != 0) | ||
513 | { | ||
514 | printf("OS_SpriteOp failed \n%s\n",err->errmess); | ||
515 | } | ||
516 | |||
517 | rects++; | ||
518 | |||
519 | /* Reset to full screen clipping */ | ||
520 | _kernel_oswrch(24); /* Set graphics clip region */ | ||
521 | _kernel_oswrch(0); /* left */ | ||
522 | _kernel_oswrch(0); | ||
523 | _kernel_oswrch(0); /* bottom */ | ||
524 | _kernel_oswrch(0); | ||
525 | _kernel_oswrch(((this->screen->w-1) << this->hidden->xeig) & 0xFF); /* right */ | ||
526 | _kernel_oswrch((((this->screen->w-1) << this->hidden->xeig) >> 8) & 0xFF); | ||
527 | _kernel_oswrch(((this->screen->h-1) << this->hidden->yeig) & 0xFF); /* top */ | ||
528 | _kernel_oswrch((((this->screen->h-1) << this->hidden->yeig) >> 8) & 0xFF); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | |||
533 | int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | ||
534 | { | ||
535 | _kernel_swi_regs regs; | ||
536 | int palette[256]; | ||
537 | |||
538 | regs.r[0] = -1; | ||
539 | regs.r[1] = -1; | ||
540 | regs.r[2] = (int)palette; | ||
541 | regs.r[3] = 1024; | ||
542 | regs.r[4] = 0; | ||
543 | _kernel_swi(ColourTrans_ReadPalette, ®s, ®s); | ||
544 | |||
545 | while(ncolors--) | ||
546 | { | ||
547 | palette[firstcolor] = ((colors->b) << 24) | ((colors->g) << 16) | ((colors->r) << 8); | ||
548 | firstcolor++; | ||
549 | colors++; | ||
550 | } | ||
551 | |||
552 | regs.r[0] = -1; | ||
553 | regs.r[1] = -1; | ||
554 | regs.r[2] = (int)palette; | ||
555 | regs.r[3] = 0; | ||
556 | regs.r[4] = 0; | ||
557 | _kernel_swi(ColourTrans_WritePalette, ®s, ®s); | ||
558 | |||
559 | return(1); | ||
560 | } | ||
561 | |||
562 | |||
563 | static int cmpmodes(const void *va, const void *vb) | ||
564 | { | ||
565 | SDL_Rect *a = *(SDL_Rect **)va; | ||
566 | SDL_Rect *b = *(SDL_Rect **)vb; | ||
567 | if(a->w == b->w) | ||
568 | return b->h - a->h; | ||
569 | else | ||
570 | return b->w - a->w; | ||
571 | } | ||
572 | |||
573 | static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h) | ||
574 | { | ||
575 | SDL_Rect *mode; | ||
576 | int i, index; | ||
577 | int next_mode; | ||
578 | |||
579 | /* Check to see if we already have this mode */ | ||
580 | if ( bpp < 8 ) { /* Not supported */ | ||
581 | return(0); | ||
582 | } | ||
583 | index = ((bpp+7)/8)-1; | ||
584 | for ( i=0; i<SDL_nummodes[index]; ++i ) { | ||
585 | mode = SDL_modelist[index][i]; | ||
586 | if ( (mode->w == w) && (mode->h == h) ) { | ||
587 | return(0); | ||
588 | } | ||
589 | } | ||
590 | |||
591 | /* Set up the new video mode rectangle */ | ||
592 | mode = (SDL_Rect *)SDL_malloc(sizeof *mode); | ||
593 | if ( mode == NULL ) { | ||
594 | SDL_OutOfMemory(); | ||
595 | return(-1); | ||
596 | } | ||
597 | mode->x = 0; | ||
598 | mode->y = 0; | ||
599 | mode->w = w; | ||
600 | mode->h = h; | ||
601 | |||
602 | /* Allocate the new list of modes, and fill in the new mode */ | ||
603 | next_mode = SDL_nummodes[index]; | ||
604 | SDL_modelist[index] = (SDL_Rect **) | ||
605 | SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); | ||
606 | if ( SDL_modelist[index] == NULL ) { | ||
607 | SDL_OutOfMemory(); | ||
608 | SDL_nummodes[index] = 0; | ||
609 | SDL_free(mode); | ||
610 | return(-1); | ||
611 | } | ||
612 | SDL_modelist[index][next_mode] = mode; | ||
613 | SDL_modelist[index][next_mode+1] = NULL; | ||
614 | SDL_nummodes[index]++; | ||
615 | |||
616 | return(0); | ||
617 | } | ||
618 | |||
619 | void FULLSCREEN_SetWriteBank(int bank) | ||
620 | { | ||
621 | _kernel_swi_regs regs; | ||
622 | regs.r[0] = 112; | ||
623 | regs.r[1] = bank+1; | ||
624 | _kernel_swi(OS_Byte, ®s, ®s); | ||
625 | } | ||
626 | |||
627 | void FULLSCREEN_SetDisplayBank(int bank) | ||
628 | { | ||
629 | _kernel_swi_regs regs; | ||
630 | regs.r[0] = 113; | ||
631 | regs.r[1] = bank+1; | ||
632 | _kernel_swi(OS_Byte, ®s, ®s); | ||
633 | } | ||
634 | |||
635 | |||
636 | /** Disable special escape key processing */ | ||
637 | static void FULLSCREEN_DisableEscape() | ||
638 | { | ||
639 | _kernel_swi_regs regs; | ||
640 | regs.r[0] = 229; | ||
641 | regs.r[1] = 1; | ||
642 | regs.r[2] = 0; | ||
643 | _kernel_swi(OS_Byte, ®s, ®s); | ||
644 | |||
645 | } | ||
646 | |||
647 | /** Enable special escape key processing */ | ||
648 | static void FULLSCREEN_EnableEscape() | ||
649 | { | ||
650 | _kernel_swi_regs regs; | ||
651 | regs.r[0] = 229; | ||
652 | regs.r[1] = 0; | ||
653 | regs.r[2] = 0; | ||
654 | _kernel_swi(OS_Byte, ®s, ®s); | ||
655 | |||
656 | } | ||
657 | |||
658 | /** Store caption in case this is called before we create a window */ | ||
659 | void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon) | ||
660 | { | ||
661 | SDL_strlcpy(this->hidden->title, title, SDL_arraysize(this->hidden->title)); | ||
662 | } | ||
663 | |||
664 | /* Set screen mode | ||
665 | * | ||
666 | * Returns 1 if mode is set ok, otherwise 0 | ||
667 | */ | ||
668 | |||
669 | int FULLSCREEN_SetMode(int width, int height, int bpp) | ||
670 | { | ||
671 | SCREENMODEBLOCK smb; | ||
672 | _kernel_swi_regs regs; | ||
673 | |||
674 | smb.flags = 1; | ||
675 | smb.x_pixels = width; | ||
676 | smb.y_pixels = height; | ||
677 | smb.mode_vars[0] = -1; | ||
678 | |||
679 | switch(bpp) | ||
680 | { | ||
681 | case 8: | ||
682 | smb.pixel_depth = 3; | ||
683 | /* Note: Need to set ModeFlags to 128 and NColour variables to 255 get full 8 bit palette */ | ||
684 | smb.mode_vars[0] = 0; smb.mode_vars[1] = 128; /* Mode flags */ | ||
685 | smb.mode_vars[2] = 3; smb.mode_vars[3] = 255; /* NColour (number of colours -1) */ | ||
686 | smb.mode_vars[4] = -1; /* End of list */ | ||
687 | break; | ||
688 | |||
689 | case 15: | ||
690 | case 16: | ||
691 | smb.pixel_depth = 4; | ||
692 | break; | ||
693 | |||
694 | case 32: | ||
695 | smb.pixel_depth = 5; | ||
696 | break; | ||
697 | |||
698 | default: | ||
699 | SDL_SetError("Pixel depth not supported"); | ||
700 | return 0; | ||
701 | break; | ||
702 | } | ||
703 | |||
704 | smb.frame_rate = -1; | ||
705 | |||
706 | regs.r[0] = 0; | ||
707 | regs.r[1] = (int)&smb; | ||
708 | |||
709 | if (_kernel_swi(OS_ScreenMode, ®s, ®s) != 0) | ||
710 | { | ||
711 | SDL_SetError("Couldn't set requested mode"); | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | /* Turn cursor off*/ | ||
716 | _kernel_oswrch(23);_kernel_oswrch(1);_kernel_oswrch(0); | ||
717 | _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0); | ||
718 | _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0); | ||
719 | _kernel_oswrch(0);_kernel_oswrch(0); | ||
720 | |||
721 | return 1; | ||
722 | } | ||
723 | |||
724 | /* Get Start addresses for the screen banks */ | ||
725 | void FULLSCREEN_SetupBanks(_THIS) | ||
726 | { | ||
727 | _kernel_swi_regs regs; | ||
728 | int block[5]; | ||
729 | block[0] = 148; /* Write screen start */ | ||
730 | block[1] = 149; /* Display screen start */ | ||
731 | block[2] = 4; /* X eig factor */ | ||
732 | block[3] = 5; /* Y eig factor */ | ||
733 | block[4] = -1; /* End of list of variables to request */ | ||
734 | |||
735 | regs.r[0] = (int)block; | ||
736 | regs.r[1] = (int)block; | ||
737 | _kernel_swi(OS_ReadVduVariables, ®s, ®s); | ||
738 | |||
739 | this->hidden->bank[0] = (void *)block[0]; | ||
740 | this->hidden->bank[1] = (void *)block[1]; | ||
741 | this->hidden->xeig = block[2]; | ||
742 | this->hidden->yeig = block[3]; | ||
743 | } | ||
744 | |||
745 | /* Toggle to full screen mode from the WIMP */ | ||
746 | |||
747 | int FULLSCREEN_ToggleFromWimp(_THIS) | ||
748 | { | ||
749 | int width = this->screen->w; | ||
750 | int height = this->screen->h; | ||
751 | int bpp = this->screen->format->BitsPerPixel; | ||
752 | |||
753 | RISCOS_StoreWimpMode(); | ||
754 | if (FULLSCREEN_SetMode(width, height, bpp)) | ||
755 | { | ||
756 | char *buffer = this->hidden->alloc_bank; /* This is start of sprite data */ | ||
757 | /* Support back buffer mode only */ | ||
758 | if (riscos_backbuffer == 0) riscos_backbuffer = 1; | ||
759 | |||
760 | FULLSCREEN_SetupBanks(this); | ||
761 | |||
762 | this->hidden->bank[0] = buffer + 60; /* Start of sprite data */ | ||
763 | if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ | ||
764 | |||
765 | this->hidden->current_bank = 0; | ||
766 | this->screen->pixels = this->hidden->bank[0]; | ||
767 | |||
768 | /* Copy back buffer to screen memory */ | ||
769 | SDL_memcpy(this->hidden->bank[1], this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel); | ||
770 | |||
771 | FULLSCREEN_SetDeviceMode(this); | ||
772 | return 1; | ||
773 | } else | ||
774 | RISCOS_RestoreWimpMode(); | ||
775 | |||
776 | return 0; | ||
777 | } | ||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c b/apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c new file mode 100644 index 0000000000..54875076ab --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c | |||
@@ -0,0 +1,549 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 27 March 2003 | ||
27 | |||
28 | Implements keyboard setup, event pump and keyboard and mouse polling | ||
29 | */ | ||
30 | |||
31 | |||
32 | #include "SDL.h" | ||
33 | #include "../../timer/SDL_timer_c.h" | ||
34 | #include "../../events/SDL_sysevents.h" | ||
35 | #include "../../events/SDL_events_c.h" | ||
36 | #include "../SDL_cursor_c.h" | ||
37 | #include "SDL_riscosvideo.h" | ||
38 | #include "SDL_riscosevents_c.h" | ||
39 | |||
40 | #include "memory.h" | ||
41 | #include "stdlib.h" | ||
42 | #include "ctype.h" | ||
43 | |||
44 | #include "kernel.h" | ||
45 | #include "swis.h" | ||
46 | |||
47 | /* The translation table from a RISC OS internal key numbers to a SDL keysym */ | ||
48 | static SDLKey RO_keymap[SDLK_LAST]; | ||
49 | |||
50 | /* RISC OS Key codes */ | ||
51 | #define ROKEY_SHIFT 0 | ||
52 | #define ROKEY_CTRL 1 | ||
53 | #define ROKEY_ALT 2 | ||
54 | /* Left shift is first key we will check for */ | ||
55 | #define ROKEY_LEFT_SHIFT 3 | ||
56 | |||
57 | /* Need to ignore mouse buttons as they are processed separately */ | ||
58 | #define ROKEY_LEFT_MOUSE 9 | ||
59 | #define ROKEY_CENTRE_MOUSE 10 | ||
60 | #define ROKEY_RIGHT_MOUSE 11 | ||
61 | |||
62 | /* No key has been pressed return value*/ | ||
63 | #define ROKEY_NONE 255 | ||
64 | |||
65 | /* Id of last key in keyboard */ | ||
66 | #define ROKEY_LAST_KEY 124 | ||
67 | |||
68 | /* Size of array for all keys */ | ||
69 | #define ROKEYBD_ARRAYSIZE 125 | ||
70 | |||
71 | static char RO_pressed[ROKEYBD_ARRAYSIZE]; | ||
72 | |||
73 | static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed); | ||
74 | |||
75 | void RISCOS_PollMouse(_THIS); | ||
76 | void RISCOS_PollKeyboard(); | ||
77 | |||
78 | void RISCOS_PollMouseHelper(_THIS, int fullscreen); | ||
79 | |||
80 | #if SDL_THREADS_DISABLED | ||
81 | extern void DRenderer_FillBuffers(); | ||
82 | |||
83 | /* Timer running function */ | ||
84 | extern void RISCOS_CheckTimer(); | ||
85 | |||
86 | #endif | ||
87 | |||
88 | void FULLSCREEN_PumpEvents(_THIS) | ||
89 | { | ||
90 | /* Current implementation requires keyboard and mouse polling */ | ||
91 | RISCOS_PollKeyboard(); | ||
92 | RISCOS_PollMouse(this); | ||
93 | #if SDL_THREADS_DISABLED | ||
94 | // DRenderer_FillBuffers(); | ||
95 | if (SDL_timer_running) RISCOS_CheckTimer(); | ||
96 | #endif | ||
97 | } | ||
98 | |||
99 | |||
100 | void RISCOS_InitOSKeymap(_THIS) | ||
101 | { | ||
102 | int i; | ||
103 | |||
104 | /* Map the VK keysyms */ | ||
105 | for ( i=0; i<SDL_arraysize(RO_keymap); ++i ) | ||
106 | RO_keymap[i] = SDLK_UNKNOWN; | ||
107 | |||
108 | RO_keymap[3] = SDLK_LSHIFT; | ||
109 | RO_keymap[4] = SDLK_LCTRL; | ||
110 | RO_keymap[5] = SDLK_LALT; | ||
111 | RO_keymap[6] = SDLK_RSHIFT; | ||
112 | RO_keymap[7] = SDLK_RCTRL; | ||
113 | RO_keymap[8] = SDLK_RALT; | ||
114 | RO_keymap[16] = SDLK_q; | ||
115 | RO_keymap[17] = SDLK_3; | ||
116 | RO_keymap[18] = SDLK_4; | ||
117 | RO_keymap[19] = SDLK_5; | ||
118 | RO_keymap[20] = SDLK_F4; | ||
119 | RO_keymap[21] = SDLK_8; | ||
120 | RO_keymap[22] = SDLK_F7; | ||
121 | RO_keymap[23] = SDLK_MINUS, | ||
122 | RO_keymap[25] = SDLK_LEFT; | ||
123 | RO_keymap[26] = SDLK_KP6; | ||
124 | RO_keymap[27] = SDLK_KP7; | ||
125 | RO_keymap[28] = SDLK_F11; | ||
126 | RO_keymap[29] = SDLK_F12; | ||
127 | RO_keymap[30] = SDLK_F10; | ||
128 | RO_keymap[31] = SDLK_SCROLLOCK; | ||
129 | RO_keymap[32] = SDLK_PRINT; | ||
130 | RO_keymap[33] = SDLK_w; | ||
131 | RO_keymap[34] = SDLK_e; | ||
132 | RO_keymap[35] = SDLK_t; | ||
133 | RO_keymap[36] = SDLK_7; | ||
134 | RO_keymap[37] = SDLK_i; | ||
135 | RO_keymap[38] = SDLK_9; | ||
136 | RO_keymap[39] = SDLK_0; | ||
137 | RO_keymap[41] = SDLK_DOWN; | ||
138 | RO_keymap[42] = SDLK_KP8; | ||
139 | RO_keymap[43] = SDLK_KP9; | ||
140 | RO_keymap[44] = SDLK_BREAK; | ||
141 | RO_keymap[45] = SDLK_BACKQUOTE; | ||
142 | /* RO_keymap[46] = SDLK_currency; TODO: Figure out if this has a value */ | ||
143 | RO_keymap[47] = SDLK_BACKSPACE; | ||
144 | RO_keymap[48] = SDLK_1; | ||
145 | RO_keymap[49] = SDLK_2; | ||
146 | RO_keymap[50] = SDLK_d; | ||
147 | RO_keymap[51] = SDLK_r; | ||
148 | RO_keymap[52] = SDLK_6; | ||
149 | RO_keymap[53] = SDLK_u; | ||
150 | RO_keymap[54] = SDLK_o; | ||
151 | RO_keymap[55] = SDLK_p; | ||
152 | RO_keymap[56] = SDLK_LEFTBRACKET; | ||
153 | RO_keymap[57] = SDLK_UP; | ||
154 | RO_keymap[58] = SDLK_KP_PLUS; | ||
155 | RO_keymap[59] = SDLK_KP_MINUS; | ||
156 | RO_keymap[60] = SDLK_KP_ENTER; | ||
157 | RO_keymap[61] = SDLK_INSERT; | ||
158 | RO_keymap[62] = SDLK_HOME; | ||
159 | RO_keymap[63] = SDLK_PAGEUP; | ||
160 | RO_keymap[64] = SDLK_CAPSLOCK; | ||
161 | RO_keymap[65] = SDLK_a; | ||
162 | RO_keymap[66] = SDLK_x; | ||
163 | RO_keymap[67] = SDLK_f; | ||
164 | RO_keymap[68] = SDLK_y; | ||
165 | RO_keymap[69] = SDLK_j; | ||
166 | RO_keymap[70] = SDLK_k; | ||
167 | RO_keymap[72] = SDLK_SEMICOLON; | ||
168 | RO_keymap[73] = SDLK_RETURN; | ||
169 | RO_keymap[74] = SDLK_KP_DIVIDE; | ||
170 | RO_keymap[76] = SDLK_KP_PERIOD; | ||
171 | RO_keymap[77] = SDLK_NUMLOCK; | ||
172 | RO_keymap[78] = SDLK_PAGEDOWN; | ||
173 | RO_keymap[79] = SDLK_QUOTE; | ||
174 | RO_keymap[81] = SDLK_s; | ||
175 | RO_keymap[82] = SDLK_c; | ||
176 | RO_keymap[83] = SDLK_g; | ||
177 | RO_keymap[84] = SDLK_h; | ||
178 | RO_keymap[85] = SDLK_n; | ||
179 | RO_keymap[86] = SDLK_l; | ||
180 | RO_keymap[87] = SDLK_SEMICOLON; | ||
181 | RO_keymap[88] = SDLK_RIGHTBRACKET; | ||
182 | RO_keymap[89] = SDLK_DELETE; | ||
183 | RO_keymap[90] = SDLK_KP_MINUS; | ||
184 | RO_keymap[91] = SDLK_KP_MULTIPLY; | ||
185 | RO_keymap[93] = SDLK_EQUALS; | ||
186 | RO_keymap[94] = SDLK_BACKSLASH; | ||
187 | RO_keymap[96] = SDLK_TAB; | ||
188 | RO_keymap[97] = SDLK_z; | ||
189 | RO_keymap[98] = SDLK_SPACE; | ||
190 | RO_keymap[99] = SDLK_v; | ||
191 | RO_keymap[100] = SDLK_b; | ||
192 | RO_keymap[101] = SDLK_m; | ||
193 | RO_keymap[102] = SDLK_COMMA; | ||
194 | RO_keymap[103] = SDLK_PERIOD; | ||
195 | RO_keymap[104] = SDLK_SLASH; | ||
196 | RO_keymap[105] = SDLK_END; | ||
197 | RO_keymap[106] = SDLK_KP0; | ||
198 | RO_keymap[107] = SDLK_KP1; | ||
199 | RO_keymap[108] = SDLK_KP3; | ||
200 | RO_keymap[112] = SDLK_ESCAPE; | ||
201 | RO_keymap[113] = SDLK_F1; | ||
202 | RO_keymap[114] = SDLK_F2; | ||
203 | RO_keymap[115] = SDLK_F3; | ||
204 | RO_keymap[116] = SDLK_F5; | ||
205 | RO_keymap[117] = SDLK_F6; | ||
206 | RO_keymap[118] = SDLK_F8; | ||
207 | RO_keymap[119] = SDLK_F9; | ||
208 | RO_keymap[120] = SDLK_HASH; | ||
209 | RO_keymap[121] = SDLK_RIGHT; | ||
210 | RO_keymap[122] = SDLK_KP4; | ||
211 | RO_keymap[123] = SDLK_KP5; | ||
212 | RO_keymap[124] = SDLK_KP2; | ||
213 | |||
214 | SDL_memset(RO_pressed, 0, ROKEYBD_ARRAYSIZE); | ||
215 | } | ||
216 | |||
217 | |||
218 | /* Variable for mouse relative processing */ | ||
219 | int mouse_relative = 0; | ||
220 | |||
221 | /* Check to see if we need to enter or leave mouse relative mode */ | ||
222 | |||
223 | void RISCOS_CheckMouseMode(_THIS) | ||
224 | { | ||
225 | /* If the mouse is hidden and input is grabbed, we use relative mode */ | ||
226 | if ( !(SDL_cursorstate & CURSOR_VISIBLE) && | ||
227 | (this->input_grab != SDL_GRAB_OFF) ) { | ||
228 | mouse_relative = 1; | ||
229 | } else { | ||
230 | mouse_relative = 0; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | |||
235 | void RISCOS_PollMouse(_THIS) | ||
236 | { | ||
237 | RISCOS_PollMouseHelper(this, 1); | ||
238 | } | ||
239 | |||
240 | extern int mouseInWindow; | ||
241 | |||
242 | void WIMP_PollMouse(_THIS) | ||
243 | { | ||
244 | /* Only poll when mouse is over the window */ | ||
245 | if (!mouseInWindow) return; | ||
246 | |||
247 | RISCOS_PollMouseHelper(this, 0); | ||
248 | } | ||
249 | |||
250 | /* Static variables so only changes are reported */ | ||
251 | static Sint16 last_x = -1, last_y = -1; | ||
252 | static int last_buttons = 0; | ||
253 | |||
254 | /* Share routine between WIMP and FULLSCREEN for polling mouse and | ||
255 | passing on events */ | ||
256 | void RISCOS_PollMouseHelper(_THIS, int fullscreen) | ||
257 | { | ||
258 | _kernel_swi_regs regs; | ||
259 | static int starting = 1; | ||
260 | |||
261 | if (_kernel_swi(OS_Mouse, ®s, ®s) == NULL) | ||
262 | { | ||
263 | Sint16 new_x = regs.r[0]; /* Initialy get as OS units */ | ||
264 | Sint16 new_y = regs.r[1]; | ||
265 | |||
266 | /* Discard mouse events until they let go of the mouse after starting */ | ||
267 | if (starting && regs.r[2] != 0) | ||
268 | return; | ||
269 | else | ||
270 | starting = 0; | ||
271 | |||
272 | if (new_x != last_x || new_y != last_y || last_buttons != regs.r[2]) | ||
273 | { | ||
274 | /* Something changed so generate appropriate events */ | ||
275 | int topLeftX, topLeftY; /* Top left OS units */ | ||
276 | int x, y; /* Mouse position in SDL pixels */ | ||
277 | |||
278 | if (fullscreen) | ||
279 | { | ||
280 | topLeftX = 0; | ||
281 | topLeftY = (this->hidden->height << this->hidden->yeig) - 1; | ||
282 | } else | ||
283 | { | ||
284 | int window_state[9]; | ||
285 | |||
286 | /* Get current window state */ | ||
287 | window_state[0] = this->hidden->window_handle; | ||
288 | regs.r[1] = (unsigned int)window_state; | ||
289 | _kernel_swi(Wimp_GetWindowState, ®s, ®s); | ||
290 | |||
291 | topLeftX = window_state[1]; | ||
292 | topLeftY = window_state[4]; | ||
293 | } | ||
294 | |||
295 | /* Convert co-ordinates to workspace */ | ||
296 | x = new_x - topLeftX; | ||
297 | y = topLeftY - new_y; /* Y goes from top of window/screen */ | ||
298 | |||
299 | /* Convert OS units to pixels */ | ||
300 | x >>= this->hidden->xeig; | ||
301 | y >>= this->hidden->yeig; | ||
302 | |||
303 | if (last_x != new_x || last_y != new_y) | ||
304 | { | ||
305 | if (mouse_relative) | ||
306 | { | ||
307 | int centre_x = SDL_VideoSurface->w/2; | ||
308 | int centre_y = SDL_VideoSurface->h/2; | ||
309 | |||
310 | if (centre_x != x || centre_y != y) | ||
311 | { | ||
312 | if (SDL_VideoSurface) SDL_PrivateMouseMotion(0,1,x - centre_x, y - centre_y); | ||
313 | last_x = topLeftX + (centre_x << this->hidden->xeig); | ||
314 | last_y = topLeftY - (centre_y << this->hidden->yeig); | ||
315 | |||
316 | /* Re-centre the mouse pointer, so we still get relative | ||
317 | movement when the mouse is at the edge of the window | ||
318 | or screen. | ||
319 | */ | ||
320 | { | ||
321 | unsigned char block[5]; | ||
322 | |||
323 | block[0] = 3; /* OSWORD move pointer sub-reason code */ | ||
324 | block[1] = last_x & 0xFF; | ||
325 | block[2] = (last_x >> 8) & 0xFF; | ||
326 | block[3] = last_y & 0xFF; | ||
327 | block[4] = (last_y >> 8) & 0xFF; | ||
328 | |||
329 | regs.r[0] = 21; /* OSWORD pointer stuff code */ | ||
330 | regs.r[1] = (int)block; | ||
331 | _kernel_swi(OS_Word, ®s, ®s); | ||
332 | } | ||
333 | } | ||
334 | } else | ||
335 | { | ||
336 | last_x = new_x; | ||
337 | last_y = new_y; | ||
338 | SDL_PrivateMouseMotion(0,0,x,y); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | if (last_buttons != regs.r[2]) | ||
343 | { | ||
344 | int changed = last_buttons ^ regs.r[2]; | ||
345 | last_buttons = regs.r[2]; | ||
346 | if (changed & 4) SDL_PrivateMouseButton((last_buttons & 4) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); | ||
347 | if (changed & 2) SDL_PrivateMouseButton((last_buttons & 2) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0); | ||
348 | if (changed & 1) SDL_PrivateMouseButton((last_buttons & 1) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); | ||
349 | } | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | void RISCOS_PollKeyboard() | ||
355 | { | ||
356 | int which_key = ROKEY_LEFT_SHIFT; | ||
357 | int j; | ||
358 | int min_key, max_key; | ||
359 | SDL_keysym key; | ||
360 | |||
361 | /* Scan the keyboard to see what is pressed */ | ||
362 | while (which_key <= ROKEY_LAST_KEY) | ||
363 | { | ||
364 | which_key = (_kernel_osbyte(121, which_key, 0) & 0xFF); | ||
365 | if (which_key != ROKEY_NONE) | ||
366 | { | ||
367 | switch(which_key) | ||
368 | { | ||
369 | /* Skip over mouse keys */ | ||
370 | case ROKEY_LEFT_MOUSE: | ||
371 | case ROKEY_CENTRE_MOUSE: | ||
372 | case ROKEY_RIGHT_MOUSE: | ||
373 | which_key = ROKEY_RIGHT_MOUSE; | ||
374 | break; | ||
375 | |||
376 | /* Ignore keys that cause 2 internal number to be generated */ | ||
377 | case 71: case 24: case 87: case 40: | ||
378 | break; | ||
379 | |||
380 | /* Ignore break as it can be latched on */ | ||
381 | case 44: | ||
382 | break; | ||
383 | |||
384 | default: | ||
385 | RO_pressed[which_key] += 2; | ||
386 | break; | ||
387 | } | ||
388 | which_key++; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | /* Generate key released messages */ | ||
393 | min_key = ROKEY_LAST_KEY+1; | ||
394 | max_key = ROKEY_LEFT_SHIFT; | ||
395 | |||
396 | for (j = ROKEY_LEFT_SHIFT; j <= ROKEY_LAST_KEY; j++) | ||
397 | { | ||
398 | if (RO_pressed[j]) | ||
399 | { | ||
400 | if (RO_pressed[j] == 1) | ||
401 | { | ||
402 | RO_pressed[j] = 0; | ||
403 | SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(j,&key,0)); | ||
404 | } else | ||
405 | { | ||
406 | if (j < min_key) min_key = j; | ||
407 | if (j > max_key) max_key = j; | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | |||
412 | /* Generate key pressed messages */ | ||
413 | for (j = min_key; j <= max_key; j++) | ||
414 | { | ||
415 | if (RO_pressed[j]) | ||
416 | { | ||
417 | if (RO_pressed[j] == 2) | ||
418 | { | ||
419 | SDL_PrivateKeyboard(SDL_PRESSED,TranslateKey(j,&key,1)); | ||
420 | } | ||
421 | RO_pressed[j] = 1; | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | |||
426 | static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed) | ||
427 | { | ||
428 | /* Set the keysym information */ | ||
429 | keysym->scancode = (unsigned char) intkey; | ||
430 | keysym->sym = RO_keymap[intkey]; | ||
431 | keysym->mod = KMOD_NONE; | ||
432 | keysym->unicode = 0; | ||
433 | if ( pressed && SDL_TranslateUNICODE ) | ||
434 | { | ||
435 | int state; | ||
436 | int ch; | ||
437 | |||
438 | state = (_kernel_osbyte(202, 0, 255) & 0xFF); | ||
439 | |||
440 | /*TODO: Take into account other keyboard layouts */ | ||
441 | |||
442 | ch = keysym->sym; /* This should handle most unshifted keys */ | ||
443 | |||
444 | if (intkey < 9 || ch == SDLK_UNKNOWN) | ||
445 | { | ||
446 | ch = 0; | ||
447 | |||
448 | } else if (state & 64) /* Control on */ | ||
449 | { | ||
450 | ch = ch & 31; | ||
451 | |||
452 | } else | ||
453 | { | ||
454 | int topOfKey = 0; | ||
455 | if (state & 8) /* Shift on */ | ||
456 | { | ||
457 | topOfKey = 1; | ||
458 | } | ||
459 | |||
460 | if ((state & 16) == 0) /* Caps lock is on */ | ||
461 | { | ||
462 | if (ch >= SDLK_a && ch <= SDLK_z) | ||
463 | { | ||
464 | if ((state & 128) == 0) /* Shift Enable off */ | ||
465 | { | ||
466 | /* All letter become upper case */ | ||
467 | topOfKey = 1; | ||
468 | } else | ||
469 | { | ||
470 | /* Shift+Letters gives lower case */ | ||
471 | topOfKey = 1 - topOfKey; | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | |||
476 | if (topOfKey) | ||
477 | { | ||
478 | /* Key produced with shift held down */ | ||
479 | |||
480 | /* Letters just give upper case version */ | ||
481 | if (ch >= SDLK_a && ch <= SDLK_z) ch = toupper(ch); | ||
482 | else | ||
483 | { | ||
484 | switch(ch) | ||
485 | { | ||
486 | case SDLK_HASH: ch = '~'; break; | ||
487 | case SDLK_QUOTE: ch = '@'; break; | ||
488 | case SDLK_COMMA: ch = '<'; break; | ||
489 | case SDLK_MINUS: ch = '_'; break; | ||
490 | case SDLK_PERIOD: ch = '>'; break; | ||
491 | case SDLK_SLASH: ch = '?'; break; | ||
492 | |||
493 | case SDLK_0: ch = ')'; break; | ||
494 | case SDLK_1: ch = '!'; break; | ||
495 | case SDLK_2: ch = '"'; break; | ||
496 | case SDLK_3: ch = '£'; break; | ||
497 | case SDLK_4: ch = '$'; break; | ||
498 | case SDLK_5: ch = '%'; break; | ||
499 | case SDLK_6: ch = '^'; break; | ||
500 | case SDLK_7: ch = '&'; break; | ||
501 | case SDLK_8: ch = '*'; break; | ||
502 | case SDLK_9: ch = '('; break; | ||
503 | |||
504 | case SDLK_SEMICOLON: ch = ':'; break; | ||
505 | case SDLK_EQUALS: ch = '+'; break; | ||
506 | case SDLK_LEFTBRACKET: ch = '{'; break; | ||
507 | case SDLK_BACKSLASH: ch = '|'; break; | ||
508 | case SDLK_RIGHTBRACKET: ch = '}'; break; | ||
509 | case SDLK_BACKQUOTE: ch = '¬'; break; | ||
510 | |||
511 | default: | ||
512 | ch = 0; /* Map to zero character if we don't understand it */ | ||
513 | break; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | } else if (ch > 126) | ||
518 | { | ||
519 | /* SDL key code < 126 map directly onto their Unicode equivalents */ | ||
520 | /* Keypad 0 to 9 maps to numeric equivalent */ | ||
521 | if (ch >= SDLK_KP0 && ch <= SDLK_KP9) ch = ch - SDLK_KP0 + '0'; | ||
522 | else | ||
523 | { | ||
524 | /* Following switch maps other keys that produce an Ascii value */ | ||
525 | switch(ch) | ||
526 | { | ||
527 | case SDLK_KP_PERIOD: ch = '.'; break; | ||
528 | case SDLK_KP_DIVIDE: ch = '/'; break; | ||
529 | case SDLK_KP_MULTIPLY: ch = '*'; break; | ||
530 | case SDLK_KP_MINUS: ch = '-'; break; | ||
531 | case SDLK_KP_PLUS: ch = '+'; break; | ||
532 | case SDLK_KP_EQUALS: ch = '='; break; | ||
533 | |||
534 | default: | ||
535 | /* If we don't know what it is set the Unicode to 0 */ | ||
536 | ch = 0; | ||
537 | break; | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | |||
543 | keysym->unicode = ch; | ||
544 | } | ||
545 | return(keysym); | ||
546 | } | ||
547 | |||
548 | /* end of SDL_riscosevents.c ... */ | ||
549 | |||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosevents_c.h b/apps/plugins/sdl/src/video/riscos/SDL_riscosevents_c.h new file mode 100644 index 0000000000..189b3c0cfe --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosevents_c.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_riscosvideo.h" | ||
25 | |||
26 | /* Variables and functions exported by SDL_sysevents.c to other parts | ||
27 | of the native video subsystem (SDL_sysvideo.c) | ||
28 | */ | ||
29 | extern void RISCOS_InitOSKeymap(_THIS); | ||
30 | extern void FULLSCREEN_PumpEvents(_THIS); | ||
31 | extern void WIMP_PumpEvents(_THIS); | ||
32 | |||
33 | /* end of SDL_nullevents_c.h ... */ | ||
34 | |||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c b/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c new file mode 100644 index 0000000000..b4a0bffc94 --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c | |||
@@ -0,0 +1,371 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 27 March 2003 | ||
27 | |||
28 | Implements mouse cursor shape definitions and positioning | ||
29 | */ | ||
30 | |||
31 | #include "SDL_mouse.h" | ||
32 | #include "../../events/SDL_events_c.h" | ||
33 | |||
34 | #include "SDL_riscosmouse_c.h" | ||
35 | |||
36 | #include "kernel.h" | ||
37 | #include "swis.h" | ||
38 | |||
39 | static WMcursor *current_cursor = NULL; | ||
40 | static WMcursor *defined_cursor = NULL; | ||
41 | |||
42 | extern int mouseInWindow; | ||
43 | |||
44 | /* Area to save cursor palette colours changed by SDL. | ||
45 | Actual values will be read before we change to the SDL cursor */ | ||
46 | static Uint8 wimp_cursor_palette[2][5] = { | ||
47 | {1, 25, 255, 255, 255}, | ||
48 | {3, 25, 255, 255, 255} | ||
49 | }; | ||
50 | |||
51 | static int cursor_palette_saved = 0; | ||
52 | |||
53 | void WIMP_SaveCursorPalette(); | ||
54 | void WIMP_RestoreWimpCursor(); | ||
55 | void WIMP_SetSDLCursorPalette(); | ||
56 | |||
57 | |||
58 | void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor) | ||
59 | { | ||
60 | SDL_free(cursor->data); | ||
61 | SDL_free(cursor); | ||
62 | } | ||
63 | |||
64 | WMcursor *RISCOS_CreateWMCursor(_THIS, | ||
65 | Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) | ||
66 | { | ||
67 | WMcursor *cursor; | ||
68 | Uint8 *cursor_data; | ||
69 | Uint8 *ptr; | ||
70 | int i,j,k; | ||
71 | int data_byte, mask_byte; | ||
72 | |||
73 | /* Check to make sure the cursor size is okay */ | ||
74 | if ( (w > 32) || (h > 32) ) { | ||
75 | SDL_SetError("Only with width and height <= 32 pixels are allowed"); | ||
76 | return(NULL); | ||
77 | } | ||
78 | |||
79 | /* Allocate the cursor */ | ||
80 | cursor = (WMcursor *)SDL_malloc(sizeof(*cursor)); | ||
81 | if ( cursor == NULL ) { | ||
82 | SDL_SetError("Out of memory"); | ||
83 | return(NULL); | ||
84 | } | ||
85 | |||
86 | /* Note: SDL says width must be a multiple of 8 */ | ||
87 | cursor_data = SDL_malloc(w/4 * h); | ||
88 | if (cursor_data == NULL) | ||
89 | { | ||
90 | SDL_free(cursor); | ||
91 | SDL_SetError("Out of memory"); | ||
92 | return(NULL); | ||
93 | } | ||
94 | |||
95 | cursor->w = w; | ||
96 | cursor->h = h; | ||
97 | cursor->hot_x = hot_x; | ||
98 | cursor->hot_y = hot_y; | ||
99 | cursor->data = cursor_data; | ||
100 | |||
101 | |||
102 | /* Data / Mask Resulting pixel on screen | ||
103 | 0 / 1 White | ||
104 | 1 / 1 Black | ||
105 | 0 / 0 Transparent | ||
106 | 1 / 0 Inverted color if possible, black if not. | ||
107 | */ | ||
108 | ptr = cursor_data; | ||
109 | |||
110 | for ( i=0; i<h; ++i ) | ||
111 | { | ||
112 | for (j = 0; j < w/8; ++j) | ||
113 | { | ||
114 | data_byte = *data; | ||
115 | mask_byte = *mask; | ||
116 | *ptr++ = 0; /* Sets whole byte transparent */ | ||
117 | *ptr = 0; | ||
118 | for (k = 0; k < 8; k++) | ||
119 | { | ||
120 | (*ptr) <<= 2; | ||
121 | if (data_byte & 1) *ptr |= 3; /* Black or inverted */ | ||
122 | else if(mask_byte & 1) *ptr |= 1; /* White */ | ||
123 | if ((k&3) == 3) ptr--; | ||
124 | data_byte >>= 1; | ||
125 | mask_byte >>= 1; | ||
126 | } | ||
127 | |||
128 | ptr+=3; | ||
129 | data++; | ||
130 | mask++; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | return(cursor); | ||
135 | } | ||
136 | |||
137 | int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor) | ||
138 | { | ||
139 | current_cursor = cursor; | ||
140 | |||
141 | if (cursor == NULL) | ||
142 | { | ||
143 | _kernel_osbyte(106,0,0); | ||
144 | defined_cursor = NULL; | ||
145 | } else | ||
146 | { | ||
147 | WMcursor *old_cursor = defined_cursor; | ||
148 | |||
149 | if (cursor != defined_cursor) | ||
150 | { | ||
151 | Uint8 cursor_def[10]; | ||
152 | |||
153 | cursor_def[0] = 0; | ||
154 | cursor_def[1] = 2; /* Use shape number 2 */ | ||
155 | cursor_def[2] = cursor->w/4; /* Width in bytes */ | ||
156 | cursor_def[3] = cursor->h; /* Height (h) in pixels */ | ||
157 | cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */ | ||
158 | cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */ | ||
159 | cursor_def[6] = ((int)(cursor->data) & 0xFF); /* Least significant byte of pointer to data */ | ||
160 | cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF; /* ... */ | ||
161 | cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */ | ||
162 | cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */ | ||
163 | |||
164 | if (_kernel_osword(21, (int *)cursor_def) != 0) | ||
165 | { | ||
166 | SDL_SetError("RISCOS couldn't create the cursor to show"); | ||
167 | return(0); | ||
168 | } | ||
169 | defined_cursor = cursor; | ||
170 | } | ||
171 | |||
172 | if (old_cursor == NULL) | ||
173 | { | ||
174 | /* First time or reshow in window, so save/setup palette */ | ||
175 | if (!cursor_palette_saved) | ||
176 | { | ||
177 | WIMP_SaveCursorPalette(); | ||
178 | } | ||
179 | WIMP_SetSDLCursorPalette(); | ||
180 | } | ||
181 | |||
182 | _kernel_osbyte(106, 2, 0); | ||
183 | } | ||
184 | |||
185 | return(1); | ||
186 | } | ||
187 | |||
188 | void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | ||
189 | { | ||
190 | Uint8 move_block[5]; | ||
191 | int eig_block[3]; | ||
192 | _kernel_swi_regs regs; | ||
193 | int os_x, os_y; | ||
194 | |||
195 | eig_block[0] = 4; /* X eig factor */ | ||
196 | eig_block[1] = 5; /* Y eig factor */ | ||
197 | eig_block[2] = -1; /* End of list of variables to request */ | ||
198 | |||
199 | regs.r[0] = (int)eig_block; | ||
200 | regs.r[1] = (int)eig_block; | ||
201 | _kernel_swi(OS_ReadVduVariables, ®s, ®s); | ||
202 | |||
203 | os_x = x << eig_block[0]; | ||
204 | os_y = y << eig_block[1]; | ||
205 | |||
206 | move_block[0] = 3; /* Move cursor */ | ||
207 | move_block[1] = os_x & 0xFF; | ||
208 | move_block[2] = (os_x >> 8) & 0xFF; | ||
209 | move_block[3] = os_y & 0xFF; | ||
210 | move_block[4] = (os_y >> 8) & 0xFF; | ||
211 | |||
212 | _kernel_osword(21, (int *)move_block); | ||
213 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
214 | } | ||
215 | |||
216 | |||
217 | /* Reshow cursor when mouse re-enters the window */ | ||
218 | void WIMP_ReshowCursor(_THIS) | ||
219 | { | ||
220 | defined_cursor = NULL; | ||
221 | cursor_palette_saved = 0; | ||
222 | RISCOS_ShowWMCursor(this, current_cursor); | ||
223 | } | ||
224 | |||
225 | void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | ||
226 | { | ||
227 | _kernel_swi_regs regs; | ||
228 | int window_state[9]; | ||
229 | char block[5]; | ||
230 | int osX, osY; | ||
231 | |||
232 | window_state[0] = this->hidden->window_handle; | ||
233 | regs.r[1] = (unsigned int)window_state; | ||
234 | _kernel_swi(Wimp_GetWindowState, ®s, ®s); | ||
235 | |||
236 | osX = (x << this->hidden->xeig) + window_state[1]; | ||
237 | osY = window_state[4] - (y << this->hidden->yeig); | ||
238 | |||
239 | block[0] = 3; | ||
240 | block[1] = osX & 0xFF; | ||
241 | block[2] = (osX >> 8) & 0xFF; | ||
242 | block[3] = osY & 0xFF; | ||
243 | block[4] = (osY >> 8) & 0xFF; | ||
244 | |||
245 | regs.r[0] = 21; | ||
246 | regs.r[1] = (int)block; | ||
247 | _kernel_swi(OS_Word, ®s, ®s); | ||
248 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
249 | } | ||
250 | |||
251 | int WIMP_ShowWMCursor(_THIS, WMcursor *cursor) | ||
252 | { | ||
253 | if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor); | ||
254 | else current_cursor = cursor; | ||
255 | |||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode) | ||
260 | { | ||
261 | /* In fullscreen mode we don't need to do anything */ | ||
262 | if (mode < SDL_GRAB_FULLSCREEN) | ||
263 | { | ||
264 | _kernel_swi_regs regs; | ||
265 | unsigned char block[9]; | ||
266 | block[0] = 1; /* Define mouse cursor bounding block */ | ||
267 | |||
268 | if ( mode == SDL_GRAB_OFF ) | ||
269 | { | ||
270 | /* Clip to whole screen */ | ||
271 | |||
272 | int r = (this->hidden->screen_width << this->hidden->xeig) - 1; | ||
273 | int t = (this->hidden->screen_height << this->hidden->yeig) - 1; | ||
274 | |||
275 | block[1] = 0; block[2] = 0; /* Left*/ | ||
276 | block[3] = 0; block[4] = 0; /* Bottom */ | ||
277 | block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */ | ||
278 | block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */ | ||
279 | } else | ||
280 | { | ||
281 | /* Clip to window */ | ||
282 | unsigned char window_state[36]; | ||
283 | |||
284 | *((int *)window_state) = this->hidden->window_handle; | ||
285 | regs.r[1] = (unsigned int)window_state; | ||
286 | _kernel_swi(Wimp_GetWindowState, ®s, ®s); | ||
287 | |||
288 | block[1] = window_state[4]; | ||
289 | block[2] = window_state[5]; | ||
290 | block[3] = window_state[8]; | ||
291 | block[4] = window_state[9]; | ||
292 | block[5] = window_state[12]; | ||
293 | block[6] = window_state[13]; | ||
294 | block[7] = window_state[16]; | ||
295 | block[8] = window_state[17]; | ||
296 | |||
297 | } | ||
298 | |||
299 | regs.r[0] = 21; /* OS word code */ | ||
300 | regs.r[1] = (int)block; | ||
301 | _kernel_swi(OS_Word, ®s, ®s); | ||
302 | } | ||
303 | |||
304 | return mode; | ||
305 | } | ||
306 | |||
307 | /* Save mouse cursor palette to be restore when we are no longer | ||
308 | defining a cursor */ | ||
309 | |||
310 | void WIMP_SaveCursorPalette() | ||
311 | { | ||
312 | _kernel_swi_regs regs; | ||
313 | int colour; | ||
314 | |||
315 | for (colour = 0; colour < 2; colour++) | ||
316 | { | ||
317 | regs.r[0] = (int)wimp_cursor_palette[colour][0]; | ||
318 | regs.r[1] = 25; | ||
319 | /* Read settings with OS_ReadPalette */ | ||
320 | if (_kernel_swi(0x2f, ®s, ®s) == NULL) | ||
321 | { | ||
322 | wimp_cursor_palette[colour][2] = (unsigned char)((regs.r[2] >> 8) & 0xFF); | ||
323 | wimp_cursor_palette[colour][3] = (unsigned char)((regs.r[2] >> 16) & 0xFF); | ||
324 | wimp_cursor_palette[colour][4] = (unsigned char)((regs.r[2] >> 24) & 0xFF); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | cursor_palette_saved = 1; | ||
329 | } | ||
330 | |||
331 | /* Restore the WIMP's cursor when we leave the SDL window */ | ||
332 | void WIMP_RestoreWimpCursor() | ||
333 | { | ||
334 | int colour; | ||
335 | |||
336 | /* Reset to pointer shape 1 */ | ||
337 | _kernel_osbyte(106, 1, 0); | ||
338 | |||
339 | /* Reset pointer colours */ | ||
340 | if (cursor_palette_saved) | ||
341 | { | ||
342 | for (colour = 0; colour < 2; colour++) | ||
343 | { | ||
344 | _kernel_osword(12, (int *)wimp_cursor_palette[colour]); | ||
345 | } | ||
346 | } | ||
347 | cursor_palette_saved = 0; | ||
348 | } | ||
349 | |||
350 | /* Set palette used for SDL mouse cursors */ | ||
351 | void WIMP_SetSDLCursorPalette() | ||
352 | { | ||
353 | /* First time set up the mouse colours */ | ||
354 | Uint8 block[5]; | ||
355 | |||
356 | /* Set up colour 1 as white */ | ||
357 | block[0] = 1; /* Colour to change 1 - 3 */ | ||
358 | block[1] = 25; /* Set pointer colour */ | ||
359 | block[2] = 255; /* red component*/ | ||
360 | block[3] = 255; /* green component */ | ||
361 | block[4] = 255; /* blue component*/ | ||
362 | _kernel_osword(12, (int *)block); | ||
363 | |||
364 | /* Set colour 3 to back */ | ||
365 | block[0] = 3; /* Colour to change 1 - 3 */ | ||
366 | block[1] = 25; /* Set pointer colour*/ | ||
367 | block[2] = 0; /* red component*/ | ||
368 | block[3] = 0; /* green component */ | ||
369 | block[4] = 0; /* blue component*/ | ||
370 | _kernel_osword(12, (int *)block); | ||
371 | } | ||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse_c.h b/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse_c.h new file mode 100644 index 0000000000..9019cb43ca --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosmouse_c.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_riscosvideo.h" | ||
25 | |||
26 | /* The implementation dependent data for the window manager cursor */ | ||
27 | struct WMcursor { | ||
28 | int w; | ||
29 | int h; | ||
30 | int hot_x; | ||
31 | int hot_y; | ||
32 | Uint8 *data; | ||
33 | }; | ||
34 | |||
35 | /* Functions to be exported */ | ||
36 | void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor); | ||
37 | WMcursor *RISCOS_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); | ||
38 | |||
39 | int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor); | ||
40 | void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y); | ||
41 | |||
42 | int WIMP_ShowWMCursor(_THIS, WMcursor *cursor); | ||
43 | void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y); | ||
44 | |||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscossprite.c b/apps/plugins/sdl/src/video/riscos/SDL_riscossprite.c new file mode 100644 index 0000000000..70b2f919db --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscossprite.c | |||
@@ -0,0 +1,265 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 27 March 2003 | ||
27 | |||
28 | Implements Sprite plotting code for wimp display.window | ||
29 | */ | ||
30 | |||
31 | #include "kernel.h" | ||
32 | #include "swis.h" | ||
33 | |||
34 | #include "SDL_stdinc.h" | ||
35 | #include "SDL_riscosvideo.h" | ||
36 | |||
37 | extern void WIMP_ReadModeInfo(_THIS); | ||
38 | |||
39 | void WIMP_PaletteChanged(_THIS); | ||
40 | |||
41 | |||
42 | /* Create sprite buffer for screen */ | ||
43 | |||
44 | unsigned char *WIMP_CreateBuffer(int width, int height, int bpp) | ||
45 | { | ||
46 | int size; | ||
47 | char sprite_name[12] = "display"; | ||
48 | unsigned char *buffer; | ||
49 | _kernel_swi_regs regs; | ||
50 | int bytesPerPixel; | ||
51 | int bytesPerRow; | ||
52 | int offsetToSpriteData = 60; | ||
53 | |||
54 | switch(bpp) | ||
55 | { | ||
56 | case 32: bytesPerPixel = 4; break; | ||
57 | case 16: bytesPerPixel = 2; break; | ||
58 | case 8: | ||
59 | bytesPerPixel = 1; | ||
60 | offsetToSpriteData += 2048; /* Add in size of palette */ | ||
61 | break; | ||
62 | default: | ||
63 | return NULL; | ||
64 | break; | ||
65 | } | ||
66 | |||
67 | bytesPerRow = bytesPerPixel * width; | ||
68 | |||
69 | if ((bytesPerRow & 3) != 0) | ||
70 | { | ||
71 | bytesPerRow += 4 - (bytesPerRow & 3); | ||
72 | } | ||
73 | size = bytesPerRow * height; | ||
74 | |||
75 | buffer = SDL_malloc( (size_t) size + offsetToSpriteData ); | ||
76 | if (!buffer) return NULL; | ||
77 | |||
78 | /* Initialise a sprite area */ | ||
79 | |||
80 | *(unsigned int *)buffer = size + offsetToSpriteData; | ||
81 | *(unsigned int *)(buffer + 8) = 16; | ||
82 | |||
83 | regs.r[0] = 256+9; | ||
84 | regs.r[1] = (unsigned int)buffer; | ||
85 | _kernel_swi(OS_SpriteOp, ®s, ®s); | ||
86 | |||
87 | regs.r[0] = 256+15; | ||
88 | regs.r[1] = (unsigned int)buffer; | ||
89 | regs.r[2] = (unsigned int)&sprite_name; | ||
90 | regs.r[3] = 0; /* Palette flag: 0 = no palette */ | ||
91 | regs.r[4] = width; | ||
92 | regs.r[5] = height; | ||
93 | if (bpp == 8) | ||
94 | { | ||
95 | /* Use old style mode number */ | ||
96 | regs.r[6] = 28; /* 8bpp 90x90dpi */ | ||
97 | } else | ||
98 | { | ||
99 | regs.r[6] = (((bpp == 16) ? 5 : 6) << 27) /* Type 6 = 32bpp sprite, 5 = 16bpp sprite */ | ||
100 | | (90 << 14) /* Vertical dpi */ | ||
101 | | (90 << 1) /* Horizontal dpi */ | ||
102 | | 1; /* Marker to distinguish between mode selectors and sprite modes */ | ||
103 | } | ||
104 | if (_kernel_swi(OS_SpriteOp, ®s, ®s) == NULL) | ||
105 | { | ||
106 | if (bpp == 8) | ||
107 | { | ||
108 | /* Modify sprite to take into account 256 colour palette */ | ||
109 | int *sprite = (int *)(buffer + 16); | ||
110 | /* Adjust sprite offsets */ | ||
111 | sprite[0] += 2048; | ||
112 | sprite[8] += 2048; | ||
113 | sprite[9] += 2048; | ||
114 | /* Adjust sprite area next free pointer */ | ||
115 | (*(int *)(buffer+12)) += 2048; | ||
116 | |||
117 | /* Don't need to set up palette as SDL sets up the default | ||
118 | 256 colour palette */ | ||
119 | /* { | ||
120 | int *pal = sprite + 11; | ||
121 | unsigned int j; | ||
122 | unsigned int entry; | ||
123 | for (j = 0; j < 255; j++) | ||
124 | { | ||
125 | entry = (j << 24) | (j << 16) | (j << 8); | ||
126 | *pal++ = entry; | ||
127 | *pal++ = entry; | ||
128 | } | ||
129 | } | ||
130 | */ | ||
131 | } | ||
132 | } else | ||
133 | { | ||
134 | SDL_free(buffer); | ||
135 | buffer = NULL; | ||
136 | } | ||
137 | |||
138 | return buffer; | ||
139 | } | ||
140 | |||
141 | |||
142 | /* Setup translation buffers for the sprite plotting */ | ||
143 | |||
144 | void WIMP_SetupPlotInfo(_THIS) | ||
145 | { | ||
146 | _kernel_swi_regs regs; | ||
147 | int *sprite = ((int *)this->hidden->bank[1])+4; | ||
148 | |||
149 | regs.r[0] = (unsigned int)this->hidden->bank[1]; | ||
150 | regs.r[1] = (unsigned int)sprite; | ||
151 | regs.r[2] = -1; /* Current mode */ | ||
152 | regs.r[3] = -1; /* Current palette */ | ||
153 | regs.r[4] = 0; /* Get size of buffer */ | ||
154 | regs.r[5] = 1|2|16; /* R1 - pointer to sprite and can use full palette words */ | ||
155 | regs.r[6] = 0; | ||
156 | regs.r[7] = 0; | ||
157 | |||
158 | if (this->hidden->pixtrans) SDL_free(this->hidden->pixtrans); | ||
159 | this->hidden->pixtrans = 0; | ||
160 | |||
161 | /* Get the size required for the buffer */ | ||
162 | _kernel_swi(ColourTrans_GenerateTable, ®s, ®s); | ||
163 | if (regs.r[4]) | ||
164 | { | ||
165 | this->hidden->pixtrans = SDL_malloc(regs.r[4]); | ||
166 | |||
167 | regs.r[4] = (unsigned int)this->hidden->pixtrans; | ||
168 | /* Actually read the buffer */ | ||
169 | _kernel_swi(ColourTrans_GenerateTable, ®s, ®s); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /* Plot the sprite in the given context */ | ||
174 | void WIMP_PlotSprite(_THIS, int x, int y) | ||
175 | { | ||
176 | _kernel_swi_regs regs; | ||
177 | _kernel_oserror *err; | ||
178 | |||
179 | regs.r[0] = 52 + 512; | ||
180 | regs.r[1] = (unsigned int)this->hidden->bank[1]; | ||
181 | regs.r[2] = (unsigned int)this->hidden->bank[1]+16; | ||
182 | regs.r[3] = x; | ||
183 | regs.r[4] = y; | ||
184 | regs.r[5] = 0|32; /* Overwrite screen and pixtrans contains wide colour entries */ | ||
185 | regs.r[6] = 0; /* No scale factors i.e. 1:1 */ | ||
186 | regs.r[7] = (int)this->hidden->pixtrans; | ||
187 | |||
188 | if ((err = _kernel_swi(OS_SpriteOp, ®s, ®s)) != 0) | ||
189 | { | ||
190 | int *p = (int *)this->hidden->pixtrans; | ||
191 | printf("OS_SpriteOp failed \n%s\n",err->errmess); | ||
192 | printf("pixtrans %d\n", (int)this->hidden->pixtrans); | ||
193 | printf("%x %x %x\n", p[0], p[1], p[2]); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | |||
198 | /* Wimp mode has changes so update colour mapping and pixel sizes | ||
199 | of windows and the sprites they plot */ | ||
200 | |||
201 | void WIMP_ModeChanged(_THIS) | ||
202 | { | ||
203 | int oldXeig = this->hidden->xeig; | ||
204 | int oldYeig = this->hidden->yeig; | ||
205 | |||
206 | WIMP_ReadModeInfo(this); | ||
207 | |||
208 | if (oldXeig == this->hidden->xeig && oldYeig == this->hidden->yeig) | ||
209 | { | ||
210 | /* Only need to update the palette */ | ||
211 | WIMP_PaletteChanged(this); | ||
212 | } else | ||
213 | { | ||
214 | _kernel_swi_regs regs; | ||
215 | int window_state[9]; | ||
216 | int extent[4]; | ||
217 | int currWidth, currHeight; | ||
218 | int newWidth, newHeight; | ||
219 | |||
220 | /* Need to resize windows and update the palette */ | ||
221 | WIMP_SetupPlotInfo(this); | ||
222 | |||
223 | |||
224 | window_state[0] = this->hidden->window_handle; | ||
225 | regs.r[1] = (unsigned int)window_state; | ||
226 | _kernel_swi(Wimp_GetWindowState, ®s, ®s); | ||
227 | |||
228 | currWidth = window_state[3] - window_state[1]; | ||
229 | currHeight = window_state[4] - window_state[2]; | ||
230 | |||
231 | newWidth = (currWidth >> oldXeig) << this->hidden->xeig; | ||
232 | newHeight = (currHeight >> oldYeig) << this->hidden->yeig; | ||
233 | /* Need to avoid extent getting too small for visible part | ||
234 | of window */ | ||
235 | extent[0] = 0; | ||
236 | if (currHeight <= newHeight) | ||
237 | { | ||
238 | extent[1] = -newHeight; | ||
239 | } else | ||
240 | { | ||
241 | extent[1] = -currHeight; | ||
242 | } | ||
243 | if (currWidth <= newWidth) | ||
244 | { | ||
245 | extent[2] = newWidth; | ||
246 | } else | ||
247 | { | ||
248 | extent[2] = currWidth; | ||
249 | } | ||
250 | extent[3] = 0; | ||
251 | |||
252 | regs.r[0] = this->hidden->window_handle; | ||
253 | regs.r[1] = (int)extent; | ||
254 | _kernel_swi(Wimp_SetExtent, ®s, ®s); | ||
255 | |||
256 | /*TODO: May need to set flag to resize window on next open */ | ||
257 | } | ||
258 | } | ||
259 | |||
260 | /* Palette has changed so update palettes used for windows sprites */ | ||
261 | |||
262 | void WIMP_PaletteChanged(_THIS) | ||
263 | { | ||
264 | WIMP_SetupPlotInfo(this); | ||
265 | } | ||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscostask.c b/apps/plugins/sdl/src/video/riscos/SDL_riscostask.c new file mode 100644 index 0000000000..67dc3e2fec --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscostask.c | |||
@@ -0,0 +1,350 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | This file added by Alan Buckley (alan_baa@hotmail.com) to support RISC OS | ||
26 | 26 March 2003 | ||
27 | |||
28 | File includes routines for: | ||
29 | Setting up as a WIMP Task | ||
30 | Reading information about the current desktop | ||
31 | Storing information before a switch to full screen | ||
32 | Restoring desktop after switching to full screen | ||
33 | */ | ||
34 | |||
35 | #include "kernel.h" | ||
36 | #include "swis.h" | ||
37 | |||
38 | #include "SDL_stdinc.h" | ||
39 | #include "SDL_riscostask.h" | ||
40 | |||
41 | #if !SDL_THREADS_DISABLED | ||
42 | #include <pthread.h> | ||
43 | pthread_t main_thread; | ||
44 | #endif | ||
45 | |||
46 | /* RISC OS variables */ | ||
47 | |||
48 | static int task_handle = 0; | ||
49 | static int wimp_version = 0; | ||
50 | |||
51 | /* RISC OS variables to help compatability with certain programs */ | ||
52 | int riscos_backbuffer = 0; /* Create a back buffer in system memory for full screen mode */ | ||
53 | int riscos_closeaction = 1; /* Close icon action */ | ||
54 | |||
55 | static int stored_mode = -1; /* -1 when in desktop, mode number or pointer when full screen */ | ||
56 | |||
57 | extern int mouseInWindow; /* Mouse is in WIMP window */ | ||
58 | |||
59 | /* Local function */ | ||
60 | |||
61 | static int RISCOS_GetTaskName(char *task_name, size_t maxlen); | ||
62 | |||
63 | /* Uncomment next line to copy mode changes/restores to stderr */ | ||
64 | /* #define DUMP_MODE */ | ||
65 | #ifdef DUMP_MODE | ||
66 | #include "stdio.h" | ||
67 | static void dump_mode() | ||
68 | { | ||
69 | fprintf(stderr, "mode %d\n", stored_mode); | ||
70 | if (stored_mode < -1 || stored_mode >= 256) | ||
71 | { | ||
72 | int blockSize = 0; | ||
73 | int *storeBlock = (int *)stored_mode; | ||
74 | |||
75 | while(blockSize < 5 || storeBlock[blockSize] != -1) | ||
76 | { | ||
77 | fprintf(stderr, " %d\n", storeBlock[blockSize++]); | ||
78 | } | ||
79 | } | ||
80 | } | ||
81 | #endif | ||
82 | |||
83 | /****************************************************************** | ||
84 | |||
85 | Initialise as RISC OS Wimp task | ||
86 | |||
87 | *******************************************************************/ | ||
88 | |||
89 | int RISCOS_InitTask() | ||
90 | { | ||
91 | char task_name[32]; | ||
92 | _kernel_swi_regs regs; | ||
93 | int messages[4]; | ||
94 | |||
95 | if (RISCOS_GetTaskName(task_name, SDL_arraysize(task_name)) == 0) return 0; | ||
96 | |||
97 | messages[0] = 9; /* Palette changed */ | ||
98 | messages[1] = 0x400c1; /* Mode changed */ | ||
99 | messages[2] = 8; /* Pre quit */ | ||
100 | messages[2] = 0; | ||
101 | |||
102 | regs.r[0] = (unsigned int)360; /* Minimum version 3.6 */ | ||
103 | regs.r[1] = (unsigned int)0x4b534154; | ||
104 | regs.r[2] = (unsigned int)task_name; | ||
105 | regs.r[3] = (unsigned int)messages; | ||
106 | |||
107 | if (_kernel_swi(Wimp_Initialise, ®s, ®s) == 0) | ||
108 | { | ||
109 | wimp_version = regs.r[0]; | ||
110 | task_handle = regs.r[1]; | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | #if !SDL_THREADS_DISABLED | ||
115 | main_thread = pthread_self(); | ||
116 | #endif | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | /********************************************************************* | ||
122 | |||
123 | Close down application on exit. | ||
124 | |||
125 | **********************************************************************/ | ||
126 | |||
127 | void RISCOS_ExitTask() | ||
128 | { | ||
129 | _kernel_swi_regs regs; | ||
130 | |||
131 | if (stored_mode == -1) | ||
132 | { | ||
133 | /* Ensure cursor is put back to standard pointer shape if | ||
134 | we have been running in a window */ | ||
135 | _kernel_osbyte(106,1,0); | ||
136 | } | ||
137 | |||
138 | /* Ensure we end up back in the wimp */ | ||
139 | RISCOS_RestoreWimpMode(); | ||
140 | |||
141 | /* Neatly exit the task */ | ||
142 | regs.r[0] = task_handle; | ||
143 | regs.r[1] = (unsigned int)0x4b534154; | ||
144 | _kernel_swi(Wimp_CloseDown, ®s, ®s); | ||
145 | task_handle = 0; | ||
146 | } | ||
147 | |||
148 | /************************************************************************** | ||
149 | |||
150 | Get the name of the task for the desktop. | ||
151 | |||
152 | Param: task_name - name of task 32 characters. | ||
153 | |||
154 | Returns: 1 is successful, otherwise 0 | ||
155 | |||
156 | Notes: Works by getting using OS_GetEnv to get the command line | ||
157 | used to run the program and then parsing a name from it | ||
158 | as follows. | ||
159 | |||
160 | 1. Use name after final period if not !RunImage | ||
161 | 2. If name is !RunImage then process item before the period | ||
162 | in front of !RunImage. | ||
163 | 3. If directory name use that | ||
164 | 4. if in form <XXX$Dir> use the XXX. | ||
165 | |||
166 | Finally once this value has been retrieved use it unless | ||
167 | there is a variable set up in the form SDL$<name>$TaskName | ||
168 | in which case the value of this variable will be used. | ||
169 | |||
170 | Now also gets other RISC OS configuration varibles | ||
171 | SDL$<name>$BackBuffer - set to 1 to use a system memory backbuffer in fullscreen mode | ||
172 | so updates wait until a call to SDL_UpdateRects. (default 0) | ||
173 | This is required for programmes where they have assumed this is | ||
174 | always the case which is contrary to the documentation. | ||
175 | SDL$<name>$CloseAction | ||
176 | 0 Don't show close icon | ||
177 | 1 Show close icon | ||
178 | |||
179 | ***************************************************************************/ | ||
180 | |||
181 | int RISCOS_GetTaskName(char *task_name, size_t maxlen) | ||
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 | size_t len = SDL_strlen(command_line)+1; | ||
192 | char *buffer = SDL_stack_alloc(char, len); | ||
193 | char *env_var; | ||
194 | char *p; | ||
195 | |||
196 | SDL_strlcpy(buffer, command_line, len); | ||
197 | p = SDL_strchr(buffer, ' '); | ||
198 | if (p) *p = 0; | ||
199 | p = SDL_strrchr(buffer, '.'); | ||
200 | if (p == 0) p = buffer; | ||
201 | if (stricmp(p+1,"!RunImage") == 0) | ||
202 | { | ||
203 | *p = 0; | ||
204 | p = SDL_strrchr(buffer, '.'); | ||
205 | if (p == 0) p = buffer; | ||
206 | } | ||
207 | if (*p == '.') p++; | ||
208 | if (*p == '!') p++; /* Skip "!" at beginning of application directories */ | ||
209 | |||
210 | if (*p == '<') | ||
211 | { | ||
212 | // Probably in the form <appname$Dir> | ||
213 | char *q = SDL_strchr(p, '$'); | ||
214 | if (q == 0) q = SDL_strchr(p,'>'); /* Use variable name if not */ | ||
215 | if (q) *q = 0; | ||
216 | p++; /* Move over the < */ | ||
217 | } | ||
218 | |||
219 | if (*p) | ||
220 | { | ||
221 | /* Read variables that effect the RISC OS SDL engine for this task */ | ||
222 | len = SDL_strlen(p) + 18; /* 18 is larger than the biggest variable name */ | ||
223 | env_var = SDL_stack_alloc(char, len); | ||
224 | if (env_var) | ||
225 | { | ||
226 | char *env_val; | ||
227 | |||
228 | /* See if a variable of form SDL$<dirname>$TaskName exists */ | ||
229 | |||
230 | SDL_strlcpy(env_var, "SDL$", len); | ||
231 | SDL_strlcat(env_var, p, len); | ||
232 | SDL_strlcat(env_var, "$TaskName", len); | ||
233 | |||
234 | env_val = SDL_getenv(env_var); | ||
235 | if (env_val) SDL_strlcpy(task_name, env_val, maxlen); | ||
236 | |||
237 | SDL_strlcpy(env_var, "SDL$", len); | ||
238 | SDL_strlcat(env_var, p, len); | ||
239 | SDL_strlcat(env_var, "$BackBuffer", len); | ||
240 | |||
241 | env_val = SDL_getenv(env_var); | ||
242 | if (env_val) riscos_backbuffer = atoi(env_val); | ||
243 | |||
244 | SDL_strlcpy(env_var, "SDL$", len); | ||
245 | SDL_strlcat(env_var, p, len); | ||
246 | SDL_strlcat(env_var, "$CloseAction", len); | ||
247 | |||
248 | env_val = SDL_getenv(env_var); | ||
249 | if (env_val && SDL_strcmp(env_val,"0") == 0) riscos_closeaction = 0; | ||
250 | |||
251 | SDL_stack_free(env_var); | ||
252 | } | ||
253 | |||
254 | if (!*task_name) SDL_strlcpy(task_name, p, maxlen); | ||
255 | } | ||
256 | |||
257 | SDL_stack_free(buffer); | ||
258 | } | ||
259 | |||
260 | if (task_name[0] == 0) SDL_strlcpy(task_name, "SDL Task", maxlen); | ||
261 | |||
262 | return 1; | ||
263 | } | ||
264 | |||
265 | /***************************************************************** | ||
266 | |||
267 | Store the current desktop screen mode if we are in the desktop. | ||
268 | |||
269 | ******************************************************************/ | ||
270 | |||
271 | void RISCOS_StoreWimpMode() | ||
272 | { | ||
273 | _kernel_swi_regs regs; | ||
274 | |||
275 | /* Don't store if in full screen mode */ | ||
276 | if (stored_mode != -1) return; | ||
277 | |||
278 | regs.r[0] = 1; | ||
279 | _kernel_swi(OS_ScreenMode, ®s, ®s); | ||
280 | if (regs.r[1] >= 0 && regs.r[1] < 256) stored_mode = regs.r[1]; | ||
281 | else | ||
282 | { | ||
283 | int blockSize = 0; | ||
284 | int *retBlock = (int *)regs.r[1]; | ||
285 | int *storeBlock; | ||
286 | int j; | ||
287 | |||
288 | while(blockSize < 5 || retBlock[blockSize] != -1) blockSize++; | ||
289 | blockSize++; | ||
290 | storeBlock = (int *)SDL_malloc(blockSize * sizeof(int)); | ||
291 | retBlock = (int *)regs.r[1]; | ||
292 | for ( j = 0; j < blockSize; j++) | ||
293 | storeBlock[j] = retBlock[j]; | ||
294 | |||
295 | stored_mode = (int)storeBlock; | ||
296 | } | ||
297 | #if DUMP_MODE | ||
298 | fprintf(stderr, "Stored "); dump_mode(); | ||
299 | #endif | ||
300 | } | ||
301 | |||
302 | /***************************************************************** | ||
303 | |||
304 | Restore desktop screen mode if we are in full screen mode. | ||
305 | |||
306 | *****************************************************************/ | ||
307 | |||
308 | void RISCOS_RestoreWimpMode() | ||
309 | { | ||
310 | _kernel_swi_regs regs; | ||
311 | |||
312 | /* Only need to restore if we are in full screen mode */ | ||
313 | if (stored_mode == -1) return; | ||
314 | |||
315 | #if DUMP_MODE | ||
316 | fprintf(stderr, "Restored"); dump_mode(); | ||
317 | #endif | ||
318 | |||
319 | regs.r[0] = stored_mode; | ||
320 | _kernel_swi(Wimp_SetMode, ®s, ®s); | ||
321 | if (stored_mode < 0 || stored_mode > 256) | ||
322 | { | ||
323 | SDL_free((int *)stored_mode); | ||
324 | } | ||
325 | stored_mode = -1; | ||
326 | |||
327 | /* Flush keyboard buffer to dump the keystrokes we've already polled */ | ||
328 | regs.r[0] = 21; | ||
329 | regs.r[1] = 0; /* Keyboard buffer number */ | ||
330 | _kernel_swi(OS_Byte, ®s, ®s); | ||
331 | |||
332 | mouseInWindow = 0; | ||
333 | |||
334 | } | ||
335 | |||
336 | /********************************************************************* | ||
337 | |||
338 | Get version of Wimp running when task was initialised. | ||
339 | |||
340 | *********************************************************************/ | ||
341 | |||
342 | int RISCOS_GetWimpVersion() | ||
343 | { | ||
344 | return wimp_version; | ||
345 | } | ||
346 | |||
347 | int RISCOS_GetTaskHandle() | ||
348 | { | ||
349 | return task_handle; | ||
350 | } | ||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscostask.h b/apps/plugins/sdl/src/video/riscos/SDL_riscostask.h new file mode 100644 index 0000000000..5744afa9db --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscostask.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | This file added by Alan Buckley (alan_baa@hotmail.com) to support RISC OS | ||
26 | 26 March 2003 | ||
27 | */ | ||
28 | |||
29 | /* Task initialisation/Clean up */ | ||
30 | |||
31 | extern int RISCOS_InitTask(); | ||
32 | extern void RISCOS_ExitTask(); | ||
33 | extern int RISCOS_GetWimpVersion(); | ||
34 | extern int RISCOS_GetTaskHandle(); | ||
35 | |||
36 | |||
37 | /* Wimp mode saveing/restoring */ | ||
38 | extern void RISCOS_StoreWimpMode(); | ||
39 | extern void RISCOS_RestoreWimpMode(); | ||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.c b/apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.c new file mode 100644 index 0000000000..bae5e374d9 --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.c | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 23 March 2003 | ||
27 | |||
28 | Implements RISC OS display device management. | ||
29 | Routines for full screen and wimp modes are split | ||
30 | into other source files. | ||
31 | */ | ||
32 | |||
33 | #include "SDL_video.h" | ||
34 | #include "SDL_mouse.h" | ||
35 | #include "SDL_syswm.h" | ||
36 | #include "../SDL_sysvideo.h" | ||
37 | #include "../SDL_pixels_c.h" | ||
38 | #include "../../events/SDL_events_c.h" | ||
39 | |||
40 | #include "SDL_riscostask.h" | ||
41 | #include "SDL_riscosvideo.h" | ||
42 | #include "SDL_riscosevents_c.h" | ||
43 | #include "SDL_riscosmouse_c.h" | ||
44 | |||
45 | #include "kernel.h" | ||
46 | #include "swis.h" | ||
47 | |||
48 | #define RISCOSVID_DRIVER_NAME "riscos" | ||
49 | |||
50 | /* Initialization/Query functions */ | ||
51 | static int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat); | ||
52 | static void RISCOS_VideoQuit(_THIS); | ||
53 | |||
54 | static SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | ||
55 | static SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | ||
56 | |||
57 | int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info); | ||
58 | |||
59 | int RISCOS_ToggleFullScreen(_THIS, int fullscreen); | ||
60 | /* Mouse checking */ | ||
61 | void RISCOS_CheckMouseMode(_THIS); | ||
62 | extern SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode); | ||
63 | |||
64 | /* Fullscreen mode functions */ | ||
65 | extern SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | ||
66 | extern void FULLSCREEN_BuildModeList(_THIS); | ||
67 | extern void FULLSCREEN_SetDeviceMode(_THIS); | ||
68 | extern int FULLSCREEN_ToggleFromWimp(_THIS); | ||
69 | |||
70 | /* Wimp mode functions */ | ||
71 | extern SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | ||
72 | extern void WIMP_DeleteWindow(_THIS); | ||
73 | extern int WIMP_ToggleFromFullScreen(_THIS); | ||
74 | |||
75 | /* Hardware surface functions - common to WIMP and FULLSCREEN */ | ||
76 | static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface); | ||
77 | static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface); | ||
78 | static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface); | ||
79 | static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface); | ||
80 | |||
81 | /* RISC OS driver bootstrap functions */ | ||
82 | |||
83 | static int RISCOS_Available(void) | ||
84 | { | ||
85 | return(1); | ||
86 | } | ||
87 | |||
88 | static void RISCOS_DeleteDevice(SDL_VideoDevice *device) | ||
89 | { | ||
90 | SDL_free(device->hidden); | ||
91 | SDL_free(device); | ||
92 | } | ||
93 | |||
94 | static SDL_VideoDevice *RISCOS_CreateDevice(int devindex) | ||
95 | { | ||
96 | SDL_VideoDevice *device; | ||
97 | |||
98 | /* Initialize all variables that we clean on shutdown */ | ||
99 | device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); | ||
100 | if ( device ) { | ||
101 | SDL_memset(device, 0, (sizeof *device)); | ||
102 | device->hidden = (struct SDL_PrivateVideoData *) | ||
103 | SDL_malloc((sizeof *device->hidden)); | ||
104 | } | ||
105 | if ( (device == NULL) || (device->hidden == NULL) ) { | ||
106 | SDL_OutOfMemory(); | ||
107 | if ( device ) { | ||
108 | SDL_free(device); | ||
109 | } | ||
110 | return(0); | ||
111 | } | ||
112 | SDL_memset(device->hidden, 0, (sizeof *device->hidden)); | ||
113 | |||
114 | /* Set the function pointers */ | ||
115 | device->VideoInit = RISCOS_VideoInit; | ||
116 | device->VideoQuit = RISCOS_VideoQuit; | ||
117 | |||
118 | device->ListModes = RISCOS_ListModes; | ||
119 | device->SetVideoMode = RISCOS_SetVideoMode; | ||
120 | device->CreateYUVOverlay = NULL; | ||
121 | device->AllocHWSurface = RISCOS_AllocHWSurface; | ||
122 | device->CheckHWBlit = NULL; | ||
123 | device->FillHWRect = NULL; | ||
124 | device->SetHWColorKey = NULL; | ||
125 | device->SetHWAlpha = NULL; | ||
126 | device->LockHWSurface = RISCOS_LockHWSurface; | ||
127 | device->UnlockHWSurface = RISCOS_UnlockHWSurface; | ||
128 | device->FreeHWSurface = RISCOS_FreeHWSurface; | ||
129 | |||
130 | device->FreeWMCursor = RISCOS_FreeWMCursor; | ||
131 | device->CreateWMCursor = RISCOS_CreateWMCursor; | ||
132 | device->CheckMouseMode = RISCOS_CheckMouseMode; | ||
133 | device->GrabInput = RISCOS_GrabInput; | ||
134 | |||
135 | device->InitOSKeymap = RISCOS_InitOSKeymap; | ||
136 | |||
137 | device->GetWMInfo = RISCOS_GetWmInfo; | ||
138 | |||
139 | device->free = RISCOS_DeleteDevice; | ||
140 | |||
141 | /* Can't get Toggle screen to work if program starts up in Full screen mode so | ||
142 | disable it here and re-enable it when a wimp screen is chosen */ | ||
143 | device->ToggleFullScreen = NULL; /*RISCOS_ToggleFullScreen;*/ | ||
144 | |||
145 | /* Set other entries for fullscreen mode */ | ||
146 | FULLSCREEN_SetDeviceMode(device); | ||
147 | |||
148 | /* Mouse pointer needs to use the WIMP ShowCursor version so | ||
149 | that it doesn't modify the pointer until the SDL Window is | ||
150 | entered or the application goes full screen */ | ||
151 | device->ShowWMCursor = WIMP_ShowWMCursor; | ||
152 | |||
153 | return device; | ||
154 | } | ||
155 | |||
156 | VideoBootStrap RISCOS_bootstrap = { | ||
157 | RISCOSVID_DRIVER_NAME, "RISC OS video driver", | ||
158 | RISCOS_Available, RISCOS_CreateDevice | ||
159 | }; | ||
160 | |||
161 | |||
162 | int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat) | ||
163 | { | ||
164 | _kernel_swi_regs regs; | ||
165 | int vars[4], vals[3]; | ||
166 | |||
167 | if (RISCOS_InitTask() == 0) | ||
168 | { | ||
169 | SDL_SetError("Unable to start task"); | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | vars[0] = 9; /* Log base 2 bpp */ | ||
174 | vars[1] = 11; /* XWndLimit - num x pixels -1 */ | ||
175 | vars[2] = 12; /* YWndLimit - num y pixels -1 */ | ||
176 | vars[3] = -1; /* Terminate list */ | ||
177 | regs.r[0] = (int)vars; | ||
178 | regs.r[1] = (int)vals; | ||
179 | |||
180 | _kernel_swi(OS_ReadVduVariables, ®s, ®s); | ||
181 | vformat->BitsPerPixel = (1 << vals[0]); | ||
182 | |||
183 | /* Determine the current screen size */ | ||
184 | this->info.current_w = vals[1] + 1; | ||
185 | this->info.current_h = vals[2] + 1; | ||
186 | |||
187 | /* Minimum bpp for SDL is 8 */ | ||
188 | if (vformat->BitsPerPixel < 8) vformat->BitsPerPixel = 8; | ||
189 | |||
190 | |||
191 | switch (vformat->BitsPerPixel) | ||
192 | { | ||
193 | case 15: | ||
194 | case 16: | ||
195 | vformat->Bmask = 0x00007c00; | ||
196 | vformat->Gmask = 0x000003e0; | ||
197 | vformat->Rmask = 0x0000001f; | ||
198 | vformat->BitsPerPixel = 16; /* SDL wants actual number of bits used */ | ||
199 | vformat->BytesPerPixel = 2; | ||
200 | break; | ||
201 | |||
202 | case 24: | ||
203 | case 32: | ||
204 | vformat->Bmask = 0x00ff0000; | ||
205 | vformat->Gmask = 0x0000ff00; | ||
206 | vformat->Rmask = 0x000000ff; | ||
207 | vformat->BytesPerPixel = 4; | ||
208 | break; | ||
209 | |||
210 | default: | ||
211 | vformat->Bmask = 0; | ||
212 | vformat->Gmask = 0; | ||
213 | vformat->Rmask = 0; | ||
214 | vformat->BytesPerPixel = 1; | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | /* Fill in some window manager capabilities */ | ||
219 | this->info.wm_available = 1; | ||
220 | |||
221 | /* We're done! */ | ||
222 | return(0); | ||
223 | } | ||
224 | |||
225 | /* Note: If we are terminated, this could be called in the middle of | ||
226 | another SDL video routine -- notably UpdateRects. | ||
227 | */ | ||
228 | void RISCOS_VideoQuit(_THIS) | ||
229 | { | ||
230 | RISCOS_ExitTask(); | ||
231 | |||
232 | if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank); | ||
233 | this->hidden->alloc_bank = 0; | ||
234 | } | ||
235 | |||
236 | |||
237 | SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | ||
238 | { | ||
239 | if (flags & SDL_FULLSCREEN) | ||
240 | { | ||
241 | /* Build mode list when first required. */ | ||
242 | if (SDL_nummodes[0] == 0) FULLSCREEN_BuildModeList(this); | ||
243 | |||
244 | return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]); | ||
245 | } else | ||
246 | return (SDL_Rect **)-1; | ||
247 | } | ||
248 | |||
249 | |||
250 | /* Set up video mode */ | ||
251 | SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current, | ||
252 | int width, int height, int bpp, Uint32 flags) | ||
253 | { | ||
254 | if (flags & SDL_FULLSCREEN) | ||
255 | { | ||
256 | RISCOS_StoreWimpMode(); | ||
257 | /* Dump wimp window on switch to full screen */ | ||
258 | if (this->hidden->window_handle) WIMP_DeleteWindow(this); | ||
259 | |||
260 | return FULLSCREEN_SetVideoMode(this, current, width, height, bpp, flags); | ||
261 | } else | ||
262 | { | ||
263 | RISCOS_RestoreWimpMode(); | ||
264 | return WIMP_SetVideoMode(this, current, width, height, bpp, flags); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | |||
269 | /* We don't actually allow hardware surfaces other than the main one */ | ||
270 | static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface) | ||
271 | { | ||
272 | return(-1); | ||
273 | } | ||
274 | static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface) | ||
275 | { | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | /* We need to wait for vertical retrace on page flipped displays */ | ||
280 | static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface) | ||
281 | { | ||
282 | return(0); | ||
283 | } | ||
284 | |||
285 | static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface) | ||
286 | { | ||
287 | return; | ||
288 | } | ||
289 | |||
290 | |||
291 | int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info) | ||
292 | { | ||
293 | SDL_VERSION(&(info->version)); | ||
294 | info->wimpVersion = RISCOS_GetWimpVersion(); | ||
295 | info->taskHandle = RISCOS_GetTaskHandle(); | ||
296 | info->window = this->hidden->window_handle; | ||
297 | |||
298 | return 1; | ||
299 | } | ||
300 | /* Toggle full screen mode. | ||
301 | Returns 1 if successful otherwise 0 | ||
302 | */ | ||
303 | |||
304 | int RISCOS_ToggleFullScreen(_THIS, int fullscreen) | ||
305 | { | ||
306 | if (fullscreen) | ||
307 | { | ||
308 | return FULLSCREEN_ToggleFromWimp(this); | ||
309 | } else | ||
310 | { | ||
311 | return WIMP_ToggleFromFullScreen(this); | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.h b/apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.h new file mode 100644 index 0000000000..7c717ad667 --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #ifndef _SDL_riscosvideo_h | ||
25 | #define _SDL_riscosvideo_h | ||
26 | |||
27 | #include "SDL_mouse.h" | ||
28 | #include "SDL_mutex.h" | ||
29 | #include "../SDL_sysvideo.h" | ||
30 | |||
31 | /* Hidden "this" pointer for the video functions */ | ||
32 | #define _THIS SDL_VideoDevice *this | ||
33 | |||
34 | |||
35 | /* Private display data */ | ||
36 | |||
37 | struct SDL_PrivateVideoData { | ||
38 | unsigned char *bank[2]; | ||
39 | int current_bank; | ||
40 | unsigned char *alloc_bank; | ||
41 | int height; | ||
42 | int xeig; | ||
43 | int yeig; | ||
44 | int screen_bpp; | ||
45 | int screen_width; | ||
46 | int screen_height; | ||
47 | char *pixtrans; | ||
48 | |||
49 | /* Wimp variables */ | ||
50 | unsigned int window_handle; | ||
51 | char title[256]; | ||
52 | |||
53 | #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ | ||
54 | int SDL_nummodes[NUM_MODELISTS]; | ||
55 | SDL_Rect **SDL_modelist[NUM_MODELISTS]; | ||
56 | }; | ||
57 | |||
58 | /* Old variable names */ | ||
59 | #define SDL_nummodes (this->hidden->SDL_nummodes) | ||
60 | #define SDL_modelist (this->hidden->SDL_modelist) | ||
61 | |||
62 | #endif /* _SDL_risosvideo_h */ | ||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c b/apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c new file mode 100644 index 0000000000..4999664536 --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c | |||
@@ -0,0 +1,330 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 27 March 2003 | ||
27 | |||
28 | Implements Pumping of events and WIMP polling | ||
29 | */ | ||
30 | |||
31 | #include "SDL.h" | ||
32 | #include "SDL_syswm.h" | ||
33 | #include "../../events/SDL_sysevents.h" | ||
34 | #include "../../events/SDL_events_c.h" | ||
35 | #include "SDL_riscosvideo.h" | ||
36 | #include "SDL_riscosevents_c.h" | ||
37 | #include "SDL_riscosmouse_c.h" | ||
38 | #include "../../timer/SDL_timer_c.h" | ||
39 | |||
40 | #include "memory.h" | ||
41 | #include "stdlib.h" | ||
42 | #include "ctype.h" | ||
43 | |||
44 | #include "kernel.h" | ||
45 | #include "swis.h" | ||
46 | #include "unixlib/os.h" | ||
47 | |||
48 | #if !SDL_THREADS_DISABLED | ||
49 | #include <pthread.h> | ||
50 | #endif | ||
51 | |||
52 | /* Local functions */ | ||
53 | void WIMP_Poll(_THIS, int waitTime); | ||
54 | void WIMP_SetFocus(int win); | ||
55 | |||
56 | /* SDL_riscossprite functions */ | ||
57 | void WIMP_PlotSprite(_THIS, int x, int y); | ||
58 | void WIMP_ModeChanged(_THIS); | ||
59 | void WIMP_PaletteChanged(_THIS); | ||
60 | |||
61 | |||
62 | extern void WIMP_PollMouse(_THIS); | ||
63 | extern void RISCOS_PollKeyboard(); | ||
64 | |||
65 | #if SDL_THREADS_DISABLED | ||
66 | /* Timer running function */ | ||
67 | extern void RISCOS_CheckTimer(); | ||
68 | #else | ||
69 | extern int riscos_using_threads; | ||
70 | #endif | ||
71 | |||
72 | /* Mouse cursor handling */ | ||
73 | extern void WIMP_ReshowCursor(_THIS); | ||
74 | extern void WIMP_RestoreWimpCursor(); | ||
75 | |||
76 | int hasFocus = 0; | ||
77 | int mouseInWindow = 0; | ||
78 | |||
79 | /* Flag to ensure window is correct size after a mode change */ | ||
80 | static int resizeOnOpen = 0; | ||
81 | |||
82 | void WIMP_PumpEvents(_THIS) | ||
83 | { | ||
84 | WIMP_Poll(this, 0); | ||
85 | if (hasFocus) RISCOS_PollKeyboard(); | ||
86 | if (mouseInWindow) WIMP_PollMouse(this); | ||
87 | #if SDL_THREADS_DISABLED | ||
88 | if (SDL_timer_running) RISCOS_CheckTimer(); | ||
89 | #endif | ||
90 | } | ||
91 | |||
92 | |||
93 | void WIMP_Poll(_THIS, int waitTime) | ||
94 | { | ||
95 | _kernel_swi_regs regs; | ||
96 | int message[64]; | ||
97 | unsigned int code; | ||
98 | int pollMask = 0; | ||
99 | int doPoll = 1; | ||
100 | int sysEvent; | ||
101 | int sdlWindow = this->hidden->window_handle; | ||
102 | |||
103 | if (this->PumpEvents != WIMP_PumpEvents) return; | ||
104 | |||
105 | if (waitTime > 0) | ||
106 | { | ||
107 | _kernel_swi(OS_ReadMonotonicTime, ®s, ®s); | ||
108 | waitTime += regs.r[0]; | ||
109 | } | ||
110 | |||
111 | while (doPoll) | ||
112 | { | ||
113 | #if !SDL_THREADS_DISABLED | ||
114 | /* Stop thread callbacks while program is paged out */ | ||
115 | if (riscos_using_threads) __pthread_stop_ticker(); | ||
116 | #endif | ||
117 | |||
118 | if (waitTime <= 0) | ||
119 | { | ||
120 | regs.r[0] = pollMask; /* Poll Mask */ | ||
121 | /* For no wait time mask out null event so we wait until something happens */ | ||
122 | if (waitTime < 0) regs.r[0] |= 1; | ||
123 | regs.r[1] = (int)message; | ||
124 | _kernel_swi(Wimp_Poll, ®s, ®s); | ||
125 | } else | ||
126 | { | ||
127 | regs.r[0] = pollMask; | ||
128 | regs.r[1] = (int)message; | ||
129 | regs.r[2] = waitTime; | ||
130 | _kernel_swi(Wimp_PollIdle, ®s, ®s); | ||
131 | } | ||
132 | |||
133 | /* Flag to specify if we post a SDL_SysWMEvent */ | ||
134 | sysEvent = 0; | ||
135 | |||
136 | code = (unsigned int)regs.r[0]; | ||
137 | |||
138 | switch(code) | ||
139 | { | ||
140 | case 0: /* Null Event - drop out for standard processing*/ | ||
141 | doPoll = 0; | ||
142 | break; | ||
143 | |||
144 | case 1: /* Redraw window */ | ||
145 | _kernel_swi(Wimp_RedrawWindow, ®s,®s); | ||
146 | if (message[0] == sdlWindow) | ||
147 | { | ||
148 | while (regs.r[0]) | ||
149 | { | ||
150 | WIMP_PlotSprite(this, message[1], message[2]); | ||
151 | _kernel_swi(Wimp_GetRectangle, ®s, ®s); | ||
152 | } | ||
153 | } else | ||
154 | { | ||
155 | /* TODO: Currently we just eat them - we may need to pass them on */ | ||
156 | while (regs.r[0]) | ||
157 | { | ||
158 | _kernel_swi(Wimp_GetRectangle, ®s, ®s); | ||
159 | } | ||
160 | } | ||
161 | break; | ||
162 | |||
163 | case 2: /* Open window */ | ||
164 | if ( resizeOnOpen && message[0] == sdlWindow) | ||
165 | { | ||
166 | /* Ensure window is correct size */ | ||
167 | resizeOnOpen = 0; | ||
168 | message[3] = message[1] + (this->screen->w << this->hidden->xeig); | ||
169 | message[4] = message[2] + (this->screen->h << this->hidden->yeig); | ||
170 | } | ||
171 | _kernel_swi(Wimp_OpenWindow, ®s, ®s); | ||
172 | break; | ||
173 | |||
174 | case 3: /* Close window */ | ||
175 | if (message[0] == sdlWindow) | ||
176 | { | ||
177 | /* Documentation makes it looks as if the following line is correct: | ||
178 | ** if (SDL_PrivateQuit() == 1) _kernel_swi(Wimp_CloseWindow, ®s, ®s); | ||
179 | ** However some programs don't process this message and so sit there invisibly | ||
180 | ** in the background so I just post the quit message and hope the application | ||
181 | ** does the correct thing. | ||
182 | */ | ||
183 | SDL_PrivateQuit(); | ||
184 | } else | ||
185 | sysEvent = 1; | ||
186 | doPoll = 0; | ||
187 | break; | ||
188 | |||
189 | case 4: /* Pointer_Leaving_Window */ | ||
190 | if (message[0] == sdlWindow) | ||
191 | { | ||
192 | mouseInWindow = 0; | ||
193 | //TODO: Lose buttons / dragging | ||
194 | /* Reset to default pointer */ | ||
195 | WIMP_RestoreWimpCursor(); | ||
196 | SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); | ||
197 | } else | ||
198 | sysEvent = 1; | ||
199 | break; | ||
200 | |||
201 | case 5: /* Pointer_Entering_Window */ | ||
202 | if (message[0] == sdlWindow) | ||
203 | { | ||
204 | mouseInWindow = 1; | ||
205 | WIMP_ReshowCursor(this); | ||
206 | SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | ||
207 | } else sysEvent = 1; | ||
208 | break; | ||
209 | |||
210 | case 6: /* Mouse_Click */ | ||
211 | if (hasFocus == 0) | ||
212 | { | ||
213 | /* First click gives focus if it's not a menu */ | ||
214 | /* we only count non-menu clicks on a window that has the focus */ | ||
215 | WIMP_SetFocus(message[3]); | ||
216 | } else | ||
217 | doPoll = 0; // So PollMouse gets a chance to pick it up | ||
218 | break; | ||
219 | |||
220 | case 7: /* User_Drag_Box - Used for mouse release */ | ||
221 | //TODO: May need to implement this in the future | ||
222 | sysEvent = 1; | ||
223 | break; | ||
224 | |||
225 | case 8: /* Keypressed */ | ||
226 | doPoll = 0; /* PollKeyboard should pick it up */ | ||
227 | if (message[0] != sdlWindow) sysEvent = 1; | ||
228 | /*TODO: May want to always pass F12 etc to the wimp | ||
229 | { | ||
230 | regs.r[0] = message[6]; | ||
231 | _kernel_swi(Wimp_ProcessKey, ®s, ®s); | ||
232 | } | ||
233 | */ | ||
234 | break; | ||
235 | |||
236 | case 11: /* Lose Caret */ | ||
237 | hasFocus = 0; | ||
238 | if (message[0] == sdlWindow) SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); | ||
239 | else sysEvent = 1; | ||
240 | break; | ||
241 | |||
242 | case 12: /* Gain Caret */ | ||
243 | hasFocus = 1; | ||
244 | if (message[0] == sdlWindow) SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); | ||
245 | else sysEvent = 1; | ||
246 | break; | ||
247 | |||
248 | case 17: | ||
249 | case 18: | ||
250 | sysEvent = 1; /* All messages are passed on */ | ||
251 | |||
252 | switch(message[4]) | ||
253 | { | ||
254 | case 0: /* Quit Event */ | ||
255 | /* No choice - have to quit */ | ||
256 | SDL_Quit(); | ||
257 | exit(0); | ||
258 | break; | ||
259 | |||
260 | case 8: /* Pre Quit */ | ||
261 | SDL_PrivateQuit(); | ||
262 | break; | ||
263 | |||
264 | case 0x400c1: /* Mode change */ | ||
265 | WIMP_ModeChanged(this); | ||
266 | resizeOnOpen = 1; | ||
267 | break; | ||
268 | |||
269 | case 9: /* Palette changed */ | ||
270 | WIMP_PaletteChanged(this); | ||
271 | break; | ||
272 | } | ||
273 | break; | ||
274 | |||
275 | default: | ||
276 | /* Pass unknown events on */ | ||
277 | sysEvent = 1; | ||
278 | break; | ||
279 | } | ||
280 | |||
281 | if (sysEvent) | ||
282 | { | ||
283 | SDL_SysWMmsg wmmsg; | ||
284 | |||
285 | SDL_VERSION(&wmmsg.version); | ||
286 | wmmsg.eventCode = code; | ||
287 | SDL_memcpy(wmmsg.pollBlock, message, 64 * sizeof(int)); | ||
288 | |||
289 | /* Fall out of polling loop if message is successfully posted */ | ||
290 | if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0; | ||
291 | } | ||
292 | #if !SDL_THREADS_DISABLED | ||
293 | if (riscos_using_threads) | ||
294 | { | ||
295 | /* Restart ticker here so other thread can not interfere | ||
296 | with the Redraw processing */ | ||
297 | if (riscos_using_threads) __pthread_start_ticker(); | ||
298 | /* Give other threads a better chance of running */ | ||
299 | pthread_yield(); | ||
300 | } | ||
301 | #endif | ||
302 | } | ||
303 | } | ||
304 | |||
305 | /* Set focus to specified window */ | ||
306 | void WIMP_SetFocus(int win) | ||
307 | { | ||
308 | _kernel_swi_regs regs; | ||
309 | |||
310 | regs.r[0] = win; | ||
311 | regs.r[1] = -1; /* Icon handle */ | ||
312 | regs.r[2] = 0; /* X-offset we just put it at position 0 */ | ||
313 | regs.r[3] = 0; /* Y-offset as above */ | ||
314 | regs.r[4] = 1 << 25; /* Caret is invisible */ | ||
315 | regs.r[5] = 0; /* index into string */ | ||
316 | |||
317 | _kernel_swi(Wimp_SetCaretPosition, ®s, ®s); | ||
318 | } | ||
319 | |||
320 | /** Run background task while in a sleep command */ | ||
321 | void RISCOS_BackgroundTasks(void) | ||
322 | { | ||
323 | if (current_video && current_video->hidden->window_handle) | ||
324 | { | ||
325 | WIMP_Poll(current_video, 0); | ||
326 | } | ||
327 | #if SDL_THREADS_DISABLED | ||
328 | if (SDL_timer_running) RISCOS_CheckTimer(); | ||
329 | #endif | ||
330 | } | ||
diff --git a/apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c b/apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c new file mode 100644 index 0000000000..0f9c5451d7 --- /dev/null +++ b/apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c | |||
@@ -0,0 +1,501 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability | ||
26 | 27 March 2003 | ||
27 | |||
28 | Implements RISC OS Wimp display. | ||
29 | */ | ||
30 | |||
31 | #include "SDL_video.h" | ||
32 | #include "SDL_mouse.h" | ||
33 | #include "../SDL_sysvideo.h" | ||
34 | #include "../SDL_pixels_c.h" | ||
35 | #include "../../events/SDL_events_c.h" | ||
36 | |||
37 | #include "SDL_riscostask.h" | ||
38 | #include "SDL_riscosvideo.h" | ||
39 | #include "SDL_riscosevents_c.h" | ||
40 | #include "SDL_riscosmouse_c.h" | ||
41 | |||
42 | #include "kernel.h" | ||
43 | #include "swis.h" | ||
44 | |||
45 | /* Initialization/Query functions */ | ||
46 | SDL_Rect **WIMP_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | ||
47 | SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | ||
48 | int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | ||
49 | void WIMP_SetWMCaption(_THIS, const char *title, const char *icon); | ||
50 | |||
51 | |||
52 | extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp); | ||
53 | extern void WIMP_PumpEvents(_THIS); | ||
54 | extern void WIMP_PlotSprite(_THIS, int x, int y); | ||
55 | extern void WIMP_SetupPlotInfo(_THIS); | ||
56 | extern void WIMP_SetFocus(int win); | ||
57 | |||
58 | /* etc. */ | ||
59 | static void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | ||
60 | |||
61 | /* RISC OS Wimp handling helpers */ | ||
62 | void WIMP_ReadModeInfo(_THIS); | ||
63 | unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface); | ||
64 | void WIMP_SetDeviceMode(_THIS); | ||
65 | void WIMP_DeleteWindow(_THIS); | ||
66 | |||
67 | /* FULLSCREEN function required for wimp/fullscreen toggling */ | ||
68 | extern int FULLSCREEN_SetMode(int width, int height, int bpp); | ||
69 | |||
70 | /* Currently need to set this up here as it only works if you | ||
71 | start up in a Wimp mode */ | ||
72 | extern int RISCOS_ToggleFullScreen(_THIS, int fullscreen); | ||
73 | |||
74 | extern int riscos_backbuffer; | ||
75 | extern int mouseInWindow; | ||
76 | extern int riscos_closeaction; | ||
77 | |||
78 | /* Following needed to ensure window is shown immediately */ | ||
79 | extern int hasFocus; | ||
80 | extern void WIMP_Poll(_THIS, int waitTime); | ||
81 | |||
82 | SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, | ||
83 | int width, int height, int bpp, Uint32 flags) | ||
84 | { | ||
85 | Uint32 Rmask = 0; | ||
86 | Uint32 Gmask = 0; | ||
87 | Uint32 Bmask = 0; | ||
88 | char *buffer = NULL; | ||
89 | int bytesPerPixel = 1; | ||
90 | |||
91 | /* Don't support double buffering in Wimp mode */ | ||
92 | flags &= ~SDL_DOUBLEBUF; | ||
93 | flags &= ~SDL_HWSURFACE; | ||
94 | |||
95 | switch(bpp) | ||
96 | { | ||
97 | case 8: | ||
98 | /* Emulated palette using ColourTrans */ | ||
99 | flags |= SDL_HWPALETTE; | ||
100 | break; | ||
101 | |||
102 | case 15: | ||
103 | case 16: | ||
104 | Bmask = 0x00007c00; | ||
105 | Gmask = 0x000003e0; | ||
106 | Rmask = 0x0000001f; | ||
107 | bytesPerPixel = 2; | ||
108 | break; | ||
109 | |||
110 | case 32: | ||
111 | Bmask = 0x00ff0000; | ||
112 | Gmask = 0x0000ff00; | ||
113 | Rmask = 0x000000ff; | ||
114 | bytesPerPixel = 4; | ||
115 | break; | ||
116 | |||
117 | default: | ||
118 | SDL_SetError("Pixel depth not supported"); | ||
119 | return NULL; | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | /* printf("Setting mode %dx%d\n", width, height);*/ | ||
124 | |||
125 | /* Allocate the new pixel format for the screen */ | ||
126 | if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) { | ||
127 | SDL_SetError("Couldn't allocate new pixel format for requested mode"); | ||
128 | return(NULL); | ||
129 | } | ||
130 | |||
131 | /* Set up the new mode framebuffer */ | ||
132 | current->w = width; | ||
133 | this->hidden->height = current->h = height; | ||
134 | |||
135 | if (bpp == 15) bpp = 16; | ||
136 | buffer = WIMP_CreateBuffer(width, height, bpp); | ||
137 | if (buffer == NULL) | ||
138 | { | ||
139 | SDL_SetError("Couldn't create sprite for video memory"); | ||
140 | return (NULL); | ||
141 | } | ||
142 | |||
143 | this->hidden->bank[0] = buffer + 60; /* Start of sprite data */ | ||
144 | if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ | ||
145 | |||
146 | this->hidden->bank[1] = buffer; /* Start of buffer */ | ||
147 | |||
148 | /* Remember sprite buffer so it can be freed later */ | ||
149 | if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank); | ||
150 | this->hidden->alloc_bank = buffer; | ||
151 | |||
152 | current->pitch = width * bytesPerPixel; | ||
153 | if ((current->pitch & 3)) | ||
154 | { | ||
155 | /* Sprites are 32bit word aligned */ | ||
156 | current->pitch += (4 - (current->pitch & 3)); | ||
157 | } | ||
158 | |||
159 | current->flags = flags | SDL_PREALLOC; | ||
160 | |||
161 | WIMP_ReadModeInfo(this); | ||
162 | |||
163 | SDL_memset(this->hidden->bank[0], 0, height * current->pitch); | ||
164 | |||
165 | this->hidden->current_bank = 0; | ||
166 | current->pixels = this->hidden->bank[0]; | ||
167 | |||
168 | |||
169 | if (WIMP_SetupWindow(this, current) == 0) | ||
170 | { | ||
171 | SDL_SetError("Unable to create window to display surface"); | ||
172 | return NULL; | ||
173 | } | ||
174 | |||
175 | /* Reset device functions for the wimp */ | ||
176 | WIMP_SetDeviceMode(this); | ||
177 | |||
178 | /* Needs to set up plot info after window has been created */ | ||
179 | /* Not sure why, but plots don't work if I do it earlier */ | ||
180 | WIMP_SetupPlotInfo(this); | ||
181 | |||
182 | /* Poll until window is shown */ | ||
183 | { | ||
184 | /* We wait until it gets the focus, but give up after 5 seconds | ||
185 | in case the focus is prevented in any way. | ||
186 | */ | ||
187 | Uint32 now = SDL_GetTicks(); | ||
188 | while (!hasFocus && SDL_GetTicks() - now < 5000) | ||
189 | { | ||
190 | WIMP_Poll(this, 0); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /* We're done */ | ||
195 | return(current); | ||
196 | } | ||
197 | |||
198 | |||
199 | void WIMP_ReadModeInfo(_THIS) | ||
200 | { | ||
201 | _kernel_swi_regs regs; | ||
202 | int vars[6]; | ||
203 | int vals[5]; | ||
204 | |||
205 | vars[0] = 4; /* XEig */ | ||
206 | vars[1] = 5; /* YEig */ | ||
207 | vars[2] = 9; /* Log base 2 bpp */ | ||
208 | vars[3] = 11; /* Screen Width - 1 */ | ||
209 | vars[4] = 12; /* Screen Depth - 1 */ | ||
210 | vars[5] = -1; /* Terminate list */ | ||
211 | |||
212 | regs.r[0] = (int)vars; | ||
213 | regs.r[1] = (int)vals; | ||
214 | _kernel_swi(OS_ReadVduVariables, ®s, ®s); | ||
215 | this->hidden->xeig = vals[0]; | ||
216 | this->hidden->yeig = vals[1]; | ||
217 | this->hidden->screen_bpp = 1 << vals[2]; | ||
218 | this->hidden->screen_width = vals[3] + 1; | ||
219 | this->hidden->screen_height = vals[4] + 1; | ||
220 | } | ||
221 | |||
222 | /* Set device function to call the correct versions for running | ||
223 | in a wimp window */ | ||
224 | |||
225 | void WIMP_SetDeviceMode(_THIS) | ||
226 | { | ||
227 | if (this->UpdateRects == WIMP_UpdateRects) return; /* Already set up */ | ||
228 | |||
229 | this->SetColors = WIMP_SetColors; | ||
230 | this->UpdateRects = WIMP_UpdateRects; | ||
231 | |||
232 | this->FlipHWSurface = NULL; | ||
233 | |||
234 | this->SetCaption = WIMP_SetWMCaption; | ||
235 | this->SetIcon = NULL; | ||
236 | this->IconifyWindow = NULL; | ||
237 | |||
238 | this->ShowWMCursor = WIMP_ShowWMCursor; | ||
239 | this->WarpWMCursor = WIMP_WarpWMCursor; | ||
240 | |||
241 | this->ToggleFullScreen = RISCOS_ToggleFullScreen; | ||
242 | |||
243 | this->PumpEvents = WIMP_PumpEvents; | ||
244 | } | ||
245 | |||
246 | /* Setup the Window to display the surface */ | ||
247 | unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface) | ||
248 | { | ||
249 | _kernel_swi_regs regs; | ||
250 | int window_data[23]; | ||
251 | int *window_block = window_data+1; | ||
252 | int x = (this->hidden->screen_width - surface->w) / 2; | ||
253 | int y = (this->hidden->screen_height - surface->h) / 2; | ||
254 | int xeig = this->hidden->xeig; | ||
255 | int yeig = this->hidden->yeig; | ||
256 | |||
257 | mouseInWindow = 0; | ||
258 | |||
259 | /* Always delete the window and recreate on a change */ | ||
260 | if (this->hidden->window_handle) WIMP_DeleteWindow(this); | ||
261 | |||
262 | /* Setup window co-ordinates */ | ||
263 | window_block[0] = x << xeig; | ||
264 | window_block[1] = y << yeig; | ||
265 | window_block[2] = window_block[0] + (surface->w << xeig); | ||
266 | window_block[3] = window_block[1] + (surface->h << yeig); | ||
267 | |||
268 | |||
269 | window_block[4] = 0; /* Scroll offsets */ | ||
270 | window_block[5] = 0; | ||
271 | window_block[6] = -1; /* Open on top of window stack */ | ||
272 | |||
273 | window_block[7] = 0x85040042; /* Window flags */ | ||
274 | if (riscos_closeaction != 0) window_block[7] |= 0x2000000; | ||
275 | |||
276 | /* TODO: Take into account surface->flags */ | ||
277 | |||
278 | window_block[8] = 0xff070207; /* Window colours */ | ||
279 | window_block[9] = 0x000c0103; | ||
280 | window_block[10] = 0; /* Work area minimum */ | ||
281 | window_block[11] = -surface->h << yeig; | ||
282 | window_block[12] = surface->w << xeig; /* Work area maximum */ | ||
283 | window_block[13] = 0; | ||
284 | window_block[14] = 0x2700013d; /* Title icon flags */ | ||
285 | window_block[15] = 0x00003000; /* Work area flags - Mouse click down reported */ | ||
286 | window_block[16] = 1; /* Sprite area control block pointer */ | ||
287 | window_block[17] = 0x00100010; /* Minimum window size (width & height) (16x16)*/ | ||
288 | window_block[18] = (int)this->hidden->title; /* Title data */ | ||
289 | window_block[19] = -1; | ||
290 | window_block[20] = 256; | ||
291 | window_block[21] = 0; /* Number of icons */ | ||
292 | |||
293 | regs.r[1] = (unsigned int)(window_block); | ||
294 | |||
295 | /* Create the window */ | ||
296 | if (_kernel_swi(Wimp_CreateWindow, ®s, ®s) == NULL) | ||
297 | { | ||
298 | this->hidden->window_handle = window_data[0] = regs.r[0]; | ||
299 | |||
300 | /* Show the window on the screen */ | ||
301 | regs.r[1] = (unsigned int)window_data; | ||
302 | if (_kernel_swi(Wimp_OpenWindow, ®s, ®s) == NULL) | ||
303 | { | ||
304 | WIMP_SetFocus(this->hidden->window_handle); | ||
305 | } else | ||
306 | { | ||
307 | WIMP_DeleteWindow(this); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | return this->hidden->window_handle; | ||
312 | } | ||
313 | |||
314 | /* Destroy the Window */ | ||
315 | |||
316 | void WIMP_DeleteWindow(_THIS) | ||
317 | { | ||
318 | _kernel_swi_regs regs; | ||
319 | regs.r[1] = (unsigned int)&(this->hidden->window_handle); | ||
320 | _kernel_swi(Wimp_DeleteWindow, ®s, ®s); | ||
321 | this->hidden->window_handle = 0; | ||
322 | } | ||
323 | |||
324 | |||
325 | void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects) | ||
326 | { | ||
327 | _kernel_swi_regs regs; | ||
328 | int update_block[12]; | ||
329 | int xeig = this->hidden->xeig; | ||
330 | int yeig = this->hidden->yeig; | ||
331 | int j; | ||
332 | update_block[0] = this->hidden->window_handle; | ||
333 | |||
334 | for (j = 0; j < numrects; j++) | ||
335 | { | ||
336 | update_block[1] = rects[j].x << xeig; /* Min X */ | ||
337 | update_block[4] = -(rects[j].y << yeig); | ||
338 | update_block[3] = update_block[1] + (rects[j].w << xeig); | ||
339 | update_block[2] = update_block[4] - (rects[j].h << yeig); | ||
340 | |||
341 | regs.r[1] = (int)update_block; | ||
342 | /* Update window can fail if called before first poll */ | ||
343 | if (_kernel_swi(Wimp_UpdateWindow, ®s, ®s) == 0) | ||
344 | { | ||
345 | while (regs.r[0]) | ||
346 | { | ||
347 | WIMP_PlotSprite(this, update_block[1], update_block[2]); | ||
348 | _kernel_swi(Wimp_GetRectangle, ®s, ®s); | ||
349 | } | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | |||
354 | |||
355 | int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | ||
356 | { | ||
357 | unsigned int *pal = (unsigned int *)(this->hidden->bank[1]+60); | ||
358 | int j; | ||
359 | SDL_Rect update; | ||
360 | |||
361 | pal += firstcolor*2; | ||
362 | for (j = 0; j < ncolors; j++) | ||
363 | { | ||
364 | *pal = (((unsigned int)colors->r) << 8) | ||
365 | + (((unsigned int)colors->g) << 16) | ||
366 | + (((unsigned int)colors->b) << 24); | ||
367 | pal[1] = *pal; | ||
368 | pal += 2; | ||
369 | colors++; | ||
370 | } | ||
371 | |||
372 | WIMP_SetupPlotInfo(this); | ||
373 | |||
374 | /* Need to refresh the window */ | ||
375 | update.x = 0; | ||
376 | update.y = 0; | ||
377 | update.w = SDL_VideoSurface->w; | ||
378 | update.h = SDL_VideoSurface->h; | ||
379 | WIMP_UpdateRects(this, 1, &update); | ||
380 | |||
381 | return 1; | ||
382 | } | ||
383 | |||
384 | void WIMP_SetWMCaption(_THIS, const char *title, const char *icon) | ||
385 | { | ||
386 | _kernel_swi_regs regs; | ||
387 | |||
388 | SDL_strlcpy(this->hidden->title, title, SDL_arraysize(this->hidden->title)); | ||
389 | |||
390 | if (RISCOS_GetWimpVersion() < 380) | ||
391 | { | ||
392 | int block[6]; | ||
393 | |||
394 | regs.r[1] = (int)block; | ||
395 | _kernel_swi(Wimp_GetCaretPosition, ®s, ®s); | ||
396 | if (block[0] == (int)this->hidden->window_handle) | ||
397 | { | ||
398 | regs.r[0] = -1; | ||
399 | _kernel_swi(Wimp_SetCaretPosition, ®s,®s); | ||
400 | } else | ||
401 | { | ||
402 | regs.r[0] = this->hidden->window_handle; | ||
403 | regs.r[1] = -1; | ||
404 | regs.r[2] = -1; | ||
405 | regs.r[3] = -1; | ||
406 | _kernel_swi(Wimp_SetCaretPosition, ®s,®s); | ||
407 | } | ||
408 | regs.r[0] = block[0]; | ||
409 | regs.r[1] = block[1]; | ||
410 | regs.r[2] = block[2]; | ||
411 | regs.r[3] = block[3]; | ||
412 | regs.r[4] = block[4]; | ||
413 | regs.r[5] = block[5]; | ||
414 | _kernel_swi(Wimp_SetCaretPosition, ®s,®s); | ||
415 | } else | ||
416 | { | ||
417 | regs.r[0] = this->hidden->window_handle; | ||
418 | regs.r[1] = 0x4b534154; /* "TASK" */ | ||
419 | regs.r[2] = 3; /* Redraw title */ | ||
420 | _kernel_swi(Wimp_ForceRedraw, ®s, ®s); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | void WIMP_RefreshDesktop(_THIS) | ||
425 | { | ||
426 | int width = this->hidden->screen_width << this->hidden->xeig; | ||
427 | int height = this->hidden->screen_height << this->hidden->yeig; | ||
428 | _kernel_swi_regs regs; | ||
429 | regs.r[0] = -1; /* Whole screen */ | ||
430 | regs.r[1] = 0; | ||
431 | regs.r[2] = 0; | ||
432 | regs.r[3] = width; | ||
433 | regs.r[4] = height; | ||
434 | _kernel_swi(Wimp_ForceRedraw, ®s, ®s); | ||
435 | } | ||
436 | |||
437 | /* Toggle to window from full screen */ | ||
438 | int WIMP_ToggleFromFullScreen(_THIS) | ||
439 | { | ||
440 | int width = this->screen->w; | ||
441 | int height = this->screen->h; | ||
442 | int bpp = this->screen->format->BitsPerPixel; | ||
443 | char *buffer = NULL; | ||
444 | char *old_bank[2]; | ||
445 | char *old_alloc_bank; | ||
446 | |||
447 | /* Ensure flags are OK */ | ||
448 | this->screen->flags &= ~(SDL_DOUBLEBUF|SDL_HWSURFACE); | ||
449 | |||
450 | if (this->hidden->bank[0] == this->hidden->alloc_bank || riscos_backbuffer == 0) | ||
451 | { | ||
452 | /* Need to create a sprite for the screen and copy the data to it */ | ||
453 | char *data; | ||
454 | buffer = WIMP_CreateBuffer(width, height, bpp); | ||
455 | data = buffer + 60; /* Start of sprite data */ | ||
456 | if (bpp == 8) data += 2048; /* 8bpp sprite have palette first */ | ||
457 | |||
458 | if (buffer == NULL) return 0; | ||
459 | SDL_memcpy(data, this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel); | ||
460 | } | ||
461 | /* else We've switch to full screen before so we already have a sprite */ | ||
462 | |||
463 | old_bank[0] = this->hidden->bank[0]; | ||
464 | old_bank[1] = this->hidden->bank[1]; | ||
465 | old_alloc_bank = this->hidden->alloc_bank; | ||
466 | |||
467 | if (buffer != NULL) this->hidden->alloc_bank = buffer; | ||
468 | |||
469 | this->hidden->bank[1] = this->hidden->alloc_bank; | ||
470 | this->hidden->bank[0] = this->hidden->bank[1] + 60; /* Start of sprite data */ | ||
471 | if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ | ||
472 | |||
473 | this->hidden->current_bank = 0; | ||
474 | this->screen->pixels = this->hidden->bank[0]; | ||
475 | |||
476 | RISCOS_RestoreWimpMode(); | ||
477 | WIMP_ReadModeInfo(this); | ||
478 | if (WIMP_SetupWindow(this, this->screen)) | ||
479 | { | ||
480 | WIMP_SetDeviceMode(this); | ||
481 | WIMP_SetupPlotInfo(this); | ||
482 | |||
483 | if (riscos_backbuffer == 0) riscos_backbuffer = 1; | ||
484 | |||
485 | if (buffer && old_alloc_bank) SDL_free(old_alloc_bank); | ||
486 | |||
487 | return 1; | ||
488 | } else | ||
489 | { | ||
490 | /* Drop back to full screen mode on failure */ | ||
491 | this->hidden->bank[0] = old_bank[0]; | ||
492 | this->hidden->bank[1] = old_bank[1]; | ||
493 | this->hidden->alloc_bank = old_alloc_bank; | ||
494 | if (buffer) SDL_free(buffer); | ||
495 | |||
496 | RISCOS_StoreWimpMode(); | ||
497 | FULLSCREEN_SetMode(width, height, bpp); | ||
498 | } | ||
499 | |||
500 | return 0; | ||
501 | } | ||