src/video/riscos/SDL_riscosvideo.c
author Cameron Cawley <ccawley2011@gmail.com>
Tue, 18 Jun 2019 23:55:01 +0100
branchSDL-1.2
changeset 12913 d07b4feae69c
parent 12786 4e73be7b4787
child 12914 87d60cae0273
permissions -rw-r--r--
riscos: Improve error reporting
     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 /* Hardware surface functions - common to WIMP and FULLSCREEN */
    58 static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface);
    59 static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface);
    60 static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
    61 static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface);
    62 
    63 /* Table of known pixel formats */
    64 const RISCOS_SDL_PixelFormat *RISCOS_SDL_PixelFormats = (const RISCOS_SDL_PixelFormat[]) {
    65 /* 8bpp palettized */
    66 { { 255,   0x0080, 3,         28 }, 8, 0, 0, 0 },
    67 /* 12bpp true colour */
    68 { { 4095,  0x0000, 4, 0x79004051 }, 12, 0x0f,     0x0f<<4, 0x0f<<8  },
    69 { { 4095,  0x4000, 4, 0x79004051 }, 12, 0x0f<<8,  0x0f<<4, 0x0f     },
    70 /* 15bpp true colour */
    71 { { 65535, 0x0000, 4, 0x28168003 }, 15, 0x1f,     0x1f<<5, 0x1f<<10 },
    72 { { 65535, 0x4000, 4, 0x78504051 }, 15, 0x1f<<10, 0x1f<<5, 0x1f     },
    73 /* 16bpp true colour */
    74 { { 65535, 0x0080, 4, 0x50168003 }, 16, 0x1f,     0x3f<<5, 0x1f<<11 },
    75 { { 65535, 0x4080, 4, 0x78A04051 }, 16, 0x1f<<11, 0x3f<<5, 0x1f     },
    76 /* 32bpp true colour */
    77 { { -1,    0x0000, 5, 0x30168003 }, 32, 0xff,     0xff<<8, 0xff<<16 },
    78 { { -1,    0x4000, 5, 0x78604051 }, 32, 0xff<<16, 0xff<<8, 0xff     },
    79 /* Terminator */
    80 { },
    81 };
    82 
    83 const RISCOS_SDL_PixelFormat *RISCOS_CurrentPixelFormat()
    84 {
    85 	_kernel_swi_regs regs;
    86 	int vduvars[4];
    87 	const RISCOS_SDL_PixelFormat *fmt;
    88 
    89 	vduvars[0] = 3; /* NColour */
    90 	vduvars[1] = 0; /* ModeFlags */
    91 	vduvars[2] = 9; /* Log2BPP */
    92 	vduvars[3] = -1;
    93 
    94 	regs.r[0] = (int) vduvars;
    95 	regs.r[1] = (int) vduvars;
    96 
    97 	_kernel_swi(OS_ReadVduVariables, &regs, &regs);
    98 
    99 	vduvars[1] &= 0xf280; /* Mask out the bits we don't care about */
   100 
   101 	fmt = RISCOS_SDL_PixelFormats;
   102 	while (fmt->sdl_bpp)
   103 	{
   104 		if ((fmt->ro.ncolour == vduvars[0]) && (fmt->ro.modeflags == vduvars[1]) && (fmt->ro.log2bpp == vduvars[2]))
   105 		{
   106 			return fmt;
   107 		}
   108 		fmt++;
   109 	}
   110 
   111 	return NULL;
   112 }
   113 
   114 /* RISC OS driver bootstrap functions */
   115 
   116 static int RISCOS_Available(void)
   117 {
   118 	return(1);
   119 }
   120 
   121 static void RISCOS_DeleteDevice(SDL_VideoDevice *device)
   122 {
   123 	SDL_free(device->hidden);
   124 	SDL_free(device);
   125 }
   126 
   127 static SDL_VideoDevice *RISCOS_CreateDevice(int devindex)
   128 {
   129 	SDL_VideoDevice *device;
   130 
   131 	/* Initialize all variables that we clean on shutdown */
   132 	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
   133 	if ( device ) {
   134 		SDL_memset(device, 0, (sizeof *device));
   135 		device->hidden = (struct SDL_PrivateVideoData *)
   136 				SDL_malloc((sizeof *device->hidden));
   137 	}
   138 	if ( (device == NULL) || (device->hidden == NULL) ) {
   139 		SDL_OutOfMemory();
   140 		if ( device ) {
   141 			SDL_free(device);
   142 		}
   143 		return(0);
   144 	}
   145 	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
   146 
   147 	/* Set the function pointers */
   148 	device->VideoInit = RISCOS_VideoInit;
   149 	device->VideoQuit = RISCOS_VideoQuit;
   150 
   151 	device->ListModes = RISCOS_ListModes;
   152 	device->SetVideoMode = RISCOS_SetVideoMode;
   153 	device->CreateYUVOverlay = NULL;
   154 	device->AllocHWSurface = RISCOS_AllocHWSurface;
   155 	device->CheckHWBlit = NULL;
   156 	device->FillHWRect = NULL;
   157 	device->SetHWColorKey = NULL;
   158 	device->SetHWAlpha = NULL;
   159 	device->LockHWSurface = RISCOS_LockHWSurface;
   160 	device->UnlockHWSurface = RISCOS_UnlockHWSurface;
   161 	device->FreeHWSurface = RISCOS_FreeHWSurface;
   162 	
   163 	device->FreeWMCursor = RISCOS_FreeWMCursor;
   164 	device->CreateWMCursor = RISCOS_CreateWMCursor;
   165 	device->CheckMouseMode = RISCOS_CheckMouseMode;
   166     device->GrabInput = RISCOS_GrabInput;
   167 
   168 	device->InitOSKeymap = RISCOS_InitOSKeymap;
   169 
   170 	device->GetWMInfo = RISCOS_GetWmInfo;
   171 
   172 	device->free = RISCOS_DeleteDevice;
   173 
   174 /* Can't get Toggle screen to work if program starts up in Full screen mode so
   175    disable it here and re-enable it when a wimp screen is chosen */
   176     device->ToggleFullScreen = NULL; /*RISCOS_ToggleFullScreen;*/
   177 
   178 	/* Set other entries for fullscreen mode */
   179 	FULLSCREEN_SetDeviceMode(device);
   180 
   181 	/* Mouse pointer needs to use the WIMP ShowCursor version so
   182 	   that it doesn't modify the pointer until the SDL Window is
   183 	   entered or the application goes full screen */
   184 	device->ShowWMCursor = WIMP_ShowWMCursor;
   185 
   186 	return device;
   187 }
   188 
   189 VideoBootStrap RISCOS_bootstrap = {
   190 	RISCOSVID_DRIVER_NAME, "RISC OS video driver",
   191 	RISCOS_Available, RISCOS_CreateDevice
   192 };
   193 
   194 
   195 int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
   196 {
   197 	_kernel_swi_regs regs;
   198 	int vars[3];
   199 	const RISCOS_SDL_PixelFormat *fmt;
   200 	SDL_PixelFormat *fmt2 = NULL;
   201 
   202 	if (RISCOS_InitTask() == 0)
   203 	{
   204 		return 0;
   205 	}
   206 
   207 	vars[0] = 11; /* XWndLimit - num x pixels -1 */
   208 	vars[1] = 12; /* YWndLimit - num y pixels -1 */
   209 	vars[2] = -1; /* Terminate list */
   210 	regs.r[0] = (int)vars;
   211 	regs.r[1] = (int)vars;
   212 
   213 	_kernel_swi(OS_ReadVduVariables, &regs, &regs);
   214 
   215 	/* Determine the current screen size */
   216 	this->info.current_w = vars[0] + 1;
   217 	this->info.current_h = vars[1] + 1;
   218 
   219 	fmt = RISCOS_CurrentPixelFormat();
   220 	if (fmt != NULL)
   221 	{
   222 		fmt2 = SDL_AllocFormat(fmt->sdl_bpp,fmt->rmask,fmt->gmask,fmt->bmask,0);
   223 	}
   224 	if (fmt2 != NULL)
   225 	{
   226 		*vformat = *fmt2;
   227 		SDL_free(fmt2);
   228 	}
   229 	else
   230 	{
   231 		/* Panic! */
   232 		vformat->BitsPerPixel = 8;
   233 		vformat->Bmask = 0;
   234 		vformat->Gmask = 0;
   235 		vformat->Rmask = 0;
   236 		vformat->BytesPerPixel = 1;
   237 	}
   238 
   239 	/* Fill in some window manager capabilities */
   240 	this->info.wm_available = 1;
   241 
   242 	/* We're done! */
   243 	return(0);
   244 }
   245 
   246 /* Note:  If we are terminated, this could be called in the middle of
   247    another SDL video routine -- notably UpdateRects.
   248 */
   249 void RISCOS_VideoQuit(_THIS)
   250 {
   251 	RISCOS_ExitTask();
   252 
   253 	if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
   254 	this->hidden->alloc_bank = 0;
   255 }
   256 
   257 
   258 SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   259 {
   260 	if (flags & SDL_FULLSCREEN)
   261 	{
   262 		/* Build mode list when first required. */
   263 		if (SDL_nummodes[0] == 0) FULLSCREEN_BuildModeList(this);
   264 
   265 		return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
   266 	} else
   267 		return (SDL_Rect **)-1;
   268 }
   269 
   270 
   271 /* Set up video mode */
   272 SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current,
   273 				int width, int height, int bpp, Uint32 flags)
   274 {
   275 	if (flags & SDL_FULLSCREEN)
   276 	{
   277 	    RISCOS_StoreWimpMode();
   278 		/* Dump wimp window on switch to full screen */
   279   	    if (this->hidden->window_handle) WIMP_DeleteWindow(this);
   280 
   281 		return FULLSCREEN_SetVideoMode(this, current, width, height, bpp, flags);
   282 	} else
   283 	{
   284 	    RISCOS_RestoreWimpMode();
   285 		return WIMP_SetVideoMode(this, current, width, height, bpp, flags);
   286 	}
   287 }
   288 
   289 
   290 /* We don't actually allow hardware surfaces other than the main one */
   291 static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface)
   292 {
   293 	return(-1);
   294 }
   295 static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface)
   296 {
   297 	return;
   298 }
   299 
   300 /* We need to wait for vertical retrace on page flipped displays */
   301 static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface)
   302 {
   303 	return(0);
   304 }
   305 
   306 static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
   307 {
   308 	return;
   309 }
   310 
   311 
   312 int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info)
   313 {
   314 	SDL_VERSION(&(info->version));
   315 	info->wimpVersion = RISCOS_GetWimpVersion();
   316 	info->taskHandle = RISCOS_GetTaskHandle();
   317 	info->window = this->hidden->window_handle;
   318 
   319 	return 1;
   320 }
   321 /* Toggle full screen mode.
   322    Returns 1 if successful otherwise 0
   323 */
   324 
   325 int RISCOS_ToggleFullScreen(_THIS, int fullscreen)
   326 {
   327     if (fullscreen)
   328     {
   329        return FULLSCREEN_ToggleFromWimp(this);
   330     } else
   331     {
   332        return WIMP_ToggleFromFullScreen(this);
   333     }
   334 
   335    return 0;
   336 }
   337