Atlas - SDL_riscosmodes.c
Home / ext / SDL / src / video / riscos Lines: 1 | Size: 8754 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#ifdef SDL_VIDEO_DRIVER_RISCOS 24 25#include "../SDL_sysvideo.h" 26#include "../../events/SDL_mouse_c.h" 27 28#include "SDL_riscosvideo.h" 29#include "SDL_riscosmodes.h" 30 31#include <kernel.h> 32#include <swis.h> 33 34enum 35{ 36 MODE_FLAG_565 = 1 << 7, 37 38 MODE_FLAG_COLOUR_SPACE = 0xF << 12, 39 40 MODE_FLAG_TBGR = 0, 41 MODE_FLAG_TRGB = 1 << 14, 42 MODE_FLAG_ABGR = 1 << 15, 43 MODE_FLAG_ARGB = MODE_FLAG_TRGB | MODE_FLAG_ABGR 44}; 45 46static const struct 47{ 48 SDL_PixelFormat pixel_format; 49 int modeflags, ncolour, log2bpp; 50} mode_to_pixelformat[] = { 51 // { SDL_PIXELFORMAT_INDEX1LSB, 0, 1, 0 }, 52 // { SDL_PIXELFORMAT_INDEX2LSB, 0, 3, 1 }, 53 // { SDL_PIXELFORMAT_INDEX4LSB, 0, 15, 2 }, 54 // { SDL_PIXELFORMAT_INDEX8, MODE_FLAG_565, 255, 3 }, 55 { SDL_PIXELFORMAT_XBGR1555, MODE_FLAG_TBGR, 65535, 4 }, 56 { SDL_PIXELFORMAT_XRGB1555, MODE_FLAG_TRGB, 65535, 4 }, 57 { SDL_PIXELFORMAT_ABGR1555, MODE_FLAG_ABGR, 65535, 4 }, 58 { SDL_PIXELFORMAT_ARGB1555, MODE_FLAG_ARGB, 65535, 4 }, 59 { SDL_PIXELFORMAT_XBGR4444, MODE_FLAG_TBGR, 4095, 4 }, 60 { SDL_PIXELFORMAT_XRGB4444, MODE_FLAG_TRGB, 4095, 4 }, 61 { SDL_PIXELFORMAT_ABGR4444, MODE_FLAG_ABGR, 4095, 4 }, 62 { SDL_PIXELFORMAT_ARGB4444, MODE_FLAG_ARGB, 4095, 4 }, 63 { SDL_PIXELFORMAT_BGR565, MODE_FLAG_TBGR | MODE_FLAG_565, 65535, 4 }, 64 { SDL_PIXELFORMAT_RGB565, MODE_FLAG_TRGB | MODE_FLAG_565, 65535, 4 }, 65 { SDL_PIXELFORMAT_BGR24, MODE_FLAG_TBGR, 16777215, 6 }, 66 { SDL_PIXELFORMAT_RGB24, MODE_FLAG_TRGB, 16777215, 6 }, 67 { SDL_PIXELFORMAT_XBGR8888, MODE_FLAG_TBGR, -1, 5 }, 68 { SDL_PIXELFORMAT_XRGB8888, MODE_FLAG_TRGB, -1, 5 }, 69 { SDL_PIXELFORMAT_ABGR8888, MODE_FLAG_ABGR, -1, 5 }, 70 { SDL_PIXELFORMAT_ARGB8888, MODE_FLAG_ARGB, -1, 5 } 71}; 72 73static SDL_PixelFormat RISCOS_ModeToPixelFormat(int ncolour, int modeflags, int log2bpp) 74{ 75 int i; 76 77 for (i = 0; i < SDL_arraysize(mode_to_pixelformat); i++) { 78 if (log2bpp == mode_to_pixelformat[i].log2bpp && 79 (ncolour == mode_to_pixelformat[i].ncolour || ncolour == 0) && 80 (modeflags & (MODE_FLAG_565 | MODE_FLAG_COLOUR_SPACE)) == mode_to_pixelformat[i].modeflags) { 81 return mode_to_pixelformat[i].pixel_format; 82 } 83 } 84 85 return SDL_PIXELFORMAT_UNKNOWN; 86} 87 88static size_t measure_mode_block(const int *block) 89{ 90 size_t blockSize = ((block[0] & 0xFF) == 3) ? 7 : 5; 91 while (block[blockSize] != -1) { 92 blockSize += 2; 93 } 94 blockSize++; 95 96 return blockSize * 4; 97} 98 99static bool read_mode_variable(int *block, int var) 100{ 101 _kernel_swi_regs regs; 102 regs.r[0] = (int)block; 103 regs.r[1] = var; 104 _kernel_swi(OS_ReadModeVariable, ®s, ®s); 105 return regs.r[2]; 106} 107 108static bool read_mode_block(int *block, SDL_DisplayMode *mode, bool extended) 109{ 110 int xres, yres, ncolour, modeflags, log2bpp, rate; 111 112 if ((block[0] & 0xFF) == 1) { 113 xres = block[1]; 114 yres = block[2]; 115 log2bpp = block[3]; 116 rate = block[4]; 117 ncolour = (1 << (1 << log2bpp)) - 1; 118 modeflags = MODE_FLAG_TBGR; 119 } else if ((block[0] & 0xFF) == 3) { 120 xres = block[1]; 121 yres = block[2]; 122 ncolour = block[3]; 123 modeflags = block[4]; 124 log2bpp = block[5]; 125 rate = block[6]; 126 } else { 127 return false; 128 } 129 130 if (extended) { 131 xres = read_mode_variable(block, 11) + 1; 132 yres = read_mode_variable(block, 12) + 1; 133 log2bpp = read_mode_variable(block, 9); 134 ncolour = read_mode_variable(block, 3); 135 modeflags = read_mode_variable(block, 0); 136 } 137 138 SDL_zerop(mode); 139 mode->w = xres; 140 mode->h = yres; 141 mode->format = RISCOS_ModeToPixelFormat(ncolour, modeflags, log2bpp); 142 mode->refresh_rate = (float)rate; 143 144 return true; 145} 146 147static void *convert_mode_block(const int *block) 148{ 149 int xres, yres, log2bpp, rate, ncolour = 0, modeflags = 0; 150 size_t pos = 0; 151 int *dst; 152 153 if ((block[0] & 0xFF) == 1) { 154 xres = block[1]; 155 yres = block[2]; 156 log2bpp = block[3]; 157 rate = block[4]; 158 } else if ((block[0] & 0xFF) == 3) { 159 xres = block[1]; 160 yres = block[2]; 161 ncolour = block[3]; 162 modeflags = block[4]; 163 log2bpp = block[5]; 164 rate = block[6]; 165 } else { 166 return NULL; 167 } 168 169 dst = SDL_malloc(40); 170 if (!dst) { 171 return NULL; 172 } 173 174 dst[pos++] = 1; 175 dst[pos++] = xres; 176 dst[pos++] = yres; 177 dst[pos++] = log2bpp; 178 dst[pos++] = rate; 179 if (ncolour != 0) { 180 dst[pos++] = 3; 181 dst[pos++] = ncolour; 182 } 183 if (modeflags != 0) { 184 dst[pos++] = 0; 185 dst[pos++] = modeflags; 186 } 187 dst[pos++] = -1; 188 189 return dst; 190} 191 192static void *copy_memory(const void *src, size_t size, size_t alloc) 193{ 194 void *dst = SDL_malloc(alloc); 195 if (dst) { 196 SDL_memcpy(dst, src, size); 197 } 198 return dst; 199} 200 201bool RISCOS_InitModes(SDL_VideoDevice *_this) 202{ 203 SDL_DisplayMode mode; 204 int *current_mode; 205 _kernel_swi_regs regs; 206 _kernel_oserror *error; 207 size_t size; 208 209 regs.r[0] = 1; 210 error = _kernel_swi(OS_ScreenMode, ®s, ®s); 211 if (error) { 212 return SDL_SetError("Unable to retrieve the current screen mode: %s (%i)", error->errmess, error->errnum); 213 } 214 215 current_mode = (int *)regs.r[1]; 216 if (!read_mode_block(current_mode, &mode, true)) { 217 return SDL_SetError("Unsupported mode block format %d", current_mode[0]); 218 } 219 220 size = measure_mode_block(current_mode); 221 mode.internal = copy_memory(current_mode, size, size); 222 if (!mode.internal) { 223 return false; 224 } 225 226 if (SDL_AddBasicVideoDisplay(&mode) == 0) { 227 return false; 228 } 229 return true; 230} 231 232bool RISCOS_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display) 233{ 234 SDL_DisplayMode mode; 235 _kernel_swi_regs regs; 236 _kernel_oserror *error; 237 void *block, *pos; 238 239 regs.r[0] = 2; 240 regs.r[2] = 0; 241 regs.r[6] = 0; 242 regs.r[7] = 0; 243 error = _kernel_swi(OS_ScreenMode, ®s, ®s); 244 if (error) { 245 return SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum); 246 } 247 248 block = SDL_malloc(-regs.r[7]); 249 if (!block) { 250 return false; 251 } 252 253 regs.r[6] = (int)block; 254 regs.r[7] = -regs.r[7]; 255 error = _kernel_swi(OS_ScreenMode, ®s, ®s); 256 if (error) { 257 SDL_free(block); 258 return SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum); 259 } 260 261 for (pos = block; pos < (void *)regs.r[6]; pos += *((int *)pos)) { 262 if (!read_mode_block(pos + 4, &mode, false)) { 263 continue; 264 } 265 266 if (mode.format == SDL_PIXELFORMAT_UNKNOWN) { 267 continue; 268 } 269 270 mode.internal = convert_mode_block(pos + 4); 271 if (!mode.internal) { 272 SDL_free(block); 273 return false; 274 } 275 276 if (!SDL_AddFullscreenDisplayMode(display, &mode)) { 277 SDL_free(mode.internal); 278 } 279 } 280 281 SDL_free(block); 282 return true; 283} 284 285bool RISCOS_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode) 286{ 287 const char disable_cursor[] = { 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 288 _kernel_swi_regs regs; 289 _kernel_oserror *error; 290 int i; 291 292 regs.r[0] = 0; 293 regs.r[1] = (int)mode->internal; 294 error = _kernel_swi(OS_ScreenMode, ®s, ®s); 295 if (error) { 296 return SDL_SetError("Unable to set the current screen mode: %s (%i)", error->errmess, error->errnum); 297 } 298 299 // Turn the text cursor off 300 for (i = 0; i < SDL_arraysize(disable_cursor); i++) { 301 _kernel_oswrch(disable_cursor[i]); 302 } 303 304 // Update cursor visibility, since it may have been disabled by the mode change. 305 SDL_RedrawCursor(); 306 307 return true; 308} 309 310#endif // SDL_VIDEO_DRIVER_RISCOS 311[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.