Mercurial > sdl-ios-xcode
comparison src/video/riscos/SDL_riscosFullScreenVideo.c @ 1035:974ba6ae0fa3
Date: Wed, 26 Jan 2005 13:37:09 GMT
From: Peter Naulls
Subject: RISC OS SDL Patches
Sam, I've attached a diff of the latest changes to libSDL for RISC OS
support. These changes are by Alan Buckley and myself.
The most significant of these are:
Optimised assembler blit rountines - I've attached the file
src/video/riscos/SDL_riscosASM.s which is needed for this.
Move to using /dev/dsp instead of its own audio implementation.
This means that src/audio/riscos/SDL_drenderer.c should be removed
Typo fixes. Mainly correct spelling of "RISC OS", but some from elsewhere
too.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 12 Feb 2005 18:01:31 +0000 |
parents | f72cc0c7305f |
children | d90b362628ea |
comparison
equal
deleted
inserted
replaced
1034:2eca15c3f609 | 1035:974ba6ae0fa3 |
---|---|
19 Sam Lantinga | 19 Sam Lantinga |
20 slouken@devolution.com | 20 slouken@devolution.com |
21 */ | 21 */ |
22 | 22 |
23 /* | 23 /* |
24 File added by Alan Buckley (alan_baa@hotmail.com) for RISCOS compatability | 24 File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability |
25 27 March 2003 | 25 27 March 2003 |
26 | 26 |
27 Implements RISCOS full screen display. | 27 Implements RISC OS full screen display. |
28 */ | 28 */ |
29 | 29 |
30 #include <stdio.h> | 30 #include <stdio.h> |
31 #include <stdlib.h> | 31 #include <stdlib.h> |
32 #include <string.h> | 32 #include <string.h> |
67 void FULLSCREEN_SetupBanks(_THIS); | 67 void FULLSCREEN_SetupBanks(_THIS); |
68 | 68 |
69 /* SDL video device functions for fullscreen mode */ | 69 /* SDL video device functions for fullscreen mode */ |
70 static int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | 70 static int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); |
71 static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface); | 71 static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface); |
72 static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | |
73 void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon); | 72 void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon); |
74 extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info); | 73 extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info); |
74 | |
75 /* UpdateRects variants */ | |
76 static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | |
77 static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects); | |
78 static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects); | |
79 static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects); | |
80 static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects); | |
81 static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects); | |
75 | 82 |
76 /* Local helper functions */ | 83 /* Local helper functions */ |
77 static int cmpmodes(const void *va, const void *vb); | 84 static int cmpmodes(const void *va, const void *vb); |
78 static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h); | 85 static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h); |
79 void FULLSCREEN_SetWriteBank(int bank); | 86 void FULLSCREEN_SetWriteBank(int bank); |
83 void FULLSCREEN_BuildModeList(_THIS); | 90 void FULLSCREEN_BuildModeList(_THIS); |
84 | 91 |
85 /* Following variable is set up in riskosTask.c */ | 92 /* Following variable is set up in riskosTask.c */ |
86 extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */ | 93 extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */ |
87 | 94 |
88 | 95 /* Following is used to create a sprite back buffer */ |
96 extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp); | |
97 | |
98 /* Fast assembler copy */ | |
99 extern void RISCOS_Put32(void *to, int pixels, int pitch, int rows, void *from, int src_skip_bytes); | |
89 | 100 |
90 SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, | 101 SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, |
91 int width, int height, int bpp, Uint32 flags) | 102 int width, int height, int bpp, Uint32 flags) |
92 { | 103 { |
93 _kernel_swi_regs regs; | 104 _kernel_swi_regs regs; |
178 FULLSCREEN_SetupBanks(this); | 189 FULLSCREEN_SetupBanks(this); |
179 | 190 |
180 if (create_back_buffer) | 191 if (create_back_buffer) |
181 { | 192 { |
182 /* If not double buffered we may need to create a memory | 193 /* If not double buffered we may need to create a memory |
183 ** back buffer to simulate processing on other OS's. | 194 ** back buffer to simulate processing on other OSes. |
184 ** This is turned on by setting the enviromental variable | 195 ** This is turned on by setting the enviromental variable |
185 ** SDL$<name>$BackBuffer to 1 | 196 ** SDL$<name>$BackBuffer >= 1 |
186 */ | 197 */ |
187 this->hidden->bank[0] = malloc(height * current->pitch); | 198 if (riscos_backbuffer == 3) |
199 this->hidden->bank[0] = WIMP_CreateBuffer(width, height, bpp); | |
200 else | |
201 this->hidden->bank[0] = malloc(height * current->pitch); | |
188 if (this->hidden->bank[0] == 0) | 202 if (this->hidden->bank[0] == 0) |
189 { | 203 { |
190 RISCOS_RestoreWimpMode(); | 204 RISCOS_RestoreWimpMode(); |
191 SDL_SetError("Couldnt allocate memory for back buffer"); | 205 SDL_SetError("Couldnt allocate memory for back buffer"); |
192 return (NULL); | 206 return (NULL); |
193 } | 207 } |
194 /* Surface updated in programs is now a software surface */ | 208 /* Surface updated in programs is now a software surface */ |
195 current->flags &= ~SDL_HWSURFACE; | 209 current->flags &= ~SDL_HWSURFACE; |
196 } | 210 } |
197 | 211 |
198 /* Store address of allocated screen bank to be freed later */ | 212 /* Store address of allocated screen bank to be freed later */ |
199 if (this->hidden->alloc_bank) free(this->hidden->alloc_bank); | 213 if (this->hidden->alloc_bank) free(this->hidden->alloc_bank); |
200 if (create_back_buffer) | 214 if (create_back_buffer) |
201 { | 215 { |
202 this->hidden->alloc_bank = this->hidden->bank[0]; | 216 this->hidden->alloc_bank = this->hidden->bank[0]; |
203 } else | 217 if (riscos_backbuffer == 3) |
204 this->hidden->alloc_bank = 0; | 218 { |
205 | 219 this->hidden->bank[0] += 60; /* Start of sprite data */ |
206 // Clear both banks to black | 220 if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ |
207 memset(this->hidden->bank[0], 0, height * current->pitch); | 221 } |
208 memset(this->hidden->bank[1], 0, height * current->pitch); | 222 } else |
223 this->hidden->alloc_bank = 0; | |
224 | |
225 // Clear both banks to black | |
226 memset(this->hidden->bank[0], 0, height * current->pitch); | |
227 memset(this->hidden->bank[1], 0, height * current->pitch); | |
209 | 228 |
210 this->hidden->current_bank = 0; | 229 this->hidden->current_bank = 0; |
211 current->pixels = this->hidden->bank[0]; | 230 current->pixels = this->hidden->bank[0]; |
212 | 231 |
232 /* Have to set the screen here, so SetDeviceMode will pick it up */ | |
233 this->screen = current; | |
234 | |
213 /* Reset device functions for the wimp */ | 235 /* Reset device functions for the wimp */ |
214 FULLSCREEN_SetDeviceMode(this); | 236 FULLSCREEN_SetDeviceMode(this); |
215 | 237 |
216 /* FULLSCREEN_DisableEscape(); */ | 238 /* FULLSCREEN_DisableEscape(); */ |
217 | 239 |
220 } | 242 } |
221 | 243 |
222 /* Reset any device functions that have been changed because we have run in WIMP mode */ | 244 /* Reset any device functions that have been changed because we have run in WIMP mode */ |
223 void FULLSCREEN_SetDeviceMode(_THIS) | 245 void FULLSCREEN_SetDeviceMode(_THIS) |
224 { | 246 { |
247 /* Update rects is different if we have a backbuffer */ | |
248 | |
249 if (riscos_backbuffer && (this->screen->flags & SDL_DOUBLEBUF) == 0) | |
250 { | |
251 switch(riscos_backbuffer) | |
252 { | |
253 case 2: /* ARM code full word copy */ | |
254 switch(this->screen->format->BytesPerPixel) | |
255 { | |
256 case 1: /* 8bpp modes */ | |
257 this->UpdateRects = FULLSCREEN_UpdateRects8bpp; | |
258 break; | |
259 case 2: /* 15/16bpp modes */ | |
260 this->UpdateRects = FULLSCREEN_UpdateRects16bpp; | |
261 break; | |
262 case 4: /* 32 bpp modes */ | |
263 this->UpdateRects = FULLSCREEN_UpdateRects32bpp; | |
264 break; | |
265 | |
266 default: /* Just default to the memcpy routine */ | |
267 this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy; | |
268 break; | |
269 } | |
270 break; | |
271 | |
272 case 3: /* Use OS sprite plot routine */ | |
273 this->UpdateRects = FULLSCREEN_UpdateRectsOS; | |
274 break; | |
275 | |
276 default: /* Old but safe memcpy */ | |
277 this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy; | |
278 break; | |
279 } | |
280 } else | |
281 this->UpdateRects = FULLSCREEN_UpdateRects; /* Default do nothing implementation */ | |
282 | |
225 if (this->SetColors == FULLSCREEN_SetColors) return; /* Already set up */ | 283 if (this->SetColors == FULLSCREEN_SetColors) return; /* Already set up */ |
226 | 284 |
227 this->SetColors = FULLSCREEN_SetColors; | 285 this->SetColors = FULLSCREEN_SetColors; |
228 this->UpdateRects = FULLSCREEN_UpdateRects; | |
229 | 286 |
230 this->FlipHWSurface = FULLSCREEN_FlipHWSurface; | 287 this->FlipHWSurface = FULLSCREEN_FlipHWSurface; |
231 | 288 |
232 this->SetCaption = FULLSCREEN_SetWMCaption; | 289 this->SetCaption = FULLSCREEN_SetWMCaption; |
233 this->SetIcon = NULL; | 290 this->SetIcon = NULL; |
320 surface->pixels = this->hidden->bank[this->hidden->current_bank]; | 377 surface->pixels = this->hidden->bank[this->hidden->current_bank]; |
321 | 378 |
322 return(0); | 379 return(0); |
323 } | 380 } |
324 | 381 |
382 /* Nothing to do if we are writing direct to hardware */ | |
325 static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects) | 383 static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects) |
326 { | 384 { |
327 if (riscos_backbuffer && (this->screen->flags & SDL_DOUBLEBUF) == 0) | 385 } |
328 { | 386 |
329 /* If not double buffered copy rectangles to main screen now */ | 387 /* Safe but slower Memory copy from our allocated back buffer */ |
388 static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects) | |
389 { | |
330 int j; | 390 int j; |
331 char *to, *from; | 391 char *to, *from; |
332 int pitch = this->screen->pitch; | 392 int pitch = this->screen->pitch; |
333 int row; | 393 int row; |
334 int xmult = this->screen->format->BytesPerPixel; | 394 int xmult = this->screen->format->BytesPerPixel; |
342 from += pitch; | 402 from += pitch; |
343 to += pitch; | 403 to += pitch; |
344 } | 404 } |
345 rects++; | 405 rects++; |
346 } | 406 } |
347 } | 407 } |
348 } | 408 |
409 /* Use optimized assembler memory copy. Deliberately copies extra columns if | |
410 necessary to ensure the rectangle is word aligned. */ | |
411 static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects) | |
412 { | |
413 int j; | |
414 char *to, *from; | |
415 int pitch = this->screen->pitch; | |
416 int width_bytes; | |
417 int src_skip_bytes; | |
418 | |
419 for (j = 0; j < numrects; j++) | |
420 { | |
421 from = this->hidden->bank[0] + rects->x + rects->y * pitch; | |
422 to = this->hidden->bank[1] + rects->x + rects->y * pitch; | |
423 width_bytes = rects->w; | |
424 if ((int)from & 3) | |
425 { | |
426 int extra = ((int)from & 3); | |
427 from -= extra; | |
428 to -= extra; | |
429 width_bytes += extra; | |
430 } | |
431 if (width_bytes & 3) width_bytes += 4 - (width_bytes & 3); | |
432 src_skip_bytes = pitch - width_bytes; | |
433 | |
434 RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes); | |
435 rects++; | |
436 } | |
437 } | |
438 | |
439 /* Use optimized assembler memory copy. Deliberately copies extra columns if | |
440 necessary to ensure the rectangle is word aligned. */ | |
441 static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects) | |
442 { | |
443 int j; | |
444 char *to, *from; | |
445 int pitch = this->screen->pitch; | |
446 int width_bytes; | |
447 int src_skip_bytes; | |
448 | |
449 for (j = 0; j < numrects; j++) | |
450 { | |
451 from = this->hidden->bank[0] + (rects->x << 1) + rects->y * pitch; | |
452 to = this->hidden->bank[1] + (rects->x << 1) + rects->y * pitch; | |
453 width_bytes = (((int)rects->w) << 1); | |
454 if ((int)from & 3) | |
455 { | |
456 from -= 2; | |
457 to -= 2; | |
458 width_bytes += 2; | |
459 } | |
460 if (width_bytes & 3) width_bytes += 2; | |
461 src_skip_bytes = pitch - width_bytes; | |
462 | |
463 RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes); | |
464 rects++; | |
465 } | |
466 } | |
467 | |
468 /* Use optimized assembler memory copy. 32 bpp modes are always word aligned */ | |
469 static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects) | |
470 { | |
471 int j; | |
472 char *to, *from; | |
473 int pitch = this->screen->pitch; | |
474 int width; | |
475 | |
476 for (j = 0; j < numrects; j++) | |
477 { | |
478 from = this->hidden->bank[0] + (rects->x << 2) + rects->y * pitch; | |
479 to = this->hidden->bank[1] + (rects->x << 2) + rects->y * pitch; | |
480 width = (int)rects->w ; | |
481 | |
482 RISCOS_Put32(to, width, pitch, (int)rects->h, from, pitch - (width << 2)); | |
483 rects++; | |
484 } | |
485 } | |
486 | |
487 /* Use operating system sprite plots. Currently this is much slower than the | |
488 other variants however accelerated sprite plotting can be seen on the horizon | |
489 so this prepares for it. */ | |
490 static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects) | |
491 { | |
492 _kernel_swi_regs regs; | |
493 _kernel_oserror *err; | |
494 int j; | |
495 int y; | |
496 | |
497 regs.r[0] = 28 + 512; | |
498 regs.r[1] = (unsigned int)this->hidden->alloc_bank; | |
499 regs.r[2] = (unsigned int)this->hidden->alloc_bank+16; | |
500 regs.r[5] = 0; | |
501 | |
502 for (j = 0; j < numrects; j++) | |
503 { | |
504 y = this->screen->h - rects->y; /* top of clipping region */ | |
505 _kernel_oswrch(24); /* Set graphics clip region */ | |
506 _kernel_oswrch((rects->x << this->hidden->xeig) & 0xFF); /* left */ | |
507 _kernel_oswrch(((rects->x << this->hidden->xeig) >> 8) & 0xFF); | |
508 _kernel_oswrch(((y - rects->h) << this->hidden->yeig) & 0xFF); /* bottom */ | |
509 _kernel_oswrch((((y - rects->h) << this->hidden->yeig)>> 8) & 0xFF); | |
510 _kernel_oswrch(((rects->x + rects->w - 1) << this->hidden->xeig) & 0xFF); /* right */ | |
511 _kernel_oswrch((((rects->x + rects->w - 1)<< this->hidden->xeig) >> 8) & 0xFF); | |
512 _kernel_oswrch(((y-1) << this->hidden->yeig) & 0xFF); /* top */ | |
513 _kernel_oswrch((((y-1) << this->hidden->yeig) >> 8) & 0xFF); | |
514 | |
515 regs.r[3] = 0; | |
516 regs.r[4] = 0; | |
517 | |
518 if ((err = _kernel_swi(OS_SpriteOp, ®s, ®s)) != 0) | |
519 { | |
520 printf("OS_SpriteOp failed \n%s\n",err->errmess); | |
521 } | |
522 | |
523 rects++; | |
524 | |
525 /* Reset to full screen clipping */ | |
526 _kernel_oswrch(24); /* Set graphics clip region */ | |
527 _kernel_oswrch(0); /* left */ | |
528 _kernel_oswrch(0); | |
529 _kernel_oswrch(0); /* bottom */ | |
530 _kernel_oswrch(0); | |
531 _kernel_oswrch(((this->screen->w-1) << this->hidden->xeig) & 0xFF); /* right */ | |
532 _kernel_oswrch((((this->screen->w-1) << this->hidden->xeig) >> 8) & 0xFF); | |
533 _kernel_oswrch(((this->screen->h-1) << this->hidden->yeig) & 0xFF); /* top */ | |
534 _kernel_oswrch((((this->screen->h-1) << this->hidden->yeig) >> 8) & 0xFF); | |
535 } | |
536 } | |
537 | |
349 | 538 |
350 int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | 539 int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) |
351 { | 540 { |
352 _kernel_swi_regs regs; | 541 _kernel_swi_regs regs; |
353 int palette[256]; | 542 int palette[256]; |
571 RISCOS_StoreWimpMode(); | 760 RISCOS_StoreWimpMode(); |
572 if (FULLSCREEN_SetMode(width, height, bpp)) | 761 if (FULLSCREEN_SetMode(width, height, bpp)) |
573 { | 762 { |
574 char *buffer = this->hidden->alloc_bank; /* This is start of sprite data */ | 763 char *buffer = this->hidden->alloc_bank; /* This is start of sprite data */ |
575 /* Support back buffer mode only */ | 764 /* Support back buffer mode only */ |
576 riscos_backbuffer = 1; | 765 if (riscos_backbuffer == 0) riscos_backbuffer = 1; |
577 | 766 |
578 FULLSCREEN_SetupBanks(this); | 767 FULLSCREEN_SetupBanks(this); |
579 | 768 |
580 this->hidden->bank[0] = buffer + 60; /* Start of sprite data */ | 769 this->hidden->bank[0] = buffer + 60; /* Start of sprite data */ |
581 if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ | 770 if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ |