diff --git a/CMakeLists.txt b/CMakeLists.txt index 807e529a6..294e93c96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2118,6 +2118,13 @@ elseif(RISCOS) set(SOURCE_FILES ${SOURCE_FILES} ${MISC_SOURCES}) set(HAVE_SDL_MISC TRUE) + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_RISCOS 1) + file(GLOB RISCOSVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/riscos/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${RISCOSVIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + endif() + if(SDL_FILESYSTEM) set(SDL_FILESYSTEM_RISCOS 1) file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/riscos/*.c) diff --git a/configure b/configure index 060845a7f..76990784f 100755 --- a/configure +++ b/configure @@ -25794,6 +25794,15 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/misc/riscos/*.c" have_misc=yes + # Set up files for the video library + if test x$enable_video = xyes; then + +$as_echo "#define SDL_VIDEO_DRIVER_RISCOS 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/video/riscos/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} riscos" + fi # Set up files for the filesystem library if test x$enable_filesystem = xyes; then diff --git a/configure.ac b/configure.ac index 3a71a16d5..b61d3f106 100644 --- a/configure.ac +++ b/configure.ac @@ -4277,6 +4277,13 @@ case "$host" in SOURCES="$SOURCES $srcdir/src/misc/riscos/*.c" have_misc=yes + # Set up files for the video library + if test x$enable_video = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_RISCOS, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/video/riscos/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} riscos" + fi # Set up files for the filesystem library if test x$enable_filesystem = xyes; then AC_DEFINE(SDL_FILESYSTEM_RISCOS, 1, [ ]) diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 7fd73e5a7..a0784f603 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -392,6 +392,7 @@ #cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@ #cmakedefine SDL_VIDEO_DRIVER_OS2 @SDL_VIDEO_DRIVER_OS2@ #cmakedefine SDL_VIDEO_DRIVER_QNX @SDL_VIDEO_DRIVER_QNX@ +#cmakedefine SDL_VIDEO_DRIVER_RISCOS @SDL_VIDEO_DRIVER_RISCOS@ #cmakedefine SDL_VIDEO_DRIVER_KMSDRM @SDL_VIDEO_DRIVER_KMSDRM@ #cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC@ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 35f5bd0b4..0bb904c13 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -401,6 +401,7 @@ #undef SDL_VIDEO_DRIVER_VIVANTE_VDK #undef SDL_VIDEO_DRIVER_OS2 #undef SDL_VIDEO_DRIVER_QNX +#undef SDL_VIDEO_DRIVER_RISCOS #undef SDL_VIDEO_RENDER_D3D #undef SDL_VIDEO_RENDER_D3D11 diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index 0936727b1..d25efc14b 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -143,7 +143,8 @@ typedef enum SDL_SYSWM_VIVANTE, SDL_SYSWM_OS2, SDL_SYSWM_HAIKU, - SDL_SYSWM_KMSDRM + SDL_SYSWM_KMSDRM, + SDL_SYSWM_RISCOS } SDL_SYSWM_TYPE; /** diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 844a7a65e..7e22d1b7a 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -437,6 +437,7 @@ extern VideoBootStrap UIKIT_bootstrap; extern VideoBootStrap Android_bootstrap; extern VideoBootStrap PSP_bootstrap; extern VideoBootStrap VITA_bootstrap; +extern VideoBootStrap RISCOS_bootstrap; extern VideoBootStrap RPI_bootstrap; extern VideoBootStrap KMSDRM_bootstrap; extern VideoBootStrap KMSDRM_LEGACY_bootstrap; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 18268a943..fda2c47b3 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -100,6 +100,9 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_KMSDRM &KMSDRM_bootstrap, #endif +#if SDL_VIDEO_DRIVER_RISCOS + &RISCOS_bootstrap, +#endif #if SDL_VIDEO_DRIVER_RPI &RPI_bootstrap, #endif @@ -4152,11 +4155,14 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) #if SDL_VIDEO_DRIVER_OS2 #include "os2/SDL_os2messagebox.h" #endif +#if SDL_VIDEO_DRIVER_RISCOS +#include "riscos/SDL_riscosmessagebox.h" +#endif #if SDL_VIDEO_DRIVER_VITA #include "vita/SDL_vitamessagebox.h" #endif -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 +#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 || SDL_VIDEO_DRIVER_RISCOS static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) { SDL_SysWMinfo info; @@ -4276,6 +4282,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) retval = 0; } #endif +#if SDL_VIDEO_DRIVER_RISCOS + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_RISCOS) && + RISCOS_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } +#endif #if SDL_VIDEO_DRIVER_VITA if (retval == -1 && VITA_ShowMessageBox(messageboxdata, buttonid) == 0) { diff --git a/src/video/riscos/SDL_riscosevents.c b/src/video/riscos/SDL_riscosevents.c new file mode 100644 index 000000000..3c428f51e --- /dev/null +++ b/src/video/riscos/SDL_riscosevents.c @@ -0,0 +1,41 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "../../events/SDL_events_c.h" + +#include "SDL_riscosvideo.h" +#include "SDL_riscosevents_c.h" + +void +RISCOS_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/SDL_riscosevents_c.h b/src/video/riscos/SDL_riscosevents_c.h new file mode 100644 index 000000000..373bb724e --- /dev/null +++ b/src/video/riscos/SDL_riscosevents_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_riscosevents_c_h_ +#define SDL_riscosevents_c_h_ + +#include "../../SDL_internal.h" + +#include "SDL_riscosvideo.h" + +extern void RISCOS_PumpEvents(_THIS); + +#endif /* SDL_riscosevents_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/SDL_riscosframebuffer.c b/src/video/riscos/SDL_riscosframebuffer.c new file mode 100644 index 000000000..7764c4237 --- /dev/null +++ b/src/video/riscos/SDL_riscosframebuffer.c @@ -0,0 +1,148 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "../SDL_sysvideo.h" +#include "SDL_riscosframebuffer_c.h" +#include "SDL_riscosvideo.h" + +#include +#include + +#define DUMMY_SURFACE "_SDL_DummySurface" + +typedef struct { + Uint32 size; + Uint32 count; + Uint32 start; + Uint32 end; +} sprite_area; + +int SDL_RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +{ + const char *sprite_name = "display"; + int width, height, size, bytesPerRow; + unsigned int sprite_mode; + _kernel_oserror *error; + _kernel_swi_regs regs; + sprite_area *buffer; + Uint32 pixelformat; + SDL_DisplayMode mode; + + /* Free the old framebuffer surface */ + buffer = (sprite_area *) SDL_SetWindowData(window, DUMMY_SURFACE, NULL); + SDL_free(buffer); + + /* Create a new one */ + SDL_GetWindowSize(window, &width, &height); + SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &mode); + + if ((SDL_ISPIXELFORMAT_PACKED(mode.format) || SDL_ISPIXELFORMAT_ARRAY(mode.format))) { + pixelformat = mode.format; + sprite_mode = (unsigned int)mode.driverdata; + } else { + pixelformat = SDL_PIXELFORMAT_BGR888; + sprite_mode = (1 | (90 << 1) | (90 << 14) | (6 << 27)); + } + + bytesPerRow = SDL_BYTESPERPIXEL(pixelformat) * width; + if ((bytesPerRow & 3) != 0) { + bytesPerRow += 4 - (bytesPerRow & 3); + } + size = 60 + (bytesPerRow * height); + + buffer = SDL_malloc(size); + if (!buffer) { + SDL_OutOfMemory(); + return -1; + } + + /* Initialise a sprite area */ + + buffer->size = size; + buffer->start = 16; + + regs.r[0] = 256+9; + regs.r[1] = (unsigned int)buffer; + error = _kernel_swi(OS_SpriteOp, ®s, ®s); + if (error != NULL) { + SDL_SetError("Unable to initialise sprite area: %s (%i)", error->errmess, error->errnum); + SDL_free(buffer); + return -1; + } + + regs.r[0] = 256+15; + regs.r[1] = (unsigned int)buffer; + regs.r[2] = (unsigned int)sprite_name; + regs.r[3] = 0; + regs.r[4] = width; + regs.r[5] = height; + regs.r[6] = sprite_mode; + error = _kernel_swi(OS_SpriteOp, ®s, ®s); + if (error != NULL) { + SDL_SetError("Unable to create sprite: %s (%i)", error->errmess, error->errnum); + SDL_free(buffer); + return -1; + } + + /* Save the info and return! */ + SDL_SetWindowData(window, DUMMY_SURFACE, buffer); + *format = pixelformat; + *pixels = ((Uint8 *)buffer) + 60; + *pitch = bytesPerRow; + + return 0; +} + +int SDL_RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + _kernel_swi_regs regs; + sprite_area *buffer; + + buffer = (sprite_area *) SDL_GetWindowData(window, DUMMY_SURFACE); + if (!buffer) { + return SDL_SetError("Couldn't find sprite for window"); + } + + regs.r[0] = 512+52; + regs.r[1] = (unsigned int)buffer; + regs.r[2] = (unsigned int)buffer + buffer->start; + regs.r[3] = window->x * 2; + regs.r[4] = window->y * 2; + regs.r[5] = 0x50; + regs.r[6] = 0; + regs.r[7] = 0; + _kernel_swi(OS_SpriteOp, ®s, ®s); + + return 0; +} + +void SDL_RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + sprite_area *buffer = (sprite_area *) SDL_SetWindowData(window, DUMMY_SURFACE, NULL); + SDL_free(buffer); +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/SDL_riscosframebuffer_c.h b/src/video/riscos/SDL_riscosframebuffer_c.h new file mode 100644 index 000000000..196a33338 --- /dev/null +++ b/src/video/riscos/SDL_riscosframebuffer_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_riscosframebuffer_c_h_ +#define SDL_riscosframebuffer_c_h_ + +#include "../../SDL_internal.h" + +extern int SDL_RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); +extern int SDL_RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); +extern void SDL_RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + +#endif /* SDL_riscosframebuffer_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/SDL_riscosmessagebox.c b/src/video/riscos/SDL_riscosmessagebox.c new file mode 100644 index 000000000..09ff4559e --- /dev/null +++ b/src/video/riscos/SDL_riscosmessagebox.c @@ -0,0 +1,68 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_messagebox.h" +#include "SDL_riscosmessagebox.h" + +#include +#include + +int +RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + _kernel_swi_regs regs; + _kernel_oserror error; + char buttonstring[1024]; + int i; + + error.errnum = 0; + SDL_strlcpy(error.errmess, messageboxdata->message, 252); + regs.r[0] = (unsigned int)&error; + + regs.r[1] = (1 << 8) | (1 << 4); + if (messageboxdata->flags == SDL_MESSAGEBOX_INFORMATION) + regs.r[1] |= (1 << 9); + else if (messageboxdata->flags == SDL_MESSAGEBOX_WARNING) + regs.r[1] |= (2 << 9); + regs.r[2] = (unsigned int)messageboxdata->title; + regs.r[3] = 0; + regs.r[4] = 0; + + SDL_strlcpy(buttonstring, "" , 1024); + for (i = 0; i < messageboxdata->numbuttons; i++) { + SDL_strlcat(buttonstring, messageboxdata->buttons[i].text, 1024); + if (i + 1 < messageboxdata->numbuttons) + SDL_strlcat(buttonstring, ",", 1024); + } + regs.r[5] = (unsigned int)buttonstring; + + _kernel_swi(Wimp_ReportError, ®s, ®s); + + *buttonid = (regs.r[1] == 0) ? -1 : messageboxdata->buttons[regs.r[1] - 3].buttonid; + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/SDL_riscosmessagebox.h b/src/video/riscos/SDL_riscosmessagebox.h new file mode 100644 index 000000000..9895a4887 --- /dev/null +++ b/src/video/riscos/SDL_riscosmessagebox.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +extern int RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/SDL_riscosvideo.c b/src/video/riscos/SDL_riscosvideo.c new file mode 100644 index 000000000..d39a3df2c --- /dev/null +++ b/src/video/riscos/SDL_riscosvideo.c @@ -0,0 +1,251 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_RISCOS + +/* Dummy SDL video driver implementation; this is just enough to make an + * SDL-based application THINK it's got a working video driver, for + * applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it, + * and also for use as a collection of stubs when porting SDL to a new + * platform for which you haven't yet written a valid video driver. + * + * This is also a great way to determine bottlenecks: if you think that SDL + * is a performance problem for a given platform, enable this driver, and + * then see if your application runs faster without video overhead. + * + * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion + * of this was cut-and-pasted from Stephane Peter's work in the AAlib + * SDL video driver. Renamed to "DUMMY" by Sam Lantinga. + */ + +#include "SDL_version.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_syswm.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_riscosvideo.h" +#include "SDL_riscosevents_c.h" +#include "SDL_riscosframebuffer_c.h" + +#include +#include + +#define RISCOSVID_DRIVER_NAME "riscos" + +/* Initialization/Query functions */ +static int RISCOS_VideoInit(_THIS); +static int RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static void RISCOS_VideoQuit(_THIS); +SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); + +/* RISC OS driver bootstrap functions */ + +static void +RISCOS_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_free(device); +} + +static SDL_VideoDevice * +RISCOS_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return (0); + } + + /* Set the function pointers */ + device->VideoInit = RISCOS_VideoInit; + device->VideoQuit = RISCOS_VideoQuit; + device->SetDisplayMode = RISCOS_SetDisplayMode; + device->PumpEvents = RISCOS_PumpEvents; + + device->GetWindowWMInfo = RISCOS_GetWindowWMInfo; + + device->CreateWindowFramebuffer = SDL_RISCOS_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = SDL_RISCOS_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = SDL_RISCOS_DestroyWindowFramebuffer; + + device->free = RISCOS_DeleteDevice; + + return device; +} + +VideoBootStrap RISCOS_bootstrap = { + RISCOSVID_DRIVER_NAME, "SDL RISC OS video driver", + RISCOS_CreateDevice +}; + +enum { + MODE_FLAG_565 = 1 << 7, + + MODE_FLAG_COLOUR_SPACE = 0xF << 12, + + MODE_FLAG_TBGR = 0, + MODE_FLAG_TRGB = 1 << 14, + MODE_FLAG_ABGR = 1 << 15, + MODE_FLAG_ARGB = MODE_FLAG_TRGB | MODE_FLAG_ABGR +}; + +#define MODE_350(type, xdpi, ydpi) \ + (1 | (xdpi << 1) | (ydpi << 14) | (type << 27)) +#define MODE_521(type, xeig, yeig, flags) \ + (0x78000001 | (xeig << 4) | (yeig << 6) | (flags & 0xFF00) | (type << 20)) + +static const struct { + SDL_PixelFormatEnum pixel_format; + int modeflags, ncolour, log2bpp, sprite_type; +} mode_to_pixelformat[] = { + { SDL_PIXELFORMAT_INDEX1LSB, 0, 1, 0, 1 }, + /* { SDL_PIXELFORMAT_INDEX2LSB, 0, 3, 1, 2 }, */ + { SDL_PIXELFORMAT_INDEX4LSB, 0, 15, 2, 3 }, + { SDL_PIXELFORMAT_INDEX8, MODE_FLAG_565, 255, 3, 4 }, + { SDL_PIXELFORMAT_BGR555, MODE_FLAG_TBGR, 65535, 4, 5 }, + { SDL_PIXELFORMAT_RGB555, MODE_FLAG_TRGB, 65535, 4, 5 }, + { SDL_PIXELFORMAT_ABGR1555, MODE_FLAG_ABGR, 65535, 4, 5 }, + { SDL_PIXELFORMAT_ARGB1555, MODE_FLAG_ARGB, 65535, 4, 5 }, + { SDL_PIXELFORMAT_BGR444, MODE_FLAG_TBGR, 4095, 4, 16 }, + { SDL_PIXELFORMAT_RGB444, MODE_FLAG_TRGB, 4095, 4, 16 }, + { SDL_PIXELFORMAT_ABGR4444, MODE_FLAG_ABGR, 4095, 4, 16 }, + { SDL_PIXELFORMAT_ARGB4444, MODE_FLAG_ARGB, 4095, 4, 16 }, + { SDL_PIXELFORMAT_BGR565, MODE_FLAG_TBGR | MODE_FLAG_565, 65535, 4, 10 }, + { SDL_PIXELFORMAT_RGB565, MODE_FLAG_TRGB | MODE_FLAG_565, 65535, 4, 10 }, + { SDL_PIXELFORMAT_BGR24, MODE_FLAG_TBGR, 16777215, 6, 8 }, + { SDL_PIXELFORMAT_RGB24, MODE_FLAG_TRGB, 16777215, 6, 8 }, + { SDL_PIXELFORMAT_BGR888, MODE_FLAG_TBGR, -1, 5, 6 }, + { SDL_PIXELFORMAT_RGB888, MODE_FLAG_TRGB, -1, 5, 6 }, + { SDL_PIXELFORMAT_ABGR8888, MODE_FLAG_ABGR, -1, 5, 6 }, + { SDL_PIXELFORMAT_ARGB8888, MODE_FLAG_ARGB, -1, 5, 6 } +}; + +static int ReadModeVariable(int mode, int variable) { + _kernel_swi_regs regs; + regs.r[0] = mode; + regs.r[1] = variable; + _kernel_swi(OS_ReadModeVariable, ®s, ®s); + return regs.r[2]; +} + +SDL_PixelFormatEnum RISCOS_ModeToPixelFormat(int *mode) { + int i, log2bpp, ncolour, modeflags; + log2bpp = ReadModeVariable((int)mode, 9); + ncolour = ReadModeVariable((int)mode, 3); + modeflags = ReadModeVariable((int)mode, 0); + + for (i = 0; i < SDL_arraysize(mode_to_pixelformat); i++) { + if (log2bpp == mode_to_pixelformat[i].log2bpp && + (ncolour == mode_to_pixelformat[i].ncolour || ncolour == 0) && + (modeflags & (MODE_FLAG_565 | MODE_FLAG_COLOUR_SPACE)) == mode_to_pixelformat[i].modeflags) { + return mode_to_pixelformat[i].pixel_format; + } + } + + return SDL_PIXELFORMAT_UNKNOWN; +} + +static void *copy_mode_block(int *storeBlock) +{ + int *outBlock; + int blockSize = (storeBlock[0] == 2) ? 7 : 5; + while(storeBlock[blockSize] != -1) { + blockSize += 2; + } + blockSize++; + + outBlock = SDL_calloc(sizeof(int), blockSize); + SDL_memcpy(outBlock, storeBlock, sizeof(int) * blockSize); + return outBlock; +} + +int +RISCOS_VideoInit(_THIS) +{ + SDL_DisplayMode mode; + int *current_mode; + _kernel_swi_regs regs; + _kernel_oserror *error; + + regs.r[0] = 1; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error != NULL) { + SDL_SetError("Unable to retrieve the current screen mode: %s (%i)", error->errmess, error->errnum); + return -1; + } + current_mode = (int *)regs.r[1]; + + /* Use a fake 32-bpp desktop mode */ + mode.w = current_mode[1]; + mode.h = current_mode[2]; + if ((current_mode[0] & 0x7F) == 1) { + mode.format = RISCOS_ModeToPixelFormat(current_mode); + mode.refresh_rate = current_mode[4]; + } else if ((current_mode[0] & 0x7F) == 3) { + mode.format = RISCOS_ModeToPixelFormat(current_mode); + mode.refresh_rate = current_mode[6]; + } else { + return -1; + } + mode.driverdata = copy_mode_block(current_mode); + + if (SDL_AddBasicVideoDisplay(&mode) < 0) { + return -1; + } + + SDL_AddDisplayMode(&_this->displays[0], &mode); + + /* We're done! */ + return 0; +} + +static int +RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +void +RISCOS_VideoQuit(_THIS) +{ +} + +SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { + if (info->version.major == SDL_MAJOR_VERSION && + info->version.minor == SDL_MINOR_VERSION) { + info->subsystem = SDL_SYSWM_RISCOS; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d.%d", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/riscos/SDL_riscosvideo.h b/src/video/riscos/SDL_riscosvideo.h new file mode 100644 index 000000000..5bf4b144c --- /dev/null +++ b/src/video/riscos/SDL_riscosvideo.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifndef SDL_riscosvideo_h_ +#define SDL_riscosvideo_h_ + +#include "../SDL_sysvideo.h" + +#endif /* SDL_riscosvideo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */