riscos: Refactor framebuffer code

main
Cameron Cawley 2021-02-12 23:46:11 +00:00 committed by Sam Lantinga
parent 25c71748ad
commit fe9bb74764
6 changed files with 224 additions and 89 deletions

View File

@ -0,0 +1,51 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
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_riscosdefs_h_
#define SDL_riscosdefs_h_
typedef struct sprite_area {
int size; /* +0 */
int count; /* +4 */
int start; /* +8 */
int end; /* +12 */
} sprite_area;
SDL_COMPILE_TIME_ASSERT(sprite_area, sizeof(sprite_area) == 16);
typedef struct sprite_header {
int next; /* +0 */
char name[12]; /* +4 */
int width; /* +16 */
int height; /* +20 */
int first_bit; /* +24 */
int last_bit; /* +28 */
int image_offset; /* +32 */
int mask_offset; /* +36 */
int mode; /* +40 */
} sprite_header;
SDL_COMPILE_TIME_ASSERT(sprite_header, sizeof(sprite_header) == 44);
#endif /* SDL_riscosdefs_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -25,122 +25,100 @@
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
#include "SDL_riscosframebuffer_c.h" #include "SDL_riscosframebuffer_c.h"
#include "SDL_riscosvideo.h" #include "SDL_riscosvideo.h"
#include "SDL_riscoswindow.h"
#include <kernel.h> #include <kernel.h>
#include <swis.h> #include <swis.h>
#define DUMMY_SURFACE "_SDL_DummySurface" int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
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)
{ {
SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
const char *sprite_name = "display"; const char *sprite_name = "display";
int width, height, size, bytesPerRow;
unsigned int sprite_mode; unsigned int sprite_mode;
_kernel_oserror *error; _kernel_oserror *error;
_kernel_swi_regs regs; _kernel_swi_regs regs;
sprite_area *buffer;
Uint32 pixelformat;
SDL_DisplayMode mode; SDL_DisplayMode mode;
int size;
/* Free the old framebuffer surface */ /* Free the old framebuffer surface */
buffer = (sprite_area *) SDL_SetWindowData(window, DUMMY_SURFACE, NULL); RISCOS_DestroyWindowFramebuffer(_this, window);
SDL_free(buffer);
/* Create a new one */ /* Create a new one */
SDL_GetWindowSize(window, &width, &height);
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &mode); SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &mode);
if ((SDL_ISPIXELFORMAT_PACKED(mode.format) || SDL_ISPIXELFORMAT_ARRAY(mode.format))) { if ((SDL_ISPIXELFORMAT_PACKED(mode.format) || SDL_ISPIXELFORMAT_ARRAY(mode.format))) {
pixelformat = mode.format; *format = mode.format;
sprite_mode = (unsigned int)mode.driverdata; sprite_mode = (unsigned int)mode.driverdata;
} else { } else {
pixelformat = SDL_PIXELFORMAT_BGR888; *format = SDL_PIXELFORMAT_BGR888;
sprite_mode = (1 | (90 << 1) | (90 << 14) | (6 << 27)); sprite_mode = (1 | (90 << 1) | (90 << 14) | (6 << 27));
} }
bytesPerRow = SDL_BYTESPERPIXEL(pixelformat) * width; /* Calculate pitch */
if ((bytesPerRow & 3) != 0) { *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
bytesPerRow += 4 - (bytesPerRow & 3);
}
size = 60 + (bytesPerRow * height);
buffer = SDL_malloc(size); /* Allocate the sprite area */
if (!buffer) { size = sizeof(sprite_area) + sizeof(sprite_header) + ((*pitch) * window->h);
SDL_OutOfMemory(); driverdata->fb_area = SDL_malloc(size);
return -1; if (!driverdata->fb_area) {
return SDL_OutOfMemory();
} }
/* Initialise a sprite area */ driverdata->fb_area->size = size;
driverdata->fb_area->count = 0;
buffer->size = size; driverdata->fb_area->start = 16;
buffer->start = 16; driverdata->fb_area->end = 16;
regs.r[0] = 256+9;
regs.r[1] = (unsigned int)buffer;
error = _kernel_swi(OS_SpriteOp, &regs, &regs);
if (error != NULL) {
SDL_SetError("Unable to initialise sprite area: %s (%i)", error->errmess, error->errnum);
SDL_free(buffer);
return -1;
}
/* Create the actual image */
regs.r[0] = 256+15; regs.r[0] = 256+15;
regs.r[1] = (unsigned int)buffer; regs.r[1] = (int)driverdata->fb_area;
regs.r[2] = (unsigned int)sprite_name; regs.r[2] = (int)sprite_name;
regs.r[3] = 0; regs.r[3] = 0;
regs.r[4] = width; regs.r[4] = window->w;
regs.r[5] = height; regs.r[5] = window->h;
regs.r[6] = sprite_mode; regs.r[6] = sprite_mode;
error = _kernel_swi(OS_SpriteOp, &regs, &regs); error = _kernel_swi(OS_SpriteOp, &regs, &regs);
if (error != NULL) { if (error != NULL) {
SDL_SetError("Unable to create sprite: %s (%i)", error->errmess, error->errnum); SDL_free(driverdata->fb_area);
SDL_free(buffer); return SDL_SetError("Unable to create sprite: %s (%i)", error->errmess, error->errnum);
return -1;
} }
/* Save the info and return! */ driverdata->fb_sprite = (sprite_header *)(((Uint8 *)driverdata->fb_area) + driverdata->fb_area->start);
SDL_SetWindowData(window, DUMMY_SURFACE, buffer); *pixels = ((Uint8 *)driverdata->fb_sprite) + driverdata->fb_sprite->image_offset;
*format = pixelformat;
*pixels = ((Uint8 *)buffer) + 60;
*pitch = bytesPerRow;
return 0; return 0;
} }
int SDL_RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
{ {
SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
_kernel_swi_regs regs; _kernel_swi_regs regs;
sprite_area *buffer; _kernel_oserror *error;
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[0] = 512+52;
regs.r[1] = (unsigned int)buffer; regs.r[1] = (int)driverdata->fb_area;
regs.r[2] = (unsigned int)buffer + buffer->start; regs.r[2] = (int)driverdata->fb_sprite;
regs.r[3] = window->x * 2; regs.r[3] = window->x << 1;
regs.r[4] = window->y * 2; regs.r[4] = window->y << 1;
regs.r[5] = 0x50; regs.r[5] = 0x50;
regs.r[6] = 0; regs.r[6] = 0;
regs.r[7] = 0; regs.r[7] = 0;
_kernel_swi(OS_SpriteOp, &regs, &regs); error = _kernel_swi(OS_SpriteOp, &regs, &regs);
if (error != NULL) {
return SDL_SetError("OS_SpriteOp 52 failed: %s (%i)", error->errmess, error->errnum);
}
return 0; return 0;
} }
void SDL_RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window) void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
{ {
sprite_area *buffer = (sprite_area *) SDL_SetWindowData(window, DUMMY_SURFACE, NULL); SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
SDL_free(buffer);
if (driverdata->fb_area) {
SDL_free(driverdata->fb_area);
driverdata->fb_area = NULL;
}
driverdata->fb_sprite = NULL;
} }
#endif /* SDL_VIDEO_DRIVER_RISCOS */ #endif /* SDL_VIDEO_DRIVER_RISCOS */

View File

@ -24,9 +24,9 @@
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
extern int SDL_RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); extern int 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 int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
extern void SDL_RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window); extern void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
#endif /* SDL_riscosframebuffer_c_h_ */ #endif /* SDL_riscosframebuffer_c_h_ */

View File

@ -37,10 +37,8 @@
* SDL video driver. Renamed to "DUMMY" by Sam Lantinga. * SDL video driver. Renamed to "DUMMY" by Sam Lantinga.
*/ */
#include "SDL_version.h"
#include "SDL_video.h" #include "SDL_video.h"
#include "SDL_mouse.h" #include "SDL_mouse.h"
#include "SDL_syswm.h"
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h" #include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h" #include "../../events/SDL_events_c.h"
@ -48,6 +46,7 @@
#include "SDL_riscosvideo.h" #include "SDL_riscosvideo.h"
#include "SDL_riscosevents_c.h" #include "SDL_riscosevents_c.h"
#include "SDL_riscosframebuffer_c.h" #include "SDL_riscosframebuffer_c.h"
#include "SDL_riscoswindow.h"
#include <kernel.h> #include <kernel.h>
#include <swis.h> #include <swis.h>
@ -58,7 +57,6 @@
static int RISCOS_VideoInit(_THIS); static int RISCOS_VideoInit(_THIS);
static int RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); static int RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
static void RISCOS_VideoQuit(_THIS); static void RISCOS_VideoQuit(_THIS);
SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info);
/* RISC OS driver bootstrap functions */ /* RISC OS driver bootstrap functions */
@ -86,11 +84,13 @@ RISCOS_CreateDevice(int devindex)
device->SetDisplayMode = RISCOS_SetDisplayMode; device->SetDisplayMode = RISCOS_SetDisplayMode;
device->PumpEvents = RISCOS_PumpEvents; device->PumpEvents = RISCOS_PumpEvents;
device->CreateSDLWindow = RISCOS_CreateWindow;
device->DestroyWindow = RISCOS_DestroyWindow;
device->GetWindowWMInfo = RISCOS_GetWindowWMInfo; device->GetWindowWMInfo = RISCOS_GetWindowWMInfo;
device->CreateWindowFramebuffer = SDL_RISCOS_CreateWindowFramebuffer; device->CreateWindowFramebuffer = RISCOS_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = SDL_RISCOS_UpdateWindowFramebuffer; device->UpdateWindowFramebuffer = RISCOS_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = SDL_RISCOS_DestroyWindowFramebuffer; device->DestroyWindowFramebuffer = RISCOS_DestroyWindowFramebuffer;
device->free = RISCOS_DeleteDevice; device->free = RISCOS_DeleteDevice;
@ -234,18 +234,6 @@ 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 */ #endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,76 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
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_version.h"
#include "SDL_syswm.h"
#include "../SDL_sysvideo.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscoswindow.h"
int
RISCOS_CreateWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *driverdata;
driverdata = (SDL_WindowData *) SDL_calloc(1, sizeof(*driverdata));
if (!driverdata) {
return SDL_OutOfMemory();
}
driverdata->window = window;
/* All done! */
window->driverdata = driverdata;
return 0;
}
void
RISCOS_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
if (!driverdata)
return;
SDL_free(driverdata);
window->driverdata = NULL;
}
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: */

View File

@ -0,0 +1,42 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
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_riscoswindow_h_
#define SDL_riscoswindow_h_
#include "SDL_riscosdefs.h"
typedef struct
{
SDL_Window *window;
sprite_area *fb_area;
sprite_header *fb_sprite;
} SDL_WindowData;
extern int RISCOS_CreateWindow(_THIS, SDL_Window * window);
extern void RISCOS_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
#endif /* SDL_riscoswindow_h_ */
/* vi: set ts=4 sw=4 expandtab: */