riscos: Add support for more pixel formats SDL-1.2
authorJeffrey Lee <me@phlamethrower.co.uk>
Sat, 01 Jun 2019 18:27:46 +0100
branchSDL-1.2
changeset 127864e73be7b4787
parent 12785 1b8374f29699
child 12800 e52413f52586
riscos: Add support for more pixel formats

* Add support for red/blue swapped, 12bpp, and 16bpp screen modes
* Clean up code a bit by moving all local 'extern' declarations into headers & making local functions static
* Fix toggling to fullscreen to retain the current palette
src/video/riscos/SDL_riscosFullScreenVideo.c
src/video/riscos/SDL_riscosevents.c
src/video/riscos/SDL_riscosevents_c.h
src/video/riscos/SDL_riscosmouse.c
src/video/riscos/SDL_riscosmouse_c.h
src/video/riscos/SDL_riscossprite.c
src/video/riscos/SDL_riscostask.c
src/video/riscos/SDL_riscostask.h
src/video/riscos/SDL_riscosvideo.c
src/video/riscos/SDL_riscosvideo.h
src/video/riscos/SDL_wimppoll.c
src/video/riscos/SDL_wimpvideo.c
     1.1 --- a/src/video/riscos/SDL_riscosFullScreenVideo.c	Fri May 31 00:26:21 2019 +0100
     1.2 +++ b/src/video/riscos/SDL_riscosFullScreenVideo.c	Sat Jun 01 18:27:46 2019 +0100
     1.3 @@ -51,20 +51,17 @@
     1.4     int y_pixels;
     1.5     int pixel_depth;  // 2^pixel_depth = bpp,i.e. 0 = 1, 1 = 2, 4 = 16, 5 = 32
     1.6     int frame_rate;   // -1 use first match
     1.7 -   int mode_vars[5]; // array of index, value pairs terminated by -1
     1.8 +   int mode_vars[7]; // array of index, value pairs terminated by -1
     1.9  } SCREENMODEBLOCK;
    1.10  
    1.11  
    1.12  /* Helper functions */
    1.13 -void FULLSCREEN_SetDeviceMode(_THIS);
    1.14 -int FULLSCREEN_SetMode(int width, int height, int bpp);
    1.15 -void FULLSCREEN_SetupBanks(_THIS);
    1.16 +static void FULLSCREEN_SetupBanks(_THIS);
    1.17  
    1.18  /* SDL video device functions for fullscreen mode */
    1.19  static int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
    1.20  static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface);
    1.21 -void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon);
    1.22 -extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
    1.23 +static void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon);
    1.24  
    1.25  /* UpdateRects variants */
    1.26  static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
    1.27 @@ -77,56 +74,19 @@
    1.28  /* Local helper functions */
    1.29  static int cmpmodes(const void *va, const void *vb);
    1.30  static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h);
    1.31 -void FULLSCREEN_SetWriteBank(int bank);
    1.32 -void FULLSCREEN_SetDisplayBank(int bank);
    1.33 +static void FULLSCREEN_SetWriteBank(int bank);
    1.34 +static void FULLSCREEN_SetDisplayBank(int bank);
    1.35  static void FULLSCREEN_DisableEscape();
    1.36  static void FULLSCREEN_EnableEscape();
    1.37 -void FULLSCREEN_BuildModeList(_THIS);
    1.38 -
    1.39 -/* Following variable is set up in riskosTask.c */
    1.40 -extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */
    1.41 -
    1.42 -/* Following is used to create a sprite back buffer */
    1.43 -extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp);
    1.44 -
    1.45 -/* Fast assembler copy */
    1.46 -extern void RISCOS_Put32(void *to, int pixels, int pitch, int rows, void *from, int src_skip_bytes);
    1.47  
    1.48  SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current,
    1.49  				int width, int height, int bpp, Uint32 flags)
    1.50  {
    1.51     _kernel_swi_regs regs;
    1.52 -   Uint32 Rmask = 0;
    1.53 -   Uint32 Gmask = 0;
    1.54 -   Uint32 Bmask = 0;
    1.55     int create_back_buffer = riscos_backbuffer;
    1.56  
    1.57 -   switch(bpp)
    1.58 -   {
    1.59 -	case 8:
    1.60 -		flags |= SDL_HWPALETTE;
    1.61 -		break;
    1.62 -
    1.63 -	case 15:
    1.64 -	case 16:
    1.65 -		Bmask = 0x00007c00;
    1.66 -		Gmask = 0x000003e0;
    1.67 -		Rmask = 0x0000001f;
    1.68 -		break;
    1.69 -
    1.70 -	case 32:
    1.71 -		Bmask = 0x00ff0000;
    1.72 -		Gmask = 0x0000ff00;
    1.73 -		Rmask = 0x000000ff;
    1.74 -		break;
    1.75 -
    1.76 -	default:
    1.77 -		SDL_SetError("Pixel depth not supported");
    1.78 -		return NULL;
    1.79 -		break;
    1.80 -   }
    1.81 -
    1.82 -   if (FULLSCREEN_SetMode(width, height, bpp) == 0)
    1.83 +   const RISCOS_SDL_PixelFormat *fmt = FULLSCREEN_SetMode(width, height, bpp);
    1.84 +   if (fmt == NULL)
    1.85     {
    1.86  	   SDL_SetError("Couldn't set requested mode");
    1.87  	   return (NULL);
    1.88 @@ -135,7 +95,7 @@
    1.89  /* 	printf("Setting mode %dx%d\n", width, height); */
    1.90  
    1.91  	/* Allocate the new pixel format for the screen */
    1.92 -	if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
    1.93 +	if ( ! SDL_ReallocFormat(current, fmt->sdl_bpp, fmt->rmask, fmt->gmask, fmt->bmask, 0) ) {
    1.94  	    RISCOS_RestoreWimpMode();
    1.95  		SDL_SetError("Couldn't allocate new pixel format for requested mode");
    1.96  		return(NULL);
    1.97 @@ -167,6 +127,11 @@
    1.98  		   flags &= ~SDL_DOUBLEBUF;
    1.99  	   }
   1.100     }
   1.101 +
   1.102 +   if (fmt->sdl_bpp == 8)
   1.103 +   {
   1.104 +      flags |= SDL_HWPALETTE;
   1.105 +   }
   1.106     
   1.107    	current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | SDL_PREALLOC;
   1.108  	
   1.109 @@ -190,7 +155,7 @@
   1.110           ** SDL$<name>$BackBuffer >= 1
   1.111           */
   1.112         if (riscos_backbuffer == 3)
   1.113 -          this->hidden->bank[0] = WIMP_CreateBuffer(width, height, bpp);
   1.114 +          this->hidden->bank[0] = WIMP_CreateBuffer(width, height, &fmt->ro);
   1.115         else
   1.116            this->hidden->bank[0] = SDL_malloc(height * current->pitch);
   1.117         if (this->hidden->bank[0] == 0)
   1.118 @@ -222,6 +187,7 @@
   1.119  
   1.120   	   this->hidden->current_bank = 0;
   1.121  	   current->pixels = this->hidden->bank[0];
   1.122 +	   this->hidden->format = fmt;
   1.123  
   1.124      /* Have to set the screen here, so SetDeviceMode will pick it up */
   1.125      this->screen = current;
   1.126 @@ -288,6 +254,46 @@
   1.127  	this->PumpEvents = FULLSCREEN_PumpEvents;	
   1.128  }
   1.129  
   1.130 +static void FULLSCREEN_CheckModeListEntry(_THIS, const int *blockInfo)
   1.131 +{
   1.132 +	if ((blockInfo[1] & 255) == 1) /* Old format mode entry */
   1.133 +	{
   1.134 +		switch(blockInfo[4])
   1.135 +		{
   1.136 +		case 3: /* 8 bits per pixel */
   1.137 +			FULLSCREEN_AddMode(this, 8, blockInfo[2], blockInfo[3]);
   1.138 +			break;
   1.139 +		case 4: /* 15 bits per pixel */
   1.140 +			FULLSCREEN_AddMode(this, 15, blockInfo[2], blockInfo[3]);
   1.141 +			break;
   1.142 +		case 5: /* 32 bits per pixel */
   1.143 +			FULLSCREEN_AddMode(this, 32, blockInfo[2], blockInfo[3]);
   1.144 +			break;
   1.145 +		}
   1.146 +	}
   1.147 +	else if ((blockInfo[1] & 255) == 3) /* Newer format mode entry */
   1.148 +	{
   1.149 +		/* Check it's RGB colourspace */
   1.150 +		if ((blockInfo[5] & 0x3000) != 0)
   1.151 +		{
   1.152 +			return;
   1.153 +		}
   1.154 +
   1.155 +		switch(blockInfo[6])
   1.156 +		{
   1.157 +		case 3: /* 8 bits per pixel */
   1.158 +			FULLSCREEN_AddMode(this, 8, blockInfo[2], blockInfo[3]);
   1.159 +			break;
   1.160 +		case 4: /* 12, 15 or 16 bits per pixel */
   1.161 +			FULLSCREEN_AddMode(this, 15, blockInfo[2], blockInfo[3]);
   1.162 +			break;
   1.163 +		case 5: /* 32 bits per pixel */
   1.164 +			FULLSCREEN_AddMode(this, 32, blockInfo[2], blockInfo[3]);
   1.165 +			break;
   1.166 +		}
   1.167 +	}
   1.168 +}
   1.169 +
   1.170  /* Query for the list of available video modes */
   1.171  void FULLSCREEN_BuildModeList(_THIS)
   1.172  {
   1.173 @@ -327,21 +333,7 @@
   1.174  	for (j =0; j < num_modes;j++)
   1.175  	{
   1.176  		blockInfo = (int *)enum_ptr;
   1.177 -		if ((blockInfo[1] & 255) == 1) /* We understand this format */
   1.178 -		{
   1.179 -			switch(blockInfo[4])
   1.180 -			{
   1.181 -			case 3: /* 8 bits per pixel */
   1.182 -				FULLSCREEN_AddMode(this, 8, blockInfo[2], blockInfo[3]);
   1.183 -				break;
   1.184 -			case 4: /* 15 bits per pixel */
   1.185 -				FULLSCREEN_AddMode(this, 15, blockInfo[2], blockInfo[3]);
   1.186 -				break;
   1.187 -			case 5: /* 32 bits per pixel */
   1.188 -				FULLSCREEN_AddMode(this, 32, blockInfo[2], blockInfo[3]);
   1.189 -				break;
   1.190 -			}
   1.191 -		}
   1.192 +		FULLSCREEN_CheckModeListEntry(this, blockInfo);
   1.193  
   1.194  		enum_ptr += blockInfo[0];
   1.195  	}
   1.196 @@ -641,64 +633,79 @@
   1.197  	SDL_strlcpy(this->hidden->title, title, SDL_arraysize(this->hidden->title));
   1.198  }
   1.199  
   1.200 -/* Set screen mode
   1.201 -*
   1.202 -*  Returns 1 if mode is set ok, otherwise 0
   1.203 -*/
   1.204 -
   1.205 -int FULLSCREEN_SetMode(int width, int height, int bpp)
   1.206 +/* Try and set the exact screen mode specified */
   1.207 +static int FULLSCREEN_TrySetMode(int width,int height,const RISCOS_PixelFormat *fmt)
   1.208  {
   1.209     SCREENMODEBLOCK smb;
   1.210     _kernel_swi_regs regs;
   1.211  
   1.212 +   /* To cope with dodgy validation by the OS or video drivers, check that the OS understands the corresponding sprite format */
   1.213 +   if (WIMP_IsSupportedSpriteFormat(fmt))
   1.214 +   {
   1.215 +      return -1;
   1.216 +   }
   1.217 +
   1.218     smb.flags = 1;
   1.219     smb.x_pixels = width;
   1.220     smb.y_pixels = height;
   1.221 -   smb.mode_vars[0] = -1;
   1.222 -
   1.223 -   switch(bpp)
   1.224 -   {
   1.225 -	case 8:
   1.226 -		smb.pixel_depth = 3;
   1.227 -		/* Note: Need to set ModeFlags to 128 and NColour variables to 255 get full 8 bit palette */
   1.228 -		smb.mode_vars[0] = 0; smb.mode_vars[1] = 128; /* Mode flags */
   1.229 -		smb.mode_vars[2] = 3; smb.mode_vars[3] = 255; /* NColour (number of colours -1) */
   1.230 -		smb.mode_vars[4] = -1; /* End of list */
   1.231 -		break;
   1.232 -
   1.233 -	case 15:
   1.234 -	case 16:
   1.235 -		smb.pixel_depth = 4;
   1.236 -		break;
   1.237 -
   1.238 -	case 32:
   1.239 -		smb.pixel_depth = 5;
   1.240 -		break;
   1.241 -
   1.242 -	default:
   1.243 -		SDL_SetError("Pixel depth not supported");
   1.244 -		return 0;
   1.245 -		break;
   1.246 -   }
   1.247 -   
   1.248 +   smb.pixel_depth = fmt->log2bpp;
   1.249     smb.frame_rate = -1;
   1.250 +   smb.mode_vars[0] = 3; /* NColour */
   1.251 +   smb.mode_vars[1] = fmt->ncolour;
   1.252 +   smb.mode_vars[2] = 0; /* ModeFlags */
   1.253 +   smb.mode_vars[3] = fmt->modeflags;
   1.254 +   smb.mode_vars[4] = -1;
   1.255  
   1.256     regs.r[0] = 0;
   1.257     regs.r[1] = (int)&smb;
   1.258  
   1.259 -   if (_kernel_swi(OS_ScreenMode, &regs, &regs) != 0)
   1.260 +   if (_kernel_swi(OS_ScreenMode, &regs, &regs) == 0)
   1.261     {
   1.262 -	   SDL_SetError("Couldn't set requested mode");
   1.263 -	   return 0;
   1.264 +      /* Turn cursor off*/
   1.265 +      _kernel_oswrch(23);_kernel_oswrch(1);_kernel_oswrch(0);
   1.266 +      _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
   1.267 +      _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
   1.268 +      _kernel_oswrch(0);_kernel_oswrch(0);
   1.269 +
   1.270 +      return 0;
   1.271 +   }
   1.272 +   
   1.273 +   return -1;
   1.274 +}
   1.275 +
   1.276 +/* Set screen mode
   1.277 +*
   1.278 +*  Returns ptr to pixel format if mode is set ok, otherwise 0
   1.279 +*/
   1.280 +
   1.281 +const RISCOS_SDL_PixelFormat *FULLSCREEN_SetMode(int width, int height, int bpp)
   1.282 +{
   1.283 +   int pass;
   1.284 +   const RISCOS_SDL_PixelFormat *fmt;
   1.285 +
   1.286 +   for(pass=0;pass<2;pass++)
   1.287 +   {
   1.288 +      for (fmt = RISCOS_SDL_PixelFormats;fmt->sdl_bpp;fmt++)
   1.289 +      {
   1.290 +         if (fmt->sdl_bpp != bpp)
   1.291 +         {
   1.292 +            continue;
   1.293 +         }
   1.294 +         
   1.295 +         if (!FULLSCREEN_TrySetMode(width,height,&fmt->ro))
   1.296 +         {
   1.297 +            return fmt;
   1.298 +         }
   1.299 +      }
   1.300 +
   1.301 +      /* Fuzzy matching for 15bpp & 16bpp */
   1.302 +      if (bpp == 15) { bpp = 16; }
   1.303 +      else if (bpp == 16) { bpp = 15; }
   1.304 +      else { break; }
   1.305     }
   1.306  
   1.307 -    /* Turn cursor off*/
   1.308 -    _kernel_oswrch(23);_kernel_oswrch(1);_kernel_oswrch(0);
   1.309 -    _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
   1.310 -    _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
   1.311 -    _kernel_oswrch(0);_kernel_oswrch(0);
   1.312 -
   1.313 -   return 1;
   1.314 +   SDL_SetError("Couldn't set requested mode");
   1.315 +   return NULL;
   1.316  }
   1.317  
   1.318  /* Get Start addresses for the screen banks */
   1.319 @@ -731,7 +738,7 @@
   1.320     int bpp = this->screen->format->BitsPerPixel;
   1.321  
   1.322     RISCOS_StoreWimpMode();
   1.323 -   if (FULLSCREEN_SetMode(width, height, bpp))
   1.324 +   if (!FULLSCREEN_TrySetMode(width, height, &this->hidden->format->ro))
   1.325     {
   1.326         unsigned char *buffer = this->hidden->alloc_bank; /* This is start of sprite data */
   1.327         /* Support back buffer mode only */
   1.328 @@ -740,7 +747,19 @@
   1.329         FULLSCREEN_SetupBanks(this);
   1.330  
   1.331         this->hidden->bank[0] = buffer + 60; /* Start of sprite data */
   1.332 -       if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
   1.333 +       if (bpp == 8)
   1.334 +       {
   1.335 +           /* Retain the SDL palette */
   1.336 +           _kernel_swi_regs regs;
   1.337 +           regs.r[0] = -1;
   1.338 +           regs.r[1] = -1;
   1.339 +           regs.r[2] = (int) this->hidden->bank[0];
   1.340 +           regs.r[3] = 0;
   1.341 +           regs.r[4] = 2; /* Flashing colours provided (source is sprite palette) */
   1.342 +           _kernel_swi(ColourTrans_WritePalette,&regs,&regs);
   1.343 +
   1.344 +           this->hidden->bank[0] += 2048;
   1.345 +       }
   1.346  
   1.347  	   this->hidden->current_bank = 0;
   1.348  	   this->screen->pixels = this->hidden->bank[0];
     2.1 --- a/src/video/riscos/SDL_riscosevents.c	Fri May 31 00:26:21 2019 +0100
     2.2 +++ b/src/video/riscos/SDL_riscosevents.c	Sat Jun 01 18:27:46 2019 +0100
     2.3 @@ -48,6 +48,11 @@
     2.4  #include <pthread.h>
     2.5  #endif
     2.6  
     2.7 +#if SDL_THREADS_DISABLED
     2.8 +/* Timer running function */
     2.9 +extern void RISCOS_CheckTimer();
    2.10 +#endif
    2.11 +
    2.12  /* The translation table from a RISC OS internal key numbers to a SDL keysym */
    2.13  static SDLKey RO_keymap[SDLK_LAST];
    2.14  
    2.15 @@ -76,20 +81,11 @@
    2.16  
    2.17  static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed);
    2.18  
    2.19 -void RISCOS_PollMouse(_THIS);
    2.20 -void RISCOS_PollKeyboard();
    2.21 +static void RISCOS_PollMouse(_THIS);
    2.22 +static void RISCOS_PollMouseHelper(_THIS, int fullscreen);
    2.23  
    2.24 -void RISCOS_PollMouseHelper(_THIS, int fullscreen);
    2.25 -
    2.26 -#if SDL_THREADS_DISABLED
    2.27 -extern void DRenderer_FillBuffers();
    2.28 -
    2.29 -/* Timer running function */
    2.30 -extern void RISCOS_CheckTimer();
    2.31 -
    2.32 -#else
    2.33 +#if !SDL_THREAD_DISABLED
    2.34  extern int riscos_using_threads;
    2.35 -
    2.36  #endif
    2.37  
    2.38  void FULLSCREEN_PumpEvents(_THIS)
    2.39 @@ -98,7 +94,6 @@
    2.40  	RISCOS_PollKeyboard();
    2.41  	RISCOS_PollMouse(this);
    2.42  #if SDL_THREADS_DISABLED
    2.43 -//	DRenderer_FillBuffers();
    2.44  	if (SDL_timer_running) RISCOS_CheckTimer();
    2.45  #else
    2.46  	/* Stop thread starvation, which will occur if the main loop
    2.47 @@ -255,8 +250,6 @@
    2.48     RISCOS_PollMouseHelper(this, 1);
    2.49  }
    2.50  
    2.51 -extern int mouseInWindow;
    2.52 -
    2.53  void WIMP_PollMouse(_THIS)
    2.54  {
    2.55     /* Only poll when mouse is over the window */
     3.1 --- a/src/video/riscos/SDL_riscosevents_c.h	Fri May 31 00:26:21 2019 +0100
     3.2 +++ b/src/video/riscos/SDL_riscosevents_c.h	Sat Jun 01 18:27:46 2019 +0100
     3.3 @@ -23,12 +23,14 @@
     3.4  
     3.5  #include "SDL_riscosvideo.h"
     3.6  
     3.7 -/* Variables and functions exported by SDL_sysevents.c to other parts 
     3.8 -   of the native video subsystem (SDL_sysvideo.c)
     3.9 +/* Variables and functions exported by SDL_riscosevents.c to other parts 
    3.10 +   of the native video subsystem
    3.11  */
    3.12  extern void RISCOS_InitOSKeymap(_THIS);
    3.13  extern void FULLSCREEN_PumpEvents(_THIS);
    3.14 -extern void WIMP_PumpEvents(_THIS);
    3.15 +extern void RISCOS_PollKeyboard();
    3.16 +extern void RISCOS_CheckMouseMode(_THIS);
    3.17 +extern void WIMP_PollMouse(_THIS);
    3.18  
    3.19 -/* end of SDL_nullevents_c.h ... */
    3.20 +/* end of SDL_riscosevents_c.h ... */
    3.21  
     4.1 --- a/src/video/riscos/SDL_riscosmouse.c	Fri May 31 00:26:21 2019 +0100
     4.2 +++ b/src/video/riscos/SDL_riscosmouse.c	Sat Jun 01 18:27:46 2019 +0100
     4.3 @@ -39,8 +39,6 @@
     4.4  static WMcursor *current_cursor = NULL;
     4.5  static WMcursor *defined_cursor = NULL;
     4.6  
     4.7 -extern int mouseInWindow;
     4.8 -
     4.9  /* Area to save cursor palette colours changed by SDL.
    4.10     Actual values will be read before we change to the SDL cursor */
    4.11  static Uint8 wimp_cursor_palette[2][5] = {
    4.12 @@ -50,9 +48,8 @@
    4.13  
    4.14  static int cursor_palette_saved = 0;
    4.15  
    4.16 -void WIMP_SaveCursorPalette();
    4.17 -void WIMP_RestoreWimpCursor();
    4.18 -void WIMP_SetSDLCursorPalette();
    4.19 +static void WIMP_SaveCursorPalette();
    4.20 +static void WIMP_SetSDLCursorPalette();
    4.21  
    4.22  
    4.23  void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
    4.24 @@ -188,7 +185,6 @@
    4.25  void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
    4.26  {
    4.27  	Uint8 move_block[5];
    4.28 -	_kernel_swi_regs regs;
    4.29  	int os_x, os_y;
    4.30  	int topLeftY;
    4.31  
     5.1 --- a/src/video/riscos/SDL_riscosmouse_c.h	Fri May 31 00:26:21 2019 +0100
     5.2 +++ b/src/video/riscos/SDL_riscosmouse_c.h	Sat Jun 01 18:27:46 2019 +0100
     5.3 @@ -33,13 +33,16 @@
     5.4  };
     5.5  
     5.6  /* Functions to be exported */
     5.7 -void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor);
     5.8 -WMcursor *RISCOS_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
     5.9 +extern void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor);
    5.10 +extern WMcursor *RISCOS_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
    5.11  
    5.12 -int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor);
    5.13 -void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
    5.14 +extern int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor);
    5.15 +extern void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
    5.16  
    5.17 -int WIMP_ShowWMCursor(_THIS, WMcursor *cursor);
    5.18 -void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
    5.19 +extern int WIMP_ShowWMCursor(_THIS, WMcursor *cursor);
    5.20 +extern void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
    5.21  
    5.22 -void WIMP_RestoreWimpCursor();
    5.23 +extern void WIMP_RestoreWimpCursor();
    5.24 +extern SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode);
    5.25 +
    5.26 +extern void WIMP_ReshowCursor(_THIS);
     6.1 --- a/src/video/riscos/SDL_riscossprite.c	Fri May 31 00:26:21 2019 +0100
     6.2 +++ b/src/video/riscos/SDL_riscossprite.c	Sat Jun 01 18:27:46 2019 +0100
     6.3 @@ -23,7 +23,7 @@
     6.4  
     6.5  /*
     6.6       File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
     6.7 -	 27 March 2003
     6.8 +     27 March 2003
     6.9  
    6.10       Implements Sprite plotting code for wimp display.window
    6.11  */
    6.12 @@ -34,73 +34,107 @@
    6.13  #include "SDL_stdinc.h"
    6.14  #include "SDL_riscosvideo.h"
    6.15  
    6.16 -extern void WIMP_ReadModeInfo(_THIS);
    6.17 +/* Check if the given pixel format is supported as a sprite */
    6.18 +int WIMP_IsSupportedSpriteFormat(const RISCOS_PixelFormat *fmt)
    6.19 +{
    6.20 +    _kernel_swi_regs r;
    6.21 +    int c;
    6.22 +
    6.23 +    /* HACK: Mode 28 won't report as having a full palette. Just assume it's supported */
    6.24 +    if (fmt->sprite_mode_word == 28) return 0;
    6.25 +
    6.26 +    /* OS_ReadModeVariable supports sprite mode words, so we can use that to sanity check things */
    6.27 +    r.r[0] = fmt->sprite_mode_word;
    6.28 +    r.r[1] = 3; /* NColour */
    6.29 +    _kernel_swi_c(OS_ReadModeVariable,&r,&r,&c);
    6.30 +    if (c || (r.r[2] != fmt->ncolour)) return -1;
    6.31 +    r.r[1] = 0; /* ModeFlags */
    6.32 +    _kernel_swi_c(OS_ReadModeVariable,&r,&r,&c);
    6.33 +    if (c || ((r.r[2] & 0xf280) != fmt->modeflags)) return -1;
    6.34 +    r.r[1] = 9; /* Log2BPP */
    6.35 +    _kernel_swi_c(OS_ReadModeVariable,&r,&r,&c);
    6.36 +    if (c || (r.r[2] != fmt->log2bpp)) return -1;
    6.37 +
    6.38 +    /* Looks good */
    6.39 +    return 0;
    6.40 +}
    6.41 +
    6.42 +/* Find a supported sprite format in the given BPP */
    6.43 +const RISCOS_SDL_PixelFormat *WIMP_FindSupportedSpriteFormat(int bpp)
    6.44 +{
    6.45 +   int pass;
    6.46 +   const RISCOS_SDL_PixelFormat *fmt;
    6.47 +
    6.48 +   for(pass=0;pass<2;pass++)
    6.49 +   {
    6.50 +      for (fmt = RISCOS_SDL_PixelFormats;fmt->sdl_bpp;fmt++)
    6.51 +      {
    6.52 +         if (fmt->sdl_bpp != bpp)
    6.53 +         {
    6.54 +            continue;
    6.55 +         }
    6.56 +         
    6.57 +         if (!WIMP_IsSupportedSpriteFormat(&fmt->ro))
    6.58 +         {
    6.59 +            return fmt;
    6.60 +         }
    6.61 +      }
    6.62 +
    6.63 +      /* Fuzzy matching for 15bpp & 16bpp */
    6.64 +      if (bpp == 15) { bpp = 16; }
    6.65 +      else if (bpp == 16) { bpp = 15; }
    6.66 +      else { break; }
    6.67 +   }
    6.68 +   return NULL;   
    6.69 +}
    6.70  
    6.71  /* Create sprite buffer for screen */
    6.72  
    6.73 -unsigned char *WIMP_CreateBuffer(int width, int height, int bpp)
    6.74 +unsigned char *WIMP_CreateBuffer(int width, int height, const RISCOS_PixelFormat *format)
    6.75  {
    6.76 -	int size;
    6.77 -	char sprite_name[12] = "display";
    6.78 -	unsigned char *buffer;
    6.79 -	_kernel_swi_regs regs;
    6.80 -	int bytesPerPixel;
    6.81 -	int bytesPerRow;
    6.82 -	int offsetToSpriteData = 60;
    6.83 +   int size;
    6.84 +   char sprite_name[12] = "display";
    6.85 +   unsigned char *buffer;
    6.86 +   _kernel_swi_regs regs;
    6.87 +   int bytesPerPixel = 1 << (format->log2bpp-3);
    6.88 +   int bytesPerRow;
    6.89 +   int offsetToSpriteData = 60;
    6.90  
    6.91 -	switch(bpp)
    6.92 -	{
    6.93 -	case 32: bytesPerPixel = 4; break;
    6.94 -	case 16: bytesPerPixel = 2; break;
    6.95 -	case 8:
    6.96 -	    bytesPerPixel = 1;
    6.97 -	    offsetToSpriteData += 2048; /* Add in size of palette */
    6.98 -	    break;
    6.99 -	default:
   6.100 -		return NULL;
   6.101 -		break;
   6.102 -	}
   6.103 +   if (format->log2bpp == 3)
   6.104 +   {
   6.105 +      offsetToSpriteData += 2048; /* Add in size of palette */
   6.106 +   }
   6.107  
   6.108 -	bytesPerRow = bytesPerPixel * width;
   6.109 +   bytesPerRow = bytesPerPixel * width;
   6.110  
   6.111 -	if ((bytesPerRow & 3) != 0)
   6.112 -	{
   6.113 -		bytesPerRow += 4 - (bytesPerRow & 3);
   6.114 -	}
   6.115 -	size = bytesPerRow * height;
   6.116 +   if ((bytesPerRow & 3) != 0)
   6.117 +   {
   6.118 +      bytesPerRow += 4 - (bytesPerRow & 3);
   6.119 +   }
   6.120 +   size = bytesPerRow * height;
   6.121  
   6.122 -	buffer = SDL_malloc( (size_t) size + offsetToSpriteData );
   6.123 -	if (!buffer) return NULL;
   6.124 +   buffer = SDL_malloc( (size_t) size + offsetToSpriteData );
   6.125 +   if (!buffer) return NULL;
   6.126  
   6.127     /* Initialise a sprite area */
   6.128  
   6.129 -	*(unsigned int *)buffer		= size + offsetToSpriteData;
   6.130 -	*(unsigned int *)(buffer + 8)	= 16;
   6.131 +   *(unsigned int *)buffer         = size + offsetToSpriteData;
   6.132 +   *(unsigned int *)(buffer + 8)   = 16;
   6.133  
   6.134 -	regs.r[0] = 256+9;
   6.135 -	regs.r[1] = (unsigned int)buffer;
   6.136 +   regs.r[0] = 256+9;
   6.137 +   regs.r[1] = (unsigned int)buffer;
   6.138     _kernel_swi(OS_SpriteOp, &regs, &regs);
   6.139  
   6.140 -	regs.r[0] = 256+15;
   6.141 -	regs.r[1] = (unsigned int)buffer;
   6.142 -	regs.r[2] = (unsigned int)&sprite_name;
   6.143 -	regs.r[3] = 0; /* Palette flag: 0 = no palette */
   6.144 -	regs.r[4] = width;
   6.145 -	regs.r[5] = height;
   6.146 -	if (bpp == 8)
   6.147 -	{
   6.148 -		/* Use old style mode number */
   6.149 -		regs.r[6] = 28; /* 8bpp 90x90dpi */
   6.150 -	} else
   6.151 -	{
   6.152 -		regs.r[6] = (((bpp == 16) ? 5 : 6) << 27) /* Type 6 = 32bpp sprite, 5 = 16bpp sprite */
   6.153 -					| (90 << 14) /* Vertical dpi */
   6.154 -					| (90 << 1)  /* Horizontal dpi */
   6.155 -					| 1; /* Marker to distinguish between mode selectors and sprite modes */
   6.156 -	}
   6.157 +   regs.r[0] = 256+15;
   6.158 +   regs.r[1] = (unsigned int)buffer;
   6.159 +   regs.r[2] = (unsigned int)&sprite_name;
   6.160 +   regs.r[3] = 0; /* Palette flag: 0 = no palette */
   6.161 +   regs.r[4] = width;
   6.162 +   regs.r[5] = height;
   6.163 +   regs.r[6] = format->sprite_mode_word;
   6.164     if (_kernel_swi(OS_SpriteOp, &regs, &regs) == NULL)
   6.165     {
   6.166 -       if (bpp == 8)
   6.167 +       if (format->log2bpp == 3)
   6.168         {
   6.169            /* Modify sprite to take into account 256 colour palette */
   6.170            int *sprite = (int *)(buffer + 16);
     7.1 --- a/src/video/riscos/SDL_riscostask.c	Fri May 31 00:26:21 2019 +0100
     7.2 +++ b/src/video/riscos/SDL_riscostask.c	Sat Jun 01 18:27:46 2019 +0100
     7.3 @@ -37,6 +37,8 @@
     7.4  
     7.5  #include "SDL_stdinc.h"
     7.6  #include "SDL_riscostask.h"
     7.7 +#include "SDL_riscosvideo.h"
     7.8 +#include "SDL_riscosmouse_c.h"
     7.9  
    7.10  #if !SDL_THREADS_DISABLED
    7.11  #include <pthread.h>
    7.12 @@ -54,8 +56,6 @@
    7.13  
    7.14  static int stored_mode = -1; /* -1 when in desktop, mode number or pointer when full screen */
    7.15  
    7.16 -extern int mouseInWindow; /* Mouse is in WIMP window */
    7.17 -
    7.18  /* Local function */
    7.19  
    7.20  static int RISCOS_GetTaskName(char *task_name, size_t maxlen);
     8.1 --- a/src/video/riscos/SDL_riscostask.h	Fri May 31 00:26:21 2019 +0100
     8.2 +++ b/src/video/riscos/SDL_riscostask.h	Sat Jun 01 18:27:46 2019 +0100
     8.3 @@ -26,6 +26,9 @@
     8.4  	26 March 2003
     8.5  */
     8.6  
     8.7 +extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */
     8.8 +extern int riscos_closeaction; /* Close icon action */
     8.9 +
    8.10  /* Task initialisation/Clean up */
    8.11  
    8.12  extern int RISCOS_InitTask();
     9.1 --- a/src/video/riscos/SDL_riscosvideo.c	Fri May 31 00:26:21 2019 +0100
     9.2 +++ b/src/video/riscos/SDL_riscosvideo.c	Sat Jun 01 18:27:46 2019 +0100
     9.3 @@ -54,30 +54,63 @@
     9.4  static SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
     9.5  static SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
     9.6  
     9.7 -int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
     9.8 -
     9.9 -int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
    9.10 -/* Mouse checking */
    9.11 -void RISCOS_CheckMouseMode(_THIS);
    9.12 -extern SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode);
    9.13 -
    9.14 -/* Fullscreen mode functions */
    9.15 -extern SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    9.16 -extern void FULLSCREEN_BuildModeList(_THIS);
    9.17 -extern void	FULLSCREEN_SetDeviceMode(_THIS);
    9.18 -extern int FULLSCREEN_ToggleFromWimp(_THIS);
    9.19 -
    9.20 -/* Wimp mode functions */
    9.21 -extern SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current,	int width, int height, int bpp, Uint32 flags);
    9.22 -extern void WIMP_DeleteWindow(_THIS);
    9.23 -extern int WIMP_ToggleFromFullScreen(_THIS);
    9.24 -
    9.25  /* Hardware surface functions - common to WIMP and FULLSCREEN */
    9.26  static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface);
    9.27  static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface);
    9.28  static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
    9.29  static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface);
    9.30  
    9.31 +/* Table of known pixel formats */
    9.32 +const RISCOS_SDL_PixelFormat *RISCOS_SDL_PixelFormats = (const RISCOS_SDL_PixelFormat[]) {
    9.33 +/* 8bpp palettized */
    9.34 +{ { 255,   0x0080, 3,         28 }, 8, 0, 0, 0 },
    9.35 +/* 12bpp true colour */
    9.36 +{ { 4095,  0x0000, 4, 0x79004051 }, 12, 0x0f,     0x0f<<4, 0x0f<<8  },
    9.37 +{ { 4095,  0x4000, 4, 0x79004051 }, 12, 0x0f<<8,  0x0f<<4, 0x0f     },
    9.38 +/* 15bpp true colour */
    9.39 +{ { 65535, 0x0000, 4, 0x28168003 }, 15, 0x1f,     0x1f<<5, 0x1f<<10 },
    9.40 +{ { 65535, 0x4000, 4, 0x78504051 }, 15, 0x1f<<10, 0x1f<<5, 0x1f     },
    9.41 +/* 16bpp true colour */
    9.42 +{ { 65535, 0x0080, 4, 0x50168003 }, 16, 0x1f,     0x3f<<5, 0x1f<<11 },
    9.43 +{ { 65535, 0x4080, 4, 0x78A04051 }, 16, 0x1f<<11, 0x3f<<5, 0x1f     },
    9.44 +/* 32bpp true colour */
    9.45 +{ { -1,    0x0000, 5, 0x30168003 }, 32, 0xff,     0xff<<8, 0xff<<16 },
    9.46 +{ { -1,    0x4000, 5, 0x78604051 }, 32, 0xff<<16, 0xff<<8, 0xff     },
    9.47 +/* Terminator */
    9.48 +{ },
    9.49 +};
    9.50 +
    9.51 +const RISCOS_SDL_PixelFormat *RISCOS_CurrentPixelFormat()
    9.52 +{
    9.53 +	_kernel_swi_regs regs;
    9.54 +	int vduvars[4];
    9.55 +	const RISCOS_SDL_PixelFormat *fmt;
    9.56 +
    9.57 +	vduvars[0] = 3; /* NColour */
    9.58 +	vduvars[1] = 0; /* ModeFlags */
    9.59 +	vduvars[2] = 9; /* Log2BPP */
    9.60 +	vduvars[3] = -1;
    9.61 +
    9.62 +	regs.r[0] = (int) vduvars;
    9.63 +	regs.r[1] = (int) vduvars;
    9.64 +
    9.65 +	_kernel_swi(OS_ReadVduVariables, &regs, &regs);
    9.66 +
    9.67 +	vduvars[1] &= 0xf280; /* Mask out the bits we don't care about */
    9.68 +
    9.69 +	fmt = RISCOS_SDL_PixelFormats;
    9.70 +	while (fmt->sdl_bpp)
    9.71 +	{
    9.72 +		if ((fmt->ro.ncolour == vduvars[0]) && (fmt->ro.modeflags == vduvars[1]) && (fmt->ro.log2bpp == vduvars[2]))
    9.73 +		{
    9.74 +			return fmt;
    9.75 +		}
    9.76 +		fmt++;
    9.77 +	}
    9.78 +
    9.79 +	return NULL;
    9.80 +}
    9.81 +
    9.82  /* RISC OS driver bootstrap functions */
    9.83  
    9.84  static int RISCOS_Available(void)
    9.85 @@ -162,7 +195,9 @@
    9.86  int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
    9.87  {
    9.88  	_kernel_swi_regs regs;
    9.89 -	int vars[4], vals[3];
    9.90 +	int vars[3];
    9.91 +	const RISCOS_SDL_PixelFormat *fmt;
    9.92 +	SDL_PixelFormat *fmt2 = NULL;
    9.93  
    9.94  	if (RISCOS_InitTask() == 0)
    9.95  	{
    9.96 @@ -170,49 +205,36 @@
    9.97  		return 0;
    9.98  	}
    9.99  
   9.100 -	vars[0] = 9;  /* Log base 2 bpp */
   9.101 -	vars[1] = 11; /* XWndLimit - num x pixels -1 */
   9.102 -	vars[2] = 12; /* YWndLimit - num y pixels -1 */
   9.103 -	vars[3] = -1; /* Terminate list */
   9.104 +	vars[0] = 11; /* XWndLimit - num x pixels -1 */
   9.105 +	vars[1] = 12; /* YWndLimit - num y pixels -1 */
   9.106 +	vars[2] = -1; /* Terminate list */
   9.107  	regs.r[0] = (int)vars;
   9.108 -	regs.r[1] = (int)vals;
   9.109 +	regs.r[1] = (int)vars;
   9.110  
   9.111  	_kernel_swi(OS_ReadVduVariables, &regs, &regs);
   9.112 -	vformat->BitsPerPixel = (1 << vals[0]);
   9.113  
   9.114  	/* Determine the current screen size */
   9.115 -	this->info.current_w = vals[1] + 1;
   9.116 -	this->info.current_h = vals[2] + 1;
   9.117 +	this->info.current_w = vars[0] + 1;
   9.118 +	this->info.current_h = vars[1] + 1;
   9.119  
   9.120 -	/* Minimum bpp for SDL is 8 */
   9.121 -	if (vformat->BitsPerPixel < 8) vformat->BitsPerPixel = 8;
   9.122 -
   9.123 -
   9.124 -	switch (vformat->BitsPerPixel)
   9.125 +	fmt = RISCOS_CurrentPixelFormat();
   9.126 +	if (fmt != NULL)
   9.127  	{
   9.128 -		case 15:
   9.129 -		case 16:
   9.130 -			vformat->Bmask = 0x00007c00;
   9.131 -			vformat->Gmask = 0x000003e0;
   9.132 -			vformat->Rmask = 0x0000001f;
   9.133 -			vformat->BitsPerPixel = 16; /* SDL wants actual number of bits used */
   9.134 -			vformat->BytesPerPixel = 2;
   9.135 -			break;
   9.136 -
   9.137 -		case 24:
   9.138 -		case 32:
   9.139 -			vformat->Bmask = 0x00ff0000;
   9.140 -			vformat->Gmask = 0x0000ff00;
   9.141 -			vformat->Rmask = 0x000000ff;
   9.142 -			vformat->BytesPerPixel = 4;
   9.143 -			break;
   9.144 -
   9.145 -		default:
   9.146 -			vformat->Bmask = 0;
   9.147 -			vformat->Gmask = 0;
   9.148 -			vformat->Rmask = 0;
   9.149 -			vformat->BytesPerPixel = 1;			
   9.150 -			break;
   9.151 +		fmt2 = SDL_AllocFormat(fmt->sdl_bpp,fmt->rmask,fmt->gmask,fmt->bmask,0);
   9.152 +	}
   9.153 +	if (fmt2 != NULL)
   9.154 +	{
   9.155 +		*vformat = *fmt2;
   9.156 +		SDL_free(fmt2);
   9.157 +	}
   9.158 +	else
   9.159 +	{
   9.160 +		/* Panic! */
   9.161 +		vformat->BitsPerPixel = 8;
   9.162 +		vformat->Bmask = 0;
   9.163 +		vformat->Gmask = 0;
   9.164 +		vformat->Rmask = 0;
   9.165 +		vformat->BytesPerPixel = 1;
   9.166  	}
   9.167  
   9.168  	/* Fill in some window manager capabilities */
    10.1 --- a/src/video/riscos/SDL_riscosvideo.h	Fri May 31 00:26:21 2019 +0100
    10.2 +++ b/src/video/riscos/SDL_riscosvideo.h	Sat Jun 01 18:27:46 2019 +0100
    10.3 @@ -31,6 +31,23 @@
    10.4  /* Hidden "this" pointer for the video functions */
    10.5  #define _THIS	SDL_VideoDevice *this
    10.6  
    10.7 +/* Information that RISC OS uses to identify/describe pixel formats */
    10.8 +typedef struct {
    10.9 +	int ncolour,modeflags,log2bpp;
   10.10 +	Uint32 sprite_mode_word;
   10.11 +} RISCOS_PixelFormat;
   10.12 +
   10.13 +/* RISC OS information combined with SDL information */
   10.14 +typedef struct {
   10.15 +	RISCOS_PixelFormat ro;
   10.16 +	int sdl_bpp;
   10.17 +	Uint32 rmask;
   10.18 +	Uint32 gmask;
   10.19 +	Uint32 bmask;
   10.20 +} RISCOS_SDL_PixelFormat;
   10.21 +
   10.22 +extern const RISCOS_SDL_PixelFormat *RISCOS_SDL_PixelFormats; /* Table of known formats */
   10.23 +
   10.24  
   10.25  /* Private display data */
   10.26  
   10.27 @@ -41,7 +58,6 @@
   10.28      int height;
   10.29      int xeig;
   10.30      int yeig;
   10.31 -	int screen_bpp;
   10.32  	int screen_width;
   10.33  	int screen_height;
   10.34  	char *pixtrans;
   10.35 @@ -51,6 +67,8 @@
   10.36  	unsigned int window_handle;
   10.37  	char title[256];
   10.38  
   10.39 +    const RISCOS_SDL_PixelFormat *format; /* Format of current SDL display */
   10.40 +
   10.41  #define NUM_MODELISTS	4		/* 8, 16, 24, and 32 bits-per-pixel */
   10.42      int SDL_nummodes[NUM_MODELISTS];
   10.43      SDL_Rect **SDL_modelist[NUM_MODELISTS];
   10.44 @@ -60,4 +78,40 @@
   10.45  #define SDL_nummodes		(this->hidden->SDL_nummodes)
   10.46  #define SDL_modelist		(this->hidden->SDL_modelist)
   10.47  
   10.48 +/* SDL_riscosvideo.c */
   10.49 +extern const RISCOS_SDL_PixelFormat *RISCOS_CurrentPixelFormat(); /* Find the current format */
   10.50 +extern int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
   10.51 +extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
   10.52 +
   10.53 +/* SDL_riscossprite.c */
   10.54 +extern int WIMP_IsSupportedSpriteFormat(const RISCOS_PixelFormat *fmt);
   10.55 +extern const RISCOS_SDL_PixelFormat *WIMP_FindSupportedSpriteFormat(int bpp);
   10.56 +extern unsigned char *WIMP_CreateBuffer(int width, int height, const RISCOS_PixelFormat *format);
   10.57 +extern void WIMP_SetupPlotInfo(_THIS);
   10.58 +extern void WIMP_PlotSprite(_THIS, int x, int y);
   10.59 +
   10.60 +/* SDL_wimpvideo.c */
   10.61 +extern void WIMP_PumpEvents(_THIS);
   10.62 +extern void WIMP_SetFocus(int win);
   10.63 +extern void WIMP_ReadModeInfo(_THIS);
   10.64 +extern void WIMP_DeleteWindow(_THIS);
   10.65 +extern SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
   10.66 +extern int WIMP_ToggleFromFullScreen(_THIS);
   10.67 +
   10.68 +/* SDL_riscosFullScreenVideo.c */
   10.69 +extern void FULLSCREEN_SetDeviceMode(_THIS);
   10.70 +extern const RISCOS_SDL_PixelFormat *FULLSCREEN_SetMode(int width, int height, int bpp);
   10.71 +extern void FULLSCREEN_BuildModeList(_THIS);
   10.72 +extern SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
   10.73 +extern int FULLSCREEN_ToggleFromWimp(_THIS);
   10.74 +
   10.75 +/* SDL_riscosASM.S */
   10.76 +extern void RISCOS_Put32(void *to, int pixels, int pitch, int rows, void *from, int src_skip_bytes); /* Fast assembler copy */
   10.77 +
   10.78 +/* SDL_wimppoll.c */
   10.79 +extern int mouseInWindow; /* Mouse is in WIMP window */
   10.80 +extern int hasFocus;
   10.81 +extern void WIMP_Poll(_THIS, int waitTime);
   10.82 +
   10.83 +
   10.84  #endif /* _SDL_risosvideo_h */
    11.1 --- a/src/video/riscos/SDL_wimppoll.c	Fri May 31 00:26:21 2019 +0100
    11.2 +++ b/src/video/riscos/SDL_wimppoll.c	Sat Jun 01 18:27:46 2019 +0100
    11.3 @@ -48,16 +48,7 @@
    11.4  #include <pthread.h>
    11.5  #endif
    11.6  
    11.7 -/* Local functions */
    11.8 -void WIMP_Poll(_THIS, int waitTime);
    11.9 -void WIMP_SetFocus(int win);
   11.10  
   11.11 -/* SDL_riscossprite functions */
   11.12 -void WIMP_PlotSprite(_THIS, int x, int y);
   11.13 -
   11.14 -
   11.15 -extern void WIMP_PollMouse(_THIS);
   11.16 -extern void RISCOS_PollKeyboard();
   11.17  
   11.18  #if SDL_THREADS_DISABLED
   11.19  /* Timer running function */
   11.20 @@ -66,10 +57,6 @@
   11.21  extern int riscos_using_threads;
   11.22  #endif
   11.23  
   11.24 -/* Mouse cursor handling */
   11.25 -extern void WIMP_ReshowCursor(_THIS);
   11.26 -extern void WIMP_RestoreWimpCursor();
   11.27 -
   11.28  int hasFocus = 0;
   11.29  int mouseInWindow = 0;
   11.30   
    12.1 --- a/src/video/riscos/SDL_wimpvideo.c	Fri May 31 00:26:21 2019 +0100
    12.2 +++ b/src/video/riscos/SDL_wimpvideo.c	Sat Jun 01 18:27:46 2019 +0100
    12.3 @@ -43,87 +43,51 @@
    12.4  #include "kernel.h"
    12.5  #include "swis.h"
    12.6  
    12.7 -/* Initialization/Query functions */
    12.8 -SDL_Rect **WIMP_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
    12.9 -SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
   12.10 -int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
   12.11 -void WIMP_SetWMCaption(_THIS, const char *title, const char *icon);
   12.12 -
   12.13 -
   12.14 -extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp);
   12.15 -extern void WIMP_PumpEvents(_THIS);
   12.16 -extern void WIMP_PlotSprite(_THIS, int x, int y);
   12.17 -extern void WIMP_SetupPlotInfo(_THIS);
   12.18 -extern void WIMP_SetFocus(int win);
   12.19 -
   12.20 -/* etc. */
   12.21 +static int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
   12.22 +static void WIMP_SetWMCaption(_THIS, const char *title, const char *icon);
   12.23  static void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
   12.24  
   12.25  /* RISC OS Wimp handling helpers */
   12.26 -void WIMP_ReadModeInfo(_THIS);
   12.27 -unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface);
   12.28 -void WIMP_SetDeviceMode(_THIS);
   12.29 -void WIMP_DeleteWindow(_THIS);
   12.30 +static unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface);
   12.31 +static void WIMP_SetDeviceMode(_THIS);
   12.32  
   12.33 -/* FULLSCREEN function required for wimp/fullscreen toggling */
   12.34 -extern int FULLSCREEN_SetMode(int width, int height, int bpp);
   12.35 -
   12.36 -/* Currently need to set this up here as it only works if you
   12.37 -   start up in a Wimp mode */
   12.38 -extern int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
   12.39 -
   12.40 -extern int riscos_backbuffer;
   12.41 -extern int riscos_closeaction;
   12.42 -
   12.43 -/* Following needed to ensure window is shown immediately */
   12.44 -extern int hasFocus;
   12.45 -extern void WIMP_Poll(_THIS, int waitTime);
   12.46  
   12.47  SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current,
   12.48  				int width, int height, int bpp, Uint32 flags)
   12.49  {
   12.50 -   Uint32 Rmask = 0;
   12.51 -   Uint32 Gmask = 0;
   12.52 -   Uint32 Bmask = 0;
   12.53 -   unsigned char *buffer = NULL;
   12.54 -   int bytesPerPixel = 1;
   12.55 +	unsigned char *buffer = NULL;
   12.56 +	int bytesPerPixel;
   12.57 +	const RISCOS_SDL_PixelFormat *fmt;
   12.58  
   12.59 -   /* Don't support double buffering in Wimp mode */
   12.60 -   flags &= ~SDL_DOUBLEBUF;
   12.61 -   flags &= ~SDL_HWSURFACE;
   12.62 +	/* Don't support double buffering in Wimp mode */
   12.63 +	flags &= ~SDL_DOUBLEBUF;
   12.64 +	flags &= ~SDL_HWSURFACE;
   12.65  
   12.66 -   switch(bpp)
   12.67 -   {
   12.68 -	case 8:
   12.69 +	/* Identify the current pixel format */
   12.70 +	fmt = RISCOS_CurrentPixelFormat();
   12.71 +	/* If it's the same (approximate) BPP as the desired BPP, use it directly (less overhead in sprite rendering) */
   12.72 +	if ((fmt == NULL) || (fmt->sdl_bpp != ((bpp+1)&~1)))
   12.73 +	{
   12.74 +		/* Not a good match - look for a supported format which is correct */
   12.75 +		fmt = WIMP_FindSupportedSpriteFormat(bpp);
   12.76 +		if (fmt == NULL)
   12.77 +		{
   12.78 +			SDL_SetError("Pixel depth not supported");
   12.79 +			return NULL;
   12.80 +		}
   12.81 +	}
   12.82 +
   12.83 +	if (fmt->sdl_bpp == 8)
   12.84 +	{
   12.85  		/* Emulated palette using ColourTrans */
   12.86  		flags |= SDL_HWPALETTE;
   12.87 -		break;
   12.88 -
   12.89 -	case 15:
   12.90 -	case 16:
   12.91 -		Bmask = 0x00007c00;
   12.92 -		Gmask = 0x000003e0;
   12.93 -		Rmask = 0x0000001f;
   12.94 -		bytesPerPixel = 2;
   12.95 -		break;
   12.96 -
   12.97 -	case 32:
   12.98 -		Bmask = 0x00ff0000;
   12.99 -		Gmask = 0x0000ff00;
  12.100 -		Rmask = 0x000000ff;
  12.101 -		bytesPerPixel = 4;
  12.102 -		break;
  12.103 -
  12.104 -	default:
  12.105 -		SDL_SetError("Pixel depth not supported");
  12.106 -		return NULL;
  12.107 -		break;
  12.108 -   }
  12.109 +	}
  12.110 +	bytesPerPixel = 1 << (fmt->ro.log2bpp - 3);
  12.111  
  12.112  /* 	printf("Setting mode %dx%d\n", width, height);*/
  12.113  
  12.114  	/* Allocate the new pixel format for the screen */
  12.115 -	if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
  12.116 +	if ( ! SDL_ReallocFormat(current, fmt->sdl_bpp, fmt->rmask, fmt->gmask, fmt->bmask, 0) ) {
  12.117  		SDL_SetError("Couldn't allocate new pixel format for requested mode");
  12.118  		return(NULL);
  12.119  	}
  12.120 @@ -133,7 +97,7 @@
  12.121  	this->hidden->height = current->h = height;
  12.122  
  12.123  	if (bpp == 15) bpp = 16;
  12.124 -	buffer = WIMP_CreateBuffer(width, height, bpp);
  12.125 +	buffer = WIMP_CreateBuffer(width, height, &fmt->ro);
  12.126  	if (buffer == NULL)
  12.127  	{
  12.128  		SDL_SetError("Couldn't create sprite for video memory");
  12.129 @@ -155,6 +119,7 @@
  12.130  		/* Sprites are 32bit word aligned */
  12.131  		current->pitch += (4 - (current->pitch & 3));
  12.132  	}
  12.133 +	this->hidden->format = fmt;
  12.134  
  12.135    	current->flags = flags | SDL_PREALLOC;
  12.136  
  12.137 @@ -214,7 +179,6 @@
  12.138  	_kernel_swi(OS_ReadVduVariables, &regs, &regs);
  12.139  	this->hidden->xeig = vals[0];
  12.140  	this->hidden->yeig = vals[1];
  12.141 -	this->hidden->screen_bpp = 1 << vals[2];
  12.142  	this->hidden->screen_width = vals[3] + 1;
  12.143  	this->hidden->screen_height = vals[4] + 1;
  12.144  }
  12.145 @@ -238,6 +202,8 @@
  12.146  	this->ShowWMCursor = WIMP_ShowWMCursor;
  12.147  	this->WarpWMCursor = WIMP_WarpWMCursor;
  12.148  
  12.149 +/* Currently need to set this up here as it only works if you
  12.150 +   start up in a Wimp mode */
  12.151          this->ToggleFullScreen = RISCOS_ToggleFullScreen;
  12.152  
  12.153  	this->PumpEvents = WIMP_PumpEvents;	
  12.154 @@ -432,7 +398,7 @@
  12.155     {
  12.156        /* Need to create a sprite for the screen and copy the data to it */
  12.157        unsigned char *data;
  12.158 -      buffer = WIMP_CreateBuffer(width, height, bpp);
  12.159 +      buffer = WIMP_CreateBuffer(width, height, &this->hidden->format->ro);
  12.160        data = buffer + 60;         /* Start of sprite data */
  12.161        if (bpp == 8) data += 2048;  /* 8bpp sprite have palette first */
  12.162