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, &regs, &regs)) != 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 */