aboutsummaryrefslogtreecommitdiffstats
path: root/distrib/sdl-1.2.15/src/video/riscos
diff options
context:
space:
mode:
Diffstat (limited to 'distrib/sdl-1.2.15/src/video/riscos')
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S116
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c777
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c549
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h34
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c371
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h44
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c265
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c350
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h39
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c316
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h62
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c330
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c501
13 files changed, 3754 insertions, 0 deletions
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S
new file mode 100644
index 0000000..fae32f8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S
@@ -0,0 +1,116 @@
+;
+; SDL - Simple DirectMedia Layer
+; Copyright (C) 1997-2012 Sam Lantinga
+;
+; This library is free software; you can redistribute it and/or
+; modify it under the terms of the GNU Library General Public
+; License as published by the Free Software Foundation; either
+; version 2 of the License, or (at your option) any later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+; Library General Public License for more details.
+;
+; You should have received a copy of the GNU Library General Public
+; License along with this library; if not, write to the Free
+; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+;
+; Sam Lantinga
+; slouken@libsdl.org
+;
+; Assembler routines for RISC OS display
+;
+
+ AREA |C$$CODE|
+
+ EXPORT |RISCOS_Put32|
+
+; Display 32bpp to 32bpp, 1:1
+;
+; Code provided by Adrain Lees
+;
+; entry a1 -> destination
+; a2 = dest width in pixels
+; a3 = dest line length in bytes
+; a4 = dest height in scanlines
+; arg5 -> source
+; arg6 = byte offset from end of source line to start of next
+
+Arg5 * 10*4
+Arg6 * Arg5+4
+
+RISCOS_Put32 ROUT
+ STMFD sp!,{a2,v1-v6,sl,fp,lr}
+ LDR ip,[sp,#Arg5]
+ MOV lr,a1
+ B ucp64lp
+
+00 ;tail strip of 1-15 pixels
+
+ LDR v1,[ip],#4
+01 SUBS a2,a2,#1
+ STR v1,[lr],#4
+ LDRHI v1,[ip],#4
+ BHI %01
+ B %02
+
+ucp64end ADDS a2,a2,#16
+ BNE %00
+
+02 SUBS a4,a4,#1 ;height--
+ LDRHI v1,[sp,#Arg6]
+ LDRHI a2,[sp] ;reload width
+ BLS %03
+
+ ;move to start of next scanline
+
+ ADD lr,a1,a3
+ ADD a1,a1,a3
+ ADD ip,ip,v1
+
+ucp64lp SUBS a2,a2,#16
+ BLO ucp64end
+
+ PLD [ip,#64]
+
+ LDR v1,[ip],#4
+ LDR v2,[ip],#4
+ LDR v3,[ip],#4
+ LDR v4,[ip],#4
+ LDR v5,[ip],#4
+ LDR v6,[ip],#4
+ LDR sl,[ip],#4
+ LDR fp,[ip],#4
+ STR v1,[lr],#4
+ STR v2,[lr],#4
+ STR v3,[lr],#4
+ STR v4,[lr],#4
+ STR v5,[lr],#4
+ STR v6,[lr],#4
+ STR sl,[lr],#4
+ STR fp,[lr],#4
+
+ PLD [ip,#64]
+
+ LDR v1,[ip],#4
+ LDR v2,[ip],#4
+ LDR v3,[ip],#4
+ LDR v4,[ip],#4
+ LDR v5,[ip],#4
+ LDR v6,[ip],#4
+ LDR sl,[ip],#4
+ LDR fp,[ip],#4
+ STR v1,[lr],#4
+ STR v2,[lr],#4
+ STR v3,[lr],#4
+ STR v4,[lr],#4
+ STR v5,[lr],#4
+ STR v6,[lr],#4
+ STR sl,[lr],#4
+ STR fp,[lr],#4
+
+ B ucp64lp
+
+03 LDMFD sp!,{a2,v1-v6,sl,fp,pc}
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c
new file mode 100644
index 0000000..b8c3cf7
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c
@@ -0,0 +1,777 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements RISC OS full screen display.
+*/
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_riscostask.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+#include "unixlib/os.h"
+#include "unixlib/local.h"
+
+/* Private structures */
+typedef struct tagScreenModeBlock
+{
+ int flags; // mode selector flags, bit 0 = 1, bit 1-7 format specifier, 8-31 reserved
+ int x_pixels;
+ int y_pixels;
+ int pixel_depth; // 2^pixel_depth = bpp,i.e. 0 = 1, 1 = 2, 4 = 16, 5 = 32
+ int frame_rate; // -1 use first match
+ int mode_vars[5]; // array of index, value pairs terminated by -1
+} SCREENMODEBLOCK;
+
+
+/* Helper functions */
+void FULLSCREEN_SetDeviceMode(_THIS);
+int FULLSCREEN_SetMode(int width, int height, int bpp);
+void FULLSCREEN_SetupBanks(_THIS);
+
+/* SDL video device functions for fullscreen mode */
+static int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface);
+void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon);
+extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
+
+/* UpdateRects variants */
+static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects);
+
+/* Local helper functions */
+static int cmpmodes(const void *va, const void *vb);
+static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h);
+void FULLSCREEN_SetWriteBank(int bank);
+void FULLSCREEN_SetDisplayBank(int bank);
+static void FULLSCREEN_DisableEscape();
+static void FULLSCREEN_EnableEscape();
+void FULLSCREEN_BuildModeList(_THIS);
+
+/* Following variable is set up in riskosTask.c */
+extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */
+
+/* Following is used to create a sprite back buffer */
+extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp);
+
+/* Fast assembler copy */
+extern void RISCOS_Put32(void *to, int pixels, int pitch, int rows, void *from, int src_skip_bytes);
+
+SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ _kernel_swi_regs regs;
+ Uint32 Rmask = 0;
+ Uint32 Gmask = 0;
+ Uint32 Bmask = 0;
+ int create_back_buffer = riscos_backbuffer;
+
+ switch(bpp)
+ {
+ case 8:
+ flags |= SDL_HWPALETTE;
+ break;
+
+ case 15:
+ case 16:
+ Bmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Rmask = 0x0000001f;
+ break;
+
+ case 32:
+ Bmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Rmask = 0x000000ff;
+ break;
+
+ default:
+ SDL_SetError("Pixel depth not supported");
+ return NULL;
+ break;
+ }
+
+ if (FULLSCREEN_SetMode(width, height, bpp) == 0)
+ {
+ SDL_SetError("Couldn't set requested mode");
+ return (NULL);
+ }
+
+/* printf("Setting mode %dx%d\n", width, height); */
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
+ RISCOS_RestoreWimpMode();
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->w = width;
+ this->hidden->height = current->h = height;
+
+ regs.r[0] = -1; /* -1 for current screen mode */
+
+ /* Get screen width in bytes */
+ regs.r[1] = 6; // Screen Width in bytes
+ _kernel_swi(OS_ReadModeVariable, &regs, &regs);
+
+ current->pitch = regs.r[2];
+
+ if (flags & SDL_DOUBLEBUF)
+ {
+ regs.r[0] = 2; /* Screen area */
+ _kernel_swi(OS_ReadDynamicArea, &regs, &regs);
+
+ /* Reg 1 has amount of memory currently used for display */
+ regs.r[0] = 2; /* Screen area */
+ regs.r[1] = (current->pitch * height * 2) - regs.r[1];
+ if (_kernel_swi(OS_ChangeDynamicArea, &regs, &regs) != NULL)
+ {
+ /* Can't allocate enough screen memory for double buffer */
+ flags &= ~SDL_DOUBLEBUF;
+ }
+ }
+
+ current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | SDL_PREALLOC;
+
+
+ /* Need to set display banks here for double buffering */
+ if (flags & SDL_DOUBLEBUF)
+ {
+ FULLSCREEN_SetWriteBank(0);
+ FULLSCREEN_SetDisplayBank(1);
+
+ create_back_buffer = 0; /* Don't need a back buffer for a double buffered display */
+ }
+
+ FULLSCREEN_SetupBanks(this);
+
+ if (create_back_buffer)
+ {
+ /* If not double buffered we may need to create a memory
+ ** back buffer to simulate processing on other OSes.
+ ** This is turned on by setting the enviromental variable
+ ** SDL$<name>$BackBuffer >= 1
+ */
+ if (riscos_backbuffer == 3)
+ this->hidden->bank[0] = WIMP_CreateBuffer(width, height, bpp);
+ else
+ this->hidden->bank[0] = SDL_malloc(height * current->pitch);
+ if (this->hidden->bank[0] == 0)
+ {
+ RISCOS_RestoreWimpMode();
+ SDL_SetError("Couldnt allocate memory for back buffer");
+ return (NULL);
+ }
+ /* Surface updated in programs is now a software surface */
+ current->flags &= ~SDL_HWSURFACE;
+ }
+
+ /* Store address of allocated screen bank to be freed later */
+ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
+ if (create_back_buffer)
+ {
+ this->hidden->alloc_bank = this->hidden->bank[0];
+ if (riscos_backbuffer == 3)
+ {
+ this->hidden->bank[0] += 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+ }
+ } else
+ this->hidden->alloc_bank = 0;
+
+ // Clear both banks to black
+ SDL_memset(this->hidden->bank[0], 0, height * current->pitch);
+ SDL_memset(this->hidden->bank[1], 0, height * current->pitch);
+
+ this->hidden->current_bank = 0;
+ current->pixels = this->hidden->bank[0];
+
+ /* Have to set the screen here, so SetDeviceMode will pick it up */
+ this->screen = current;
+
+ /* Reset device functions for the wimp */
+ FULLSCREEN_SetDeviceMode(this);
+
+/* FULLSCREEN_DisableEscape(); */
+
+ /* We're done */
+ return(current);
+}
+
+/* Reset any device functions that have been changed because we have run in WIMP mode */
+void FULLSCREEN_SetDeviceMode(_THIS)
+{
+ /* Update rects is different if we have a backbuffer */
+
+ if (riscos_backbuffer && (this->screen->flags & SDL_DOUBLEBUF) == 0)
+ {
+ switch(riscos_backbuffer)
+ {
+ case 2: /* ARM code full word copy */
+ switch(this->screen->format->BytesPerPixel)
+ {
+ case 1: /* 8bpp modes */
+ this->UpdateRects = FULLSCREEN_UpdateRects8bpp;
+ break;
+ case 2: /* 15/16bpp modes */
+ this->UpdateRects = FULLSCREEN_UpdateRects16bpp;
+ break;
+ case 4: /* 32 bpp modes */
+ this->UpdateRects = FULLSCREEN_UpdateRects32bpp;
+ break;
+
+ default: /* Just default to the memcpy routine */
+ this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy;
+ break;
+ }
+ break;
+
+ case 3: /* Use OS sprite plot routine */
+ this->UpdateRects = FULLSCREEN_UpdateRectsOS;
+ break;
+
+ default: /* Old but safe memcpy */
+ this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy;
+ break;
+ }
+ } else
+ this->UpdateRects = FULLSCREEN_UpdateRects; /* Default do nothing implementation */
+
+ this->SetColors = FULLSCREEN_SetColors;
+
+ this->FlipHWSurface = FULLSCREEN_FlipHWSurface;
+
+ this->SetCaption = FULLSCREEN_SetWMCaption;
+ this->SetIcon = NULL;
+ this->IconifyWindow = NULL;
+
+ this->ShowWMCursor = RISCOS_ShowWMCursor;
+ this->WarpWMCursor = FULLSCREEN_WarpWMCursor;
+
+ this->PumpEvents = FULLSCREEN_PumpEvents;
+}
+
+/* Query for the list of available video modes */
+void FULLSCREEN_BuildModeList(_THIS)
+{
+ _kernel_swi_regs regs;
+ char *enumInfo = NULL;
+ char *enum_ptr;
+ int *blockInfo;
+ int j;
+ int num_modes;
+
+ /* Find out how much space we need */
+ regs.r[0] = 2; /* Reason code */
+ regs.r[2] = 0; /* Number of modes to skip */
+ regs.r[6] = 0; /* pointer to block or 0 for count */
+ regs.r[7] = 0; /* Size of block in bytes */
+ _kernel_swi(OS_ScreenMode, &regs, &regs);
+
+ num_modes = -regs.r[2];
+
+ /* Video memory should be in r[5] */
+ this->info.video_mem = regs.r[5]/1024;
+
+ enumInfo = (unsigned char *)SDL_malloc(-regs.r[7]);
+ if (enumInfo == NULL)
+ {
+ SDL_OutOfMemory();
+ return;
+ }
+ /* Read mode information into block */
+ regs.r[2] = 0;
+ regs.r[6] = (int)enumInfo;
+ regs.r[7] = -regs.r[7];
+ _kernel_swi(OS_ScreenMode, &regs, &regs);
+
+ enum_ptr = enumInfo;
+
+ for (j =0; j < num_modes;j++)
+ {
+ blockInfo = (int *)enum_ptr;
+ if ((blockInfo[1] & 255) == 1) /* We understand this format */
+ {
+ switch(blockInfo[4])
+ {
+ case 3: /* 8 bits per pixel */
+ FULLSCREEN_AddMode(this, 8, blockInfo[2], blockInfo[3]);
+ break;
+ case 4: /* 15 bits per pixel */
+ FULLSCREEN_AddMode(this, 15, blockInfo[2], blockInfo[3]);
+ break;
+ case 5: /* 32 bits per pixel */
+ FULLSCREEN_AddMode(this, 32, blockInfo[2], blockInfo[3]);
+ break;
+ }
+ }
+
+ enum_ptr += blockInfo[0];
+ }
+
+ SDL_free(enumInfo);
+
+ /* Sort the mode lists */
+ for ( j=0; j<NUM_MODELISTS; ++j ) {
+ if ( SDL_nummodes[j] > 0 ) {
+ SDL_qsort(SDL_modelist[j], SDL_nummodes[j], sizeof *SDL_modelist[j], cmpmodes);
+ }
+ }
+}
+
+static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 19;
+
+ FULLSCREEN_SetDisplayBank(this->hidden->current_bank);
+ this->hidden->current_bank ^= 1;
+ FULLSCREEN_SetWriteBank(this->hidden->current_bank);
+ surface->pixels = this->hidden->bank[this->hidden->current_bank];
+
+ /* Wait for Vsync */
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+ return(0);
+}
+
+/* Nothing to do if we are writing direct to hardware */
+static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+}
+
+/* Safe but slower Memory copy from our allocated back buffer */
+static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int row;
+ int xmult = this->screen->format->BytesPerPixel;
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + rects->x * xmult + rects->y * pitch;
+ to = this->hidden->bank[1] + rects->x * xmult + rects->y * pitch;
+ for (row = 0; row < rects->h; row++)
+ {
+ SDL_memcpy(to, from, rects->w * xmult);
+ from += pitch;
+ to += pitch;
+ }
+ rects++;
+ }
+}
+
+/* Use optimized assembler memory copy. Deliberately copies extra columns if
+ necessary to ensure the rectangle is word aligned. */
+static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int width_bytes;
+ int src_skip_bytes;
+
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + rects->x + rects->y * pitch;
+ to = this->hidden->bank[1] + rects->x + rects->y * pitch;
+ width_bytes = rects->w;
+ if ((int)from & 3)
+ {
+ int extra = ((int)from & 3);
+ from -= extra;
+ to -= extra;
+ width_bytes += extra;
+ }
+ if (width_bytes & 3) width_bytes += 4 - (width_bytes & 3);
+ src_skip_bytes = pitch - width_bytes;
+
+ RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes);
+ rects++;
+ }
+}
+
+/* Use optimized assembler memory copy. Deliberately copies extra columns if
+ necessary to ensure the rectangle is word aligned. */
+static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int width_bytes;
+ int src_skip_bytes;
+
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + (rects->x << 1) + rects->y * pitch;
+ to = this->hidden->bank[1] + (rects->x << 1) + rects->y * pitch;
+ width_bytes = (((int)rects->w) << 1);
+ if ((int)from & 3)
+ {
+ from -= 2;
+ to -= 2;
+ width_bytes += 2;
+ }
+ if (width_bytes & 3) width_bytes += 2;
+ src_skip_bytes = pitch - width_bytes;
+
+ RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes);
+ rects++;
+ }
+}
+
+/* Use optimized assembler memory copy. 32 bpp modes are always word aligned */
+static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int width;
+
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + (rects->x << 2) + rects->y * pitch;
+ to = this->hidden->bank[1] + (rects->x << 2) + rects->y * pitch;
+ width = (int)rects->w ;
+
+ RISCOS_Put32(to, width, pitch, (int)rects->h, from, pitch - (width << 2));
+ rects++;
+ }
+}
+
+/* Use operating system sprite plots. Currently this is much slower than the
+ other variants however accelerated sprite plotting can be seen on the horizon
+ so this prepares for it. */
+static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects)
+{
+ _kernel_swi_regs regs;
+ _kernel_oserror *err;
+ int j;
+ int y;
+
+ regs.r[0] = 28 + 512;
+ regs.r[1] = (unsigned int)this->hidden->alloc_bank;
+ regs.r[2] = (unsigned int)this->hidden->alloc_bank+16;
+ regs.r[5] = 0;
+
+ for (j = 0; j < numrects; j++)
+ {
+ y = this->screen->h - rects->y; /* top of clipping region */
+ _kernel_oswrch(24); /* Set graphics clip region */
+ _kernel_oswrch((rects->x << this->hidden->xeig) & 0xFF); /* left */
+ _kernel_oswrch(((rects->x << this->hidden->xeig) >> 8) & 0xFF);
+ _kernel_oswrch(((y - rects->h) << this->hidden->yeig) & 0xFF); /* bottom */
+ _kernel_oswrch((((y - rects->h) << this->hidden->yeig)>> 8) & 0xFF);
+ _kernel_oswrch(((rects->x + rects->w - 1) << this->hidden->xeig) & 0xFF); /* right */
+ _kernel_oswrch((((rects->x + rects->w - 1)<< this->hidden->xeig) >> 8) & 0xFF);
+ _kernel_oswrch(((y-1) << this->hidden->yeig) & 0xFF); /* top */
+ _kernel_oswrch((((y-1) << this->hidden->yeig) >> 8) & 0xFF);
+
+ regs.r[3] = 0;
+ regs.r[4] = 0;
+
+ if ((err = _kernel_swi(OS_SpriteOp, &regs, &regs)) != 0)
+ {
+ printf("OS_SpriteOp failed \n%s\n",err->errmess);
+ }
+
+ rects++;
+
+ /* Reset to full screen clipping */
+ _kernel_oswrch(24); /* Set graphics clip region */
+ _kernel_oswrch(0); /* left */
+ _kernel_oswrch(0);
+ _kernel_oswrch(0); /* bottom */
+ _kernel_oswrch(0);
+ _kernel_oswrch(((this->screen->w-1) << this->hidden->xeig) & 0xFF); /* right */
+ _kernel_oswrch((((this->screen->w-1) << this->hidden->xeig) >> 8) & 0xFF);
+ _kernel_oswrch(((this->screen->h-1) << this->hidden->yeig) & 0xFF); /* top */
+ _kernel_oswrch((((this->screen->h-1) << this->hidden->yeig) >> 8) & 0xFF);
+ }
+}
+
+
+int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ _kernel_swi_regs regs;
+ int palette[256];
+
+ regs.r[0] = -1;
+ regs.r[1] = -1;
+ regs.r[2] = (int)palette;
+ regs.r[3] = 1024;
+ regs.r[4] = 0;
+ _kernel_swi(ColourTrans_ReadPalette, &regs, &regs);
+
+ while(ncolors--)
+ {
+ palette[firstcolor] = ((colors->b) << 24) | ((colors->g) << 16) | ((colors->r) << 8);
+ firstcolor++;
+ colors++;
+ }
+
+ regs.r[0] = -1;
+ regs.r[1] = -1;
+ regs.r[2] = (int)palette;
+ regs.r[3] = 0;
+ regs.r[4] = 0;
+ _kernel_swi(ColourTrans_WritePalette, &regs, &regs);
+
+ return(1);
+}
+
+
+static int cmpmodes(const void *va, const void *vb)
+{
+ SDL_Rect *a = *(SDL_Rect **)va;
+ SDL_Rect *b = *(SDL_Rect **)vb;
+ if(a->w == b->w)
+ return b->h - a->h;
+ else
+ return b->w - a->w;
+}
+
+static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h)
+{
+ SDL_Rect *mode;
+ int i, index;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( bpp < 8 ) { /* Not supported */
+ return(0);
+ }
+ index = ((bpp+7)/8)-1;
+ for ( i=0; i<SDL_nummodes[index]; ++i ) {
+ mode = SDL_modelist[index][i];
+ if ( (mode->w == w) && (mode->h == h) ) {
+ return(0);
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return(0);
+}
+
+void FULLSCREEN_SetWriteBank(int bank)
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 112;
+ regs.r[1] = bank+1;
+ _kernel_swi(OS_Byte, &regs, &regs);
+}
+
+void FULLSCREEN_SetDisplayBank(int bank)
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 113;
+ regs.r[1] = bank+1;
+ _kernel_swi(OS_Byte, &regs, &regs);
+}
+
+
+/** Disable special escape key processing */
+static void FULLSCREEN_DisableEscape()
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 229;
+ regs.r[1] = 1;
+ regs.r[2] = 0;
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+}
+
+/** Enable special escape key processing */
+static void FULLSCREEN_EnableEscape()
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 229;
+ regs.r[1] = 0;
+ regs.r[2] = 0;
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+}
+
+/** Store caption in case this is called before we create a window */
+void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon)
+{
+ SDL_strlcpy(this->hidden->title, title, SDL_arraysize(this->hidden->title));
+}
+
+/* Set screen mode
+*
+* Returns 1 if mode is set ok, otherwise 0
+*/
+
+int FULLSCREEN_SetMode(int width, int height, int bpp)
+{
+ SCREENMODEBLOCK smb;
+ _kernel_swi_regs regs;
+
+ smb.flags = 1;
+ smb.x_pixels = width;
+ smb.y_pixels = height;
+ smb.mode_vars[0] = -1;
+
+ switch(bpp)
+ {
+ case 8:
+ smb.pixel_depth = 3;
+ /* Note: Need to set ModeFlags to 128 and NColour variables to 255 get full 8 bit palette */
+ smb.mode_vars[0] = 0; smb.mode_vars[1] = 128; /* Mode flags */
+ smb.mode_vars[2] = 3; smb.mode_vars[3] = 255; /* NColour (number of colours -1) */
+ smb.mode_vars[4] = -1; /* End of list */
+ break;
+
+ case 15:
+ case 16:
+ smb.pixel_depth = 4;
+ break;
+
+ case 32:
+ smb.pixel_depth = 5;
+ break;
+
+ default:
+ SDL_SetError("Pixel depth not supported");
+ return 0;
+ break;
+ }
+
+ smb.frame_rate = -1;
+
+ regs.r[0] = 0;
+ regs.r[1] = (int)&smb;
+
+ if (_kernel_swi(OS_ScreenMode, &regs, &regs) != 0)
+ {
+ SDL_SetError("Couldn't set requested mode");
+ return 0;
+ }
+
+ /* Turn cursor off*/
+ _kernel_oswrch(23);_kernel_oswrch(1);_kernel_oswrch(0);
+ _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
+ _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
+ _kernel_oswrch(0);_kernel_oswrch(0);
+
+ return 1;
+}
+
+/* Get Start addresses for the screen banks */
+void FULLSCREEN_SetupBanks(_THIS)
+{
+ _kernel_swi_regs regs;
+ int block[5];
+ block[0] = 148; /* Write screen start */
+ block[1] = 149; /* Display screen start */
+ block[2] = 4; /* X eig factor */
+ block[3] = 5; /* Y eig factor */
+ block[4] = -1; /* End of list of variables to request */
+
+ regs.r[0] = (int)block;
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+
+ this->hidden->bank[0] = (void *)block[0];
+ this->hidden->bank[1] = (void *)block[1];
+ this->hidden->xeig = block[2];
+ this->hidden->yeig = block[3];
+}
+
+/* Toggle to full screen mode from the WIMP */
+
+int FULLSCREEN_ToggleFromWimp(_THIS)
+{
+ int width = this->screen->w;
+ int height = this->screen->h;
+ int bpp = this->screen->format->BitsPerPixel;
+
+ RISCOS_StoreWimpMode();
+ if (FULLSCREEN_SetMode(width, height, bpp))
+ {
+ char *buffer = this->hidden->alloc_bank; /* This is start of sprite data */
+ /* Support back buffer mode only */
+ if (riscos_backbuffer == 0) riscos_backbuffer = 1;
+
+ FULLSCREEN_SetupBanks(this);
+
+ this->hidden->bank[0] = buffer + 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+
+ this->hidden->current_bank = 0;
+ this->screen->pixels = this->hidden->bank[0];
+
+ /* Copy back buffer to screen memory */
+ SDL_memcpy(this->hidden->bank[1], this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel);
+
+ FULLSCREEN_SetDeviceMode(this);
+ return 1;
+ } else
+ RISCOS_RestoreWimpMode();
+
+ return 0;
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c
new file mode 100644
index 0000000..5487507
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c
@@ -0,0 +1,549 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements keyboard setup, event pump and keyboard and mouse polling
+*/
+
+
+#include "SDL.h"
+#include "../../timer/SDL_timer_c.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+
+#include "memory.h"
+#include "stdlib.h"
+#include "ctype.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+/* The translation table from a RISC OS internal key numbers to a SDL keysym */
+static SDLKey RO_keymap[SDLK_LAST];
+
+/* RISC OS Key codes */
+#define ROKEY_SHIFT 0
+#define ROKEY_CTRL 1
+#define ROKEY_ALT 2
+/* Left shift is first key we will check for */
+#define ROKEY_LEFT_SHIFT 3
+
+/* Need to ignore mouse buttons as they are processed separately */
+#define ROKEY_LEFT_MOUSE 9
+#define ROKEY_CENTRE_MOUSE 10
+#define ROKEY_RIGHT_MOUSE 11
+
+/* No key has been pressed return value*/
+#define ROKEY_NONE 255
+
+/* Id of last key in keyboard */
+#define ROKEY_LAST_KEY 124
+
+/* Size of array for all keys */
+#define ROKEYBD_ARRAYSIZE 125
+
+static char RO_pressed[ROKEYBD_ARRAYSIZE];
+
+static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed);
+
+void RISCOS_PollMouse(_THIS);
+void RISCOS_PollKeyboard();
+
+void RISCOS_PollMouseHelper(_THIS, int fullscreen);
+
+#if SDL_THREADS_DISABLED
+extern void DRenderer_FillBuffers();
+
+/* Timer running function */
+extern void RISCOS_CheckTimer();
+
+#endif
+
+void FULLSCREEN_PumpEvents(_THIS)
+{
+ /* Current implementation requires keyboard and mouse polling */
+ RISCOS_PollKeyboard();
+ RISCOS_PollMouse(this);
+#if SDL_THREADS_DISABLED
+// DRenderer_FillBuffers();
+ if (SDL_timer_running) RISCOS_CheckTimer();
+#endif
+}
+
+
+void RISCOS_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Map the VK keysyms */
+ for ( i=0; i<SDL_arraysize(RO_keymap); ++i )
+ RO_keymap[i] = SDLK_UNKNOWN;
+
+ RO_keymap[3] = SDLK_LSHIFT;
+ RO_keymap[4] = SDLK_LCTRL;
+ RO_keymap[5] = SDLK_LALT;
+ RO_keymap[6] = SDLK_RSHIFT;
+ RO_keymap[7] = SDLK_RCTRL;
+ RO_keymap[8] = SDLK_RALT;
+ RO_keymap[16] = SDLK_q;
+ RO_keymap[17] = SDLK_3;
+ RO_keymap[18] = SDLK_4;
+ RO_keymap[19] = SDLK_5;
+ RO_keymap[20] = SDLK_F4;
+ RO_keymap[21] = SDLK_8;
+ RO_keymap[22] = SDLK_F7;
+ RO_keymap[23] = SDLK_MINUS,
+ RO_keymap[25] = SDLK_LEFT;
+ RO_keymap[26] = SDLK_KP6;
+ RO_keymap[27] = SDLK_KP7;
+ RO_keymap[28] = SDLK_F11;
+ RO_keymap[29] = SDLK_F12;
+ RO_keymap[30] = SDLK_F10;
+ RO_keymap[31] = SDLK_SCROLLOCK;
+ RO_keymap[32] = SDLK_PRINT;
+ RO_keymap[33] = SDLK_w;
+ RO_keymap[34] = SDLK_e;
+ RO_keymap[35] = SDLK_t;
+ RO_keymap[36] = SDLK_7;
+ RO_keymap[37] = SDLK_i;
+ RO_keymap[38] = SDLK_9;
+ RO_keymap[39] = SDLK_0;
+ RO_keymap[41] = SDLK_DOWN;
+ RO_keymap[42] = SDLK_KP8;
+ RO_keymap[43] = SDLK_KP9;
+ RO_keymap[44] = SDLK_BREAK;
+ RO_keymap[45] = SDLK_BACKQUOTE;
+/* RO_keymap[46] = SDLK_currency; TODO: Figure out if this has a value */
+ RO_keymap[47] = SDLK_BACKSPACE;
+ RO_keymap[48] = SDLK_1;
+ RO_keymap[49] = SDLK_2;
+ RO_keymap[50] = SDLK_d;
+ RO_keymap[51] = SDLK_r;
+ RO_keymap[52] = SDLK_6;
+ RO_keymap[53] = SDLK_u;
+ RO_keymap[54] = SDLK_o;
+ RO_keymap[55] = SDLK_p;
+ RO_keymap[56] = SDLK_LEFTBRACKET;
+ RO_keymap[57] = SDLK_UP;
+ RO_keymap[58] = SDLK_KP_PLUS;
+ RO_keymap[59] = SDLK_KP_MINUS;
+ RO_keymap[60] = SDLK_KP_ENTER;
+ RO_keymap[61] = SDLK_INSERT;
+ RO_keymap[62] = SDLK_HOME;
+ RO_keymap[63] = SDLK_PAGEUP;
+ RO_keymap[64] = SDLK_CAPSLOCK;
+ RO_keymap[65] = SDLK_a;
+ RO_keymap[66] = SDLK_x;
+ RO_keymap[67] = SDLK_f;
+ RO_keymap[68] = SDLK_y;
+ RO_keymap[69] = SDLK_j;
+ RO_keymap[70] = SDLK_k;
+ RO_keymap[72] = SDLK_SEMICOLON;
+ RO_keymap[73] = SDLK_RETURN;
+ RO_keymap[74] = SDLK_KP_DIVIDE;
+ RO_keymap[76] = SDLK_KP_PERIOD;
+ RO_keymap[77] = SDLK_NUMLOCK;
+ RO_keymap[78] = SDLK_PAGEDOWN;
+ RO_keymap[79] = SDLK_QUOTE;
+ RO_keymap[81] = SDLK_s;
+ RO_keymap[82] = SDLK_c;
+ RO_keymap[83] = SDLK_g;
+ RO_keymap[84] = SDLK_h;
+ RO_keymap[85] = SDLK_n;
+ RO_keymap[86] = SDLK_l;
+ RO_keymap[87] = SDLK_SEMICOLON;
+ RO_keymap[88] = SDLK_RIGHTBRACKET;
+ RO_keymap[89] = SDLK_DELETE;
+ RO_keymap[90] = SDLK_KP_MINUS;
+ RO_keymap[91] = SDLK_KP_MULTIPLY;
+ RO_keymap[93] = SDLK_EQUALS;
+ RO_keymap[94] = SDLK_BACKSLASH;
+ RO_keymap[96] = SDLK_TAB;
+ RO_keymap[97] = SDLK_z;
+ RO_keymap[98] = SDLK_SPACE;
+ RO_keymap[99] = SDLK_v;
+ RO_keymap[100] = SDLK_b;
+ RO_keymap[101] = SDLK_m;
+ RO_keymap[102] = SDLK_COMMA;
+ RO_keymap[103] = SDLK_PERIOD;
+ RO_keymap[104] = SDLK_SLASH;
+ RO_keymap[105] = SDLK_END;
+ RO_keymap[106] = SDLK_KP0;
+ RO_keymap[107] = SDLK_KP1;
+ RO_keymap[108] = SDLK_KP3;
+ RO_keymap[112] = SDLK_ESCAPE;
+ RO_keymap[113] = SDLK_F1;
+ RO_keymap[114] = SDLK_F2;
+ RO_keymap[115] = SDLK_F3;
+ RO_keymap[116] = SDLK_F5;
+ RO_keymap[117] = SDLK_F6;
+ RO_keymap[118] = SDLK_F8;
+ RO_keymap[119] = SDLK_F9;
+ RO_keymap[120] = SDLK_HASH;
+ RO_keymap[121] = SDLK_RIGHT;
+ RO_keymap[122] = SDLK_KP4;
+ RO_keymap[123] = SDLK_KP5;
+ RO_keymap[124] = SDLK_KP2;
+
+ SDL_memset(RO_pressed, 0, ROKEYBD_ARRAYSIZE);
+}
+
+
+/* Variable for mouse relative processing */
+int mouse_relative = 0;
+
+/* Check to see if we need to enter or leave mouse relative mode */
+
+void RISCOS_CheckMouseMode(_THIS)
+{
+ /* If the mouse is hidden and input is grabbed, we use relative mode */
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
+ (this->input_grab != SDL_GRAB_OFF) ) {
+ mouse_relative = 1;
+ } else {
+ mouse_relative = 0;
+ }
+}
+
+
+void RISCOS_PollMouse(_THIS)
+{
+ RISCOS_PollMouseHelper(this, 1);
+}
+
+extern int mouseInWindow;
+
+void WIMP_PollMouse(_THIS)
+{
+ /* Only poll when mouse is over the window */
+ if (!mouseInWindow) return;
+
+ RISCOS_PollMouseHelper(this, 0);
+}
+
+/* Static variables so only changes are reported */
+static Sint16 last_x = -1, last_y = -1;
+static int last_buttons = 0;
+
+/* Share routine between WIMP and FULLSCREEN for polling mouse and
+ passing on events */
+void RISCOS_PollMouseHelper(_THIS, int fullscreen)
+{
+ _kernel_swi_regs regs;
+ static int starting = 1;
+
+ if (_kernel_swi(OS_Mouse, &regs, &regs) == NULL)
+ {
+ Sint16 new_x = regs.r[0]; /* Initialy get as OS units */
+ Sint16 new_y = regs.r[1];
+
+ /* Discard mouse events until they let go of the mouse after starting */
+ if (starting && regs.r[2] != 0)
+ return;
+ else
+ starting = 0;
+
+ if (new_x != last_x || new_y != last_y || last_buttons != regs.r[2])
+ {
+ /* Something changed so generate appropriate events */
+ int topLeftX, topLeftY; /* Top left OS units */
+ int x, y; /* Mouse position in SDL pixels */
+
+ if (fullscreen)
+ {
+ topLeftX = 0;
+ topLeftY = (this->hidden->height << this->hidden->yeig) - 1;
+ } else
+ {
+ int window_state[9];
+
+ /* Get current window state */
+ window_state[0] = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ topLeftX = window_state[1];
+ topLeftY = window_state[4];
+ }
+
+ /* Convert co-ordinates to workspace */
+ x = new_x - topLeftX;
+ y = topLeftY - new_y; /* Y goes from top of window/screen */
+
+ /* Convert OS units to pixels */
+ x >>= this->hidden->xeig;
+ y >>= this->hidden->yeig;
+
+ if (last_x != new_x || last_y != new_y)
+ {
+ if (mouse_relative)
+ {
+ int centre_x = SDL_VideoSurface->w/2;
+ int centre_y = SDL_VideoSurface->h/2;
+
+ if (centre_x != x || centre_y != y)
+ {
+ if (SDL_VideoSurface) SDL_PrivateMouseMotion(0,1,x - centre_x, y - centre_y);
+ last_x = topLeftX + (centre_x << this->hidden->xeig);
+ last_y = topLeftY - (centre_y << this->hidden->yeig);
+
+ /* Re-centre the mouse pointer, so we still get relative
+ movement when the mouse is at the edge of the window
+ or screen.
+ */
+ {
+ unsigned char block[5];
+
+ block[0] = 3; /* OSWORD move pointer sub-reason code */
+ block[1] = last_x & 0xFF;
+ block[2] = (last_x >> 8) & 0xFF;
+ block[3] = last_y & 0xFF;
+ block[4] = (last_y >> 8) & 0xFF;
+
+ regs.r[0] = 21; /* OSWORD pointer stuff code */
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_Word, &regs, &regs);
+ }
+ }
+ } else
+ {
+ last_x = new_x;
+ last_y = new_y;
+ SDL_PrivateMouseMotion(0,0,x,y);
+ }
+ }
+
+ if (last_buttons != regs.r[2])
+ {
+ int changed = last_buttons ^ regs.r[2];
+ last_buttons = regs.r[2];
+ if (changed & 4) SDL_PrivateMouseButton((last_buttons & 4) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
+ if (changed & 2) SDL_PrivateMouseButton((last_buttons & 2) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
+ if (changed & 1) SDL_PrivateMouseButton((last_buttons & 1) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
+ }
+ }
+ }
+}
+
+void RISCOS_PollKeyboard()
+{
+ int which_key = ROKEY_LEFT_SHIFT;
+ int j;
+ int min_key, max_key;
+ SDL_keysym key;
+
+ /* Scan the keyboard to see what is pressed */
+ while (which_key <= ROKEY_LAST_KEY)
+ {
+ which_key = (_kernel_osbyte(121, which_key, 0) & 0xFF);
+ if (which_key != ROKEY_NONE)
+ {
+ switch(which_key)
+ {
+ /* Skip over mouse keys */
+ case ROKEY_LEFT_MOUSE:
+ case ROKEY_CENTRE_MOUSE:
+ case ROKEY_RIGHT_MOUSE:
+ which_key = ROKEY_RIGHT_MOUSE;
+ break;
+
+ /* Ignore keys that cause 2 internal number to be generated */
+ case 71: case 24: case 87: case 40:
+ break;
+
+ /* Ignore break as it can be latched on */
+ case 44:
+ break;
+
+ default:
+ RO_pressed[which_key] += 2;
+ break;
+ }
+ which_key++;
+ }
+ }
+
+ /* Generate key released messages */
+ min_key = ROKEY_LAST_KEY+1;
+ max_key = ROKEY_LEFT_SHIFT;
+
+ for (j = ROKEY_LEFT_SHIFT; j <= ROKEY_LAST_KEY; j++)
+ {
+ if (RO_pressed[j])
+ {
+ if (RO_pressed[j] == 1)
+ {
+ RO_pressed[j] = 0;
+ SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(j,&key,0));
+ } else
+ {
+ if (j < min_key) min_key = j;
+ if (j > max_key) max_key = j;
+ }
+ }
+ }
+
+ /* Generate key pressed messages */
+ for (j = min_key; j <= max_key; j++)
+ {
+ if (RO_pressed[j])
+ {
+ if (RO_pressed[j] == 2)
+ {
+ SDL_PrivateKeyboard(SDL_PRESSED,TranslateKey(j,&key,1));
+ }
+ RO_pressed[j] = 1;
+ }
+ }
+}
+
+static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed)
+{
+ /* Set the keysym information */
+ keysym->scancode = (unsigned char) intkey;
+ keysym->sym = RO_keymap[intkey];
+ keysym->mod = KMOD_NONE;
+ keysym->unicode = 0;
+ if ( pressed && SDL_TranslateUNICODE )
+ {
+ int state;
+ int ch;
+
+ state = (_kernel_osbyte(202, 0, 255) & 0xFF);
+
+ /*TODO: Take into account other keyboard layouts */
+
+ ch = keysym->sym; /* This should handle most unshifted keys */
+
+ if (intkey < 9 || ch == SDLK_UNKNOWN)
+ {
+ ch = 0;
+
+ } else if (state & 64) /* Control on */
+ {
+ ch = ch & 31;
+
+ } else
+ {
+ int topOfKey = 0;
+ if (state & 8) /* Shift on */
+ {
+ topOfKey = 1;
+ }
+
+ if ((state & 16) == 0) /* Caps lock is on */
+ {
+ if (ch >= SDLK_a && ch <= SDLK_z)
+ {
+ if ((state & 128) == 0) /* Shift Enable off */
+ {
+ /* All letter become upper case */
+ topOfKey = 1;
+ } else
+ {
+ /* Shift+Letters gives lower case */
+ topOfKey = 1 - topOfKey;
+ }
+ }
+ }
+
+ if (topOfKey)
+ {
+ /* Key produced with shift held down */
+
+ /* Letters just give upper case version */
+ if (ch >= SDLK_a && ch <= SDLK_z) ch = toupper(ch);
+ else
+ {
+ switch(ch)
+ {
+ case SDLK_HASH: ch = '~'; break;
+ case SDLK_QUOTE: ch = '@'; break;
+ case SDLK_COMMA: ch = '<'; break;
+ case SDLK_MINUS: ch = '_'; break;
+ case SDLK_PERIOD: ch = '>'; break;
+ case SDLK_SLASH: ch = '?'; break;
+
+ case SDLK_0: ch = ')'; break;
+ case SDLK_1: ch = '!'; break;
+ case SDLK_2: ch = '"'; break;
+ case SDLK_3: ch = '£'; break;
+ case SDLK_4: ch = '$'; break;
+ case SDLK_5: ch = '%'; break;
+ case SDLK_6: ch = '^'; break;
+ case SDLK_7: ch = '&'; break;
+ case SDLK_8: ch = '*'; break;
+ case SDLK_9: ch = '('; break;
+
+ case SDLK_SEMICOLON: ch = ':'; break;
+ case SDLK_EQUALS: ch = '+'; break;
+ case SDLK_LEFTBRACKET: ch = '{'; break;
+ case SDLK_BACKSLASH: ch = '|'; break;
+ case SDLK_RIGHTBRACKET: ch = '}'; break;
+ case SDLK_BACKQUOTE: ch = '¬'; break;
+
+ default:
+ ch = 0; /* Map to zero character if we don't understand it */
+ break;
+ }
+ }
+
+ } else if (ch > 126)
+ {
+ /* SDL key code < 126 map directly onto their Unicode equivalents */
+ /* Keypad 0 to 9 maps to numeric equivalent */
+ if (ch >= SDLK_KP0 && ch <= SDLK_KP9) ch = ch - SDLK_KP0 + '0';
+ else
+ {
+ /* Following switch maps other keys that produce an Ascii value */
+ switch(ch)
+ {
+ case SDLK_KP_PERIOD: ch = '.'; break;
+ case SDLK_KP_DIVIDE: ch = '/'; break;
+ case SDLK_KP_MULTIPLY: ch = '*'; break;
+ case SDLK_KP_MINUS: ch = '-'; break;
+ case SDLK_KP_PLUS: ch = '+'; break;
+ case SDLK_KP_EQUALS: ch = '='; break;
+
+ default:
+ /* If we don't know what it is set the Unicode to 0 */
+ ch = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ keysym->unicode = ch;
+ }
+ return(keysym);
+}
+
+/* end of SDL_riscosevents.c ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h
new file mode 100644
index 0000000..189b3c0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_riscosvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void RISCOS_InitOSKeymap(_THIS);
+extern void FULLSCREEN_PumpEvents(_THIS);
+extern void WIMP_PumpEvents(_THIS);
+
+/* end of SDL_nullevents_c.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c
new file mode 100644
index 0000000..b4a0bff
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c
@@ -0,0 +1,371 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements mouse cursor shape definitions and positioning
+*/
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+static WMcursor *current_cursor = NULL;
+static WMcursor *defined_cursor = NULL;
+
+extern int mouseInWindow;
+
+/* Area to save cursor palette colours changed by SDL.
+ Actual values will be read before we change to the SDL cursor */
+static Uint8 wimp_cursor_palette[2][5] = {
+ {1, 25, 255, 255, 255},
+ {3, 25, 255, 255, 255}
+};
+
+static int cursor_palette_saved = 0;
+
+void WIMP_SaveCursorPalette();
+void WIMP_RestoreWimpCursor();
+void WIMP_SetSDLCursorPalette();
+
+
+void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ SDL_free(cursor->data);
+ SDL_free(cursor);
+}
+
+WMcursor *RISCOS_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor *cursor;
+ Uint8 *cursor_data;
+ Uint8 *ptr;
+ int i,j,k;
+ int data_byte, mask_byte;
+
+ /* Check to make sure the cursor size is okay */
+ if ( (w > 32) || (h > 32) ) {
+ SDL_SetError("Only with width and height <= 32 pixels are allowed");
+ return(NULL);
+ }
+
+ /* Allocate the cursor */
+ cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
+ if ( cursor == NULL ) {
+ SDL_SetError("Out of memory");
+ return(NULL);
+ }
+
+ /* Note: SDL says width must be a multiple of 8 */
+ cursor_data = SDL_malloc(w/4 * h);
+ if (cursor_data == NULL)
+ {
+ SDL_free(cursor);
+ SDL_SetError("Out of memory");
+ return(NULL);
+ }
+
+ cursor->w = w;
+ cursor->h = h;
+ cursor->hot_x = hot_x;
+ cursor->hot_y = hot_y;
+ cursor->data = cursor_data;
+
+
+/* Data / Mask Resulting pixel on screen
+ 0 / 1 White
+ 1 / 1 Black
+ 0 / 0 Transparent
+ 1 / 0 Inverted color if possible, black if not.
+*/
+ ptr = cursor_data;
+
+ for ( i=0; i<h; ++i )
+ {
+ for (j = 0; j < w/8; ++j)
+ {
+ data_byte = *data;
+ mask_byte = *mask;
+ *ptr++ = 0; /* Sets whole byte transparent */
+ *ptr = 0;
+ for (k = 0; k < 8; k++)
+ {
+ (*ptr) <<= 2;
+ if (data_byte & 1) *ptr |= 3; /* Black or inverted */
+ else if(mask_byte & 1) *ptr |= 1; /* White */
+ if ((k&3) == 3) ptr--;
+ data_byte >>= 1;
+ mask_byte >>= 1;
+ }
+
+ ptr+=3;
+ data++;
+ mask++;
+ }
+ }
+
+ return(cursor);
+}
+
+int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ current_cursor = cursor;
+
+ if (cursor == NULL)
+ {
+ _kernel_osbyte(106,0,0);
+ defined_cursor = NULL;
+ } else
+ {
+ WMcursor *old_cursor = defined_cursor;
+
+ if (cursor != defined_cursor)
+ {
+ Uint8 cursor_def[10];
+
+ cursor_def[0] = 0;
+ cursor_def[1] = 2; /* Use shape number 2 */
+ cursor_def[2] = cursor->w/4; /* Width in bytes */
+ cursor_def[3] = cursor->h; /* Height (h) in pixels */
+ cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */
+ cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */
+ cursor_def[6] = ((int)(cursor->data) & 0xFF); /* Least significant byte of pointer to data */
+ cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF; /* ... */
+ cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */
+ cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */
+
+ if (_kernel_osword(21, (int *)cursor_def) != 0)
+ {
+ SDL_SetError("RISCOS couldn't create the cursor to show");
+ return(0);
+ }
+ defined_cursor = cursor;
+ }
+
+ if (old_cursor == NULL)
+ {
+ /* First time or reshow in window, so save/setup palette */
+ if (!cursor_palette_saved)
+ {
+ WIMP_SaveCursorPalette();
+ }
+ WIMP_SetSDLCursorPalette();
+ }
+
+ _kernel_osbyte(106, 2, 0);
+ }
+
+ return(1);
+}
+
+void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ Uint8 move_block[5];
+ int eig_block[3];
+ _kernel_swi_regs regs;
+ int os_x, os_y;
+
+ eig_block[0] = 4; /* X eig factor */
+ eig_block[1] = 5; /* Y eig factor */
+ eig_block[2] = -1; /* End of list of variables to request */
+
+ regs.r[0] = (int)eig_block;
+ regs.r[1] = (int)eig_block;
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+
+ os_x = x << eig_block[0];
+ os_y = y << eig_block[1];
+
+ move_block[0] = 3; /* Move cursor */
+ move_block[1] = os_x & 0xFF;
+ move_block[2] = (os_x >> 8) & 0xFF;
+ move_block[3] = os_y & 0xFF;
+ move_block[4] = (os_y >> 8) & 0xFF;
+
+ _kernel_osword(21, (int *)move_block);
+ SDL_PrivateMouseMotion(0, 0, x, y);
+}
+
+
+/* Reshow cursor when mouse re-enters the window */
+void WIMP_ReshowCursor(_THIS)
+{
+ defined_cursor = NULL;
+ cursor_palette_saved = 0;
+ RISCOS_ShowWMCursor(this, current_cursor);
+}
+
+void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ _kernel_swi_regs regs;
+ int window_state[9];
+ char block[5];
+ int osX, osY;
+
+ window_state[0] = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ osX = (x << this->hidden->xeig) + window_state[1];
+ osY = window_state[4] - (y << this->hidden->yeig);
+
+ block[0] = 3;
+ block[1] = osX & 0xFF;
+ block[2] = (osX >> 8) & 0xFF;
+ block[3] = osY & 0xFF;
+ block[4] = (osY >> 8) & 0xFF;
+
+ regs.r[0] = 21;
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_Word, &regs, &regs);
+ SDL_PrivateMouseMotion(0, 0, x, y);
+}
+
+int WIMP_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor);
+ else current_cursor = cursor;
+
+ return 1;
+}
+
+SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode)
+{
+ /* In fullscreen mode we don't need to do anything */
+ if (mode < SDL_GRAB_FULLSCREEN)
+ {
+ _kernel_swi_regs regs;
+ unsigned char block[9];
+ block[0] = 1; /* Define mouse cursor bounding block */
+
+ if ( mode == SDL_GRAB_OFF )
+ {
+ /* Clip to whole screen */
+
+ int r = (this->hidden->screen_width << this->hidden->xeig) - 1;
+ int t = (this->hidden->screen_height << this->hidden->yeig) - 1;
+
+ block[1] = 0; block[2] = 0; /* Left*/
+ block[3] = 0; block[4] = 0; /* Bottom */
+ block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */
+ block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */
+ } else
+ {
+ /* Clip to window */
+ unsigned char window_state[36];
+
+ *((int *)window_state) = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ block[1] = window_state[4];
+ block[2] = window_state[5];
+ block[3] = window_state[8];
+ block[4] = window_state[9];
+ block[5] = window_state[12];
+ block[6] = window_state[13];
+ block[7] = window_state[16];
+ block[8] = window_state[17];
+
+ }
+
+ regs.r[0] = 21; /* OS word code */
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_Word, &regs, &regs);
+ }
+
+ return mode;
+}
+
+/* Save mouse cursor palette to be restore when we are no longer
+ defining a cursor */
+
+void WIMP_SaveCursorPalette()
+{
+ _kernel_swi_regs regs;
+ int colour;
+
+ for (colour = 0; colour < 2; colour++)
+ {
+ regs.r[0] = (int)wimp_cursor_palette[colour][0];
+ regs.r[1] = 25;
+ /* Read settings with OS_ReadPalette */
+ if (_kernel_swi(0x2f, &regs, &regs) == NULL)
+ {
+ wimp_cursor_palette[colour][2] = (unsigned char)((regs.r[2] >> 8) & 0xFF);
+ wimp_cursor_palette[colour][3] = (unsigned char)((regs.r[2] >> 16) & 0xFF);
+ wimp_cursor_palette[colour][4] = (unsigned char)((regs.r[2] >> 24) & 0xFF);
+ }
+ }
+
+ cursor_palette_saved = 1;
+}
+
+/* Restore the WIMP's cursor when we leave the SDL window */
+void WIMP_RestoreWimpCursor()
+{
+ int colour;
+
+ /* Reset to pointer shape 1 */
+ _kernel_osbyte(106, 1, 0);
+
+ /* Reset pointer colours */
+ if (cursor_palette_saved)
+ {
+ for (colour = 0; colour < 2; colour++)
+ {
+ _kernel_osword(12, (int *)wimp_cursor_palette[colour]);
+ }
+ }
+ cursor_palette_saved = 0;
+}
+
+/* Set palette used for SDL mouse cursors */
+void WIMP_SetSDLCursorPalette()
+{
+ /* First time set up the mouse colours */
+ Uint8 block[5];
+
+ /* Set up colour 1 as white */
+ block[0] = 1; /* Colour to change 1 - 3 */
+ block[1] = 25; /* Set pointer colour */
+ block[2] = 255; /* red component*/
+ block[3] = 255; /* green component */
+ block[4] = 255; /* blue component*/
+ _kernel_osword(12, (int *)block);
+
+ /* Set colour 3 to back */
+ block[0] = 3; /* Colour to change 1 - 3 */
+ block[1] = 25; /* Set pointer colour*/
+ block[2] = 0; /* red component*/
+ block[3] = 0; /* green component */
+ block[4] = 0; /* blue component*/
+ _kernel_osword(12, (int *)block);
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h
new file mode 100644
index 0000000..9019cb4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h
@@ -0,0 +1,44 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_riscosvideo.h"
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int w;
+ int h;
+ int hot_x;
+ int hot_y;
+ Uint8 *data;
+};
+
+/* Functions to be exported */
+void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor);
+WMcursor *RISCOS_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+
+int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor);
+void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+
+int WIMP_ShowWMCursor(_THIS, WMcursor *cursor);
+void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c
new file mode 100644
index 0000000..70b2f91
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c
@@ -0,0 +1,265 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements Sprite plotting code for wimp display.window
+*/
+
+#include "kernel.h"
+#include "swis.h"
+
+#include "SDL_stdinc.h"
+#include "SDL_riscosvideo.h"
+
+extern void WIMP_ReadModeInfo(_THIS);
+
+void WIMP_PaletteChanged(_THIS);
+
+
+/* Create sprite buffer for screen */
+
+unsigned char *WIMP_CreateBuffer(int width, int height, int bpp)
+{
+ int size;
+ char sprite_name[12] = "display";
+ unsigned char *buffer;
+ _kernel_swi_regs regs;
+ int bytesPerPixel;
+ int bytesPerRow;
+ int offsetToSpriteData = 60;
+
+ switch(bpp)
+ {
+ case 32: bytesPerPixel = 4; break;
+ case 16: bytesPerPixel = 2; break;
+ case 8:
+ bytesPerPixel = 1;
+ offsetToSpriteData += 2048; /* Add in size of palette */
+ break;
+ default:
+ return NULL;
+ break;
+ }
+
+ bytesPerRow = bytesPerPixel * width;
+
+ if ((bytesPerRow & 3) != 0)
+ {
+ bytesPerRow += 4 - (bytesPerRow & 3);
+ }
+ size = bytesPerRow * height;
+
+ buffer = SDL_malloc( (size_t) size + offsetToSpriteData );
+ if (!buffer) return NULL;
+
+ /* Initialise a sprite area */
+
+ *(unsigned int *)buffer = size + offsetToSpriteData;
+ *(unsigned int *)(buffer + 8) = 16;
+
+ regs.r[0] = 256+9;
+ regs.r[1] = (unsigned int)buffer;
+ _kernel_swi(OS_SpriteOp, &regs, &regs);
+
+ regs.r[0] = 256+15;
+ regs.r[1] = (unsigned int)buffer;
+ regs.r[2] = (unsigned int)&sprite_name;
+ regs.r[3] = 0; /* Palette flag: 0 = no palette */
+ regs.r[4] = width;
+ regs.r[5] = height;
+ if (bpp == 8)
+ {
+ /* Use old style mode number */
+ regs.r[6] = 28; /* 8bpp 90x90dpi */
+ } else
+ {
+ regs.r[6] = (((bpp == 16) ? 5 : 6) << 27) /* Type 6 = 32bpp sprite, 5 = 16bpp sprite */
+ | (90 << 14) /* Vertical dpi */
+ | (90 << 1) /* Horizontal dpi */
+ | 1; /* Marker to distinguish between mode selectors and sprite modes */
+ }
+ if (_kernel_swi(OS_SpriteOp, &regs, &regs) == NULL)
+ {
+ if (bpp == 8)
+ {
+ /* Modify sprite to take into account 256 colour palette */
+ int *sprite = (int *)(buffer + 16);
+ /* Adjust sprite offsets */
+ sprite[0] += 2048;
+ sprite[8] += 2048;
+ sprite[9] += 2048;
+ /* Adjust sprite area next free pointer */
+ (*(int *)(buffer+12)) += 2048;
+
+ /* Don't need to set up palette as SDL sets up the default
+ 256 colour palette */
+/* {
+ int *pal = sprite + 11;
+ unsigned int j;
+ unsigned int entry;
+ for (j = 0; j < 255; j++)
+ {
+ entry = (j << 24) | (j << 16) | (j << 8);
+ *pal++ = entry;
+ *pal++ = entry;
+ }
+ }
+*/
+ }
+ } else
+ {
+ SDL_free(buffer);
+ buffer = NULL;
+ }
+
+ return buffer;
+}
+
+
+/* Setup translation buffers for the sprite plotting */
+
+void WIMP_SetupPlotInfo(_THIS)
+{
+ _kernel_swi_regs regs;
+ int *sprite = ((int *)this->hidden->bank[1])+4;
+
+ regs.r[0] = (unsigned int)this->hidden->bank[1];
+ regs.r[1] = (unsigned int)sprite;
+ regs.r[2] = -1; /* Current mode */
+ regs.r[3] = -1; /* Current palette */
+ regs.r[4] = 0; /* Get size of buffer */
+ regs.r[5] = 1|2|16; /* R1 - pointer to sprite and can use full palette words */
+ regs.r[6] = 0;
+ regs.r[7] = 0;
+
+ if (this->hidden->pixtrans) SDL_free(this->hidden->pixtrans);
+ this->hidden->pixtrans = 0;
+
+ /* Get the size required for the buffer */
+ _kernel_swi(ColourTrans_GenerateTable, &regs, &regs);
+ if (regs.r[4])
+ {
+ this->hidden->pixtrans = SDL_malloc(regs.r[4]);
+
+ regs.r[4] = (unsigned int)this->hidden->pixtrans;
+ /* Actually read the buffer */
+ _kernel_swi(ColourTrans_GenerateTable, &regs, &regs);
+ }
+}
+
+/* Plot the sprite in the given context */
+void WIMP_PlotSprite(_THIS, int x, int y)
+{
+ _kernel_swi_regs regs;
+ _kernel_oserror *err;
+
+ regs.r[0] = 52 + 512;
+ regs.r[1] = (unsigned int)this->hidden->bank[1];
+ regs.r[2] = (unsigned int)this->hidden->bank[1]+16;
+ regs.r[3] = x;
+ regs.r[4] = y;
+ regs.r[5] = 0|32; /* Overwrite screen and pixtrans contains wide colour entries */
+ regs.r[6] = 0; /* No scale factors i.e. 1:1 */
+ regs.r[7] = (int)this->hidden->pixtrans;
+
+ if ((err = _kernel_swi(OS_SpriteOp, &regs, &regs)) != 0)
+ {
+ int *p = (int *)this->hidden->pixtrans;
+ printf("OS_SpriteOp failed \n%s\n",err->errmess);
+ printf("pixtrans %d\n", (int)this->hidden->pixtrans);
+ printf("%x %x %x\n", p[0], p[1], p[2]);
+ }
+}
+
+
+/* Wimp mode has changes so update colour mapping and pixel sizes
+ of windows and the sprites they plot */
+
+void WIMP_ModeChanged(_THIS)
+{
+ int oldXeig = this->hidden->xeig;
+ int oldYeig = this->hidden->yeig;
+
+ WIMP_ReadModeInfo(this);
+
+ if (oldXeig == this->hidden->xeig && oldYeig == this->hidden->yeig)
+ {
+ /* Only need to update the palette */
+ WIMP_PaletteChanged(this);
+ } else
+ {
+ _kernel_swi_regs regs;
+ int window_state[9];
+ int extent[4];
+ int currWidth, currHeight;
+ int newWidth, newHeight;
+
+ /* Need to resize windows and update the palette */
+ WIMP_SetupPlotInfo(this);
+
+
+ window_state[0] = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ currWidth = window_state[3] - window_state[1];
+ currHeight = window_state[4] - window_state[2];
+
+ newWidth = (currWidth >> oldXeig) << this->hidden->xeig;
+ newHeight = (currHeight >> oldYeig) << this->hidden->yeig;
+ /* Need to avoid extent getting too small for visible part
+ of window */
+ extent[0] = 0;
+ if (currHeight <= newHeight)
+ {
+ extent[1] = -newHeight;
+ } else
+ {
+ extent[1] = -currHeight;
+ }
+ if (currWidth <= newWidth)
+ {
+ extent[2] = newWidth;
+ } else
+ {
+ extent[2] = currWidth;
+ }
+ extent[3] = 0;
+
+ regs.r[0] = this->hidden->window_handle;
+ regs.r[1] = (int)extent;
+ _kernel_swi(Wimp_SetExtent, &regs, &regs);
+
+ /*TODO: May need to set flag to resize window on next open */
+ }
+}
+
+/* Palette has changed so update palettes used for windows sprites */
+
+void WIMP_PaletteChanged(_THIS)
+{
+ WIMP_SetupPlotInfo(this);
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c
new file mode 100644
index 0000000..67dc3e2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c
@@ -0,0 +1,350 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ This file added by Alan Buckley (alan_baa@hotmail.com) to support RISC OS
+ 26 March 2003
+
+ File includes routines for:
+ Setting up as a WIMP Task
+ Reading information about the current desktop
+ Storing information before a switch to full screen
+ Restoring desktop after switching to full screen
+*/
+
+#include "kernel.h"
+#include "swis.h"
+
+#include "SDL_stdinc.h"
+#include "SDL_riscostask.h"
+
+#if !SDL_THREADS_DISABLED
+#include <pthread.h>
+pthread_t main_thread;
+#endif
+
+/* RISC OS variables */
+
+static int task_handle = 0;
+static int wimp_version = 0;
+
+/* RISC OS variables to help compatability with certain programs */
+int riscos_backbuffer = 0; /* Create a back buffer in system memory for full screen mode */
+int riscos_closeaction = 1; /* Close icon action */
+
+static int stored_mode = -1; /* -1 when in desktop, mode number or pointer when full screen */
+
+extern int mouseInWindow; /* Mouse is in WIMP window */
+
+/* Local function */
+
+static int RISCOS_GetTaskName(char *task_name, size_t maxlen);
+
+/* Uncomment next line to copy mode changes/restores to stderr */
+/* #define DUMP_MODE */
+#ifdef DUMP_MODE
+#include "stdio.h"
+static void dump_mode()
+{
+ fprintf(stderr, "mode %d\n", stored_mode);
+ if (stored_mode < -1 || stored_mode >= 256)
+ {
+ int blockSize = 0;
+ int *storeBlock = (int *)stored_mode;
+
+ while(blockSize < 5 || storeBlock[blockSize] != -1)
+ {
+ fprintf(stderr, " %d\n", storeBlock[blockSize++]);
+ }
+ }
+}
+#endif
+
+/******************************************************************
+
+ Initialise as RISC OS Wimp task
+
+*******************************************************************/
+
+int RISCOS_InitTask()
+{
+ char task_name[32];
+ _kernel_swi_regs regs;
+ int messages[4];
+
+ if (RISCOS_GetTaskName(task_name, SDL_arraysize(task_name)) == 0) return 0;
+
+ messages[0] = 9; /* Palette changed */
+ messages[1] = 0x400c1; /* Mode changed */
+ messages[2] = 8; /* Pre quit */
+ messages[2] = 0;
+
+ regs.r[0] = (unsigned int)360; /* Minimum version 3.6 */
+ regs.r[1] = (unsigned int)0x4b534154;
+ regs.r[2] = (unsigned int)task_name;
+ regs.r[3] = (unsigned int)messages;
+
+ if (_kernel_swi(Wimp_Initialise, &regs, &regs) == 0)
+ {
+ wimp_version = regs.r[0];
+ task_handle = regs.r[1];
+ return 1;
+ }
+
+#if !SDL_THREADS_DISABLED
+ main_thread = pthread_self();
+#endif
+
+ return 0;
+}
+
+/*********************************************************************
+
+ Close down application on exit.
+
+**********************************************************************/
+
+void RISCOS_ExitTask()
+{
+ _kernel_swi_regs regs;
+
+ if (stored_mode == -1)
+ {
+ /* Ensure cursor is put back to standard pointer shape if
+ we have been running in a window */
+ _kernel_osbyte(106,1,0);
+ }
+
+ /* Ensure we end up back in the wimp */
+ RISCOS_RestoreWimpMode();
+
+ /* Neatly exit the task */
+ regs.r[0] = task_handle;
+ regs.r[1] = (unsigned int)0x4b534154;
+ _kernel_swi(Wimp_CloseDown, &regs, &regs);
+ task_handle = 0;
+}
+
+/**************************************************************************
+
+ Get the name of the task for the desktop.
+
+ Param: task_name - name of task 32 characters.
+
+ Returns: 1 is successful, otherwise 0
+
+ Notes: Works by getting using OS_GetEnv to get the command line
+ used to run the program and then parsing a name from it
+ as follows.
+
+ 1. Use name after final period if not !RunImage
+ 2. If name is !RunImage then process item before the period
+ in front of !RunImage.
+ 3. If directory name use that
+ 4. if in form <XXX$Dir> use the XXX.
+
+ Finally once this value has been retrieved use it unless
+ there is a variable set up in the form SDL$<name>$TaskName
+ in which case the value of this variable will be used.
+
+ Now also gets other RISC OS configuration varibles
+ SDL$<name>$BackBuffer - set to 1 to use a system memory backbuffer in fullscreen mode
+ so updates wait until a call to SDL_UpdateRects. (default 0)
+ This is required for programmes where they have assumed this is
+ always the case which is contrary to the documentation.
+ SDL$<name>$CloseAction
+ 0 Don't show close icon
+ 1 Show close icon
+
+***************************************************************************/
+
+int RISCOS_GetTaskName(char *task_name, size_t maxlen)
+{
+ _kernel_swi_regs regs;
+
+ task_name[0] = 0;
+
+ /* Figure out a sensible task name */
+ if (_kernel_swi(OS_GetEnv, &regs, &regs) == 0)
+ {
+ char *command_line = (char *)regs.r[0];
+ size_t len = SDL_strlen(command_line)+1;
+ char *buffer = SDL_stack_alloc(char, len);
+ char *env_var;
+ char *p;
+
+ SDL_strlcpy(buffer, command_line, len);
+ p = SDL_strchr(buffer, ' ');
+ if (p) *p = 0;
+ p = SDL_strrchr(buffer, '.');
+ if (p == 0) p = buffer;
+ if (stricmp(p+1,"!RunImage") == 0)
+ {
+ *p = 0;
+ p = SDL_strrchr(buffer, '.');
+ if (p == 0) p = buffer;
+ }
+ if (*p == '.') p++;
+ if (*p == '!') p++; /* Skip "!" at beginning of application directories */
+
+ if (*p == '<')
+ {
+ // Probably in the form <appname$Dir>
+ char *q = SDL_strchr(p, '$');
+ if (q == 0) q = SDL_strchr(p,'>'); /* Use variable name if not */
+ if (q) *q = 0;
+ p++; /* Move over the < */
+ }
+
+ if (*p)
+ {
+ /* Read variables that effect the RISC OS SDL engine for this task */
+ len = SDL_strlen(p) + 18; /* 18 is larger than the biggest variable name */
+ env_var = SDL_stack_alloc(char, len);
+ if (env_var)
+ {
+ char *env_val;
+
+ /* See if a variable of form SDL$<dirname>$TaskName exists */
+
+ SDL_strlcpy(env_var, "SDL$", len);
+ SDL_strlcat(env_var, p, len);
+ SDL_strlcat(env_var, "$TaskName", len);
+
+ env_val = SDL_getenv(env_var);
+ if (env_val) SDL_strlcpy(task_name, env_val, maxlen);
+
+ SDL_strlcpy(env_var, "SDL$", len);
+ SDL_strlcat(env_var, p, len);
+ SDL_strlcat(env_var, "$BackBuffer", len);
+
+ env_val = SDL_getenv(env_var);
+ if (env_val) riscos_backbuffer = atoi(env_val);
+
+ SDL_strlcpy(env_var, "SDL$", len);
+ SDL_strlcat(env_var, p, len);
+ SDL_strlcat(env_var, "$CloseAction", len);
+
+ env_val = SDL_getenv(env_var);
+ if (env_val && SDL_strcmp(env_val,"0") == 0) riscos_closeaction = 0;
+
+ SDL_stack_free(env_var);
+ }
+
+ if (!*task_name) SDL_strlcpy(task_name, p, maxlen);
+ }
+
+ SDL_stack_free(buffer);
+ }
+
+ if (task_name[0] == 0) SDL_strlcpy(task_name, "SDL Task", maxlen);
+
+ return 1;
+}
+
+/*****************************************************************
+
+ Store the current desktop screen mode if we are in the desktop.
+
+******************************************************************/
+
+void RISCOS_StoreWimpMode()
+{
+ _kernel_swi_regs regs;
+
+ /* Don't store if in full screen mode */
+ if (stored_mode != -1) return;
+
+ regs.r[0] = 1;
+ _kernel_swi(OS_ScreenMode, &regs, &regs);
+ if (regs.r[1] >= 0 && regs.r[1] < 256) stored_mode = regs.r[1];
+ else
+ {
+ int blockSize = 0;
+ int *retBlock = (int *)regs.r[1];
+ int *storeBlock;
+ int j;
+
+ while(blockSize < 5 || retBlock[blockSize] != -1) blockSize++;
+ blockSize++;
+ storeBlock = (int *)SDL_malloc(blockSize * sizeof(int));
+ retBlock = (int *)regs.r[1];
+ for ( j = 0; j < blockSize; j++)
+ storeBlock[j] = retBlock[j];
+
+ stored_mode = (int)storeBlock;
+ }
+#if DUMP_MODE
+ fprintf(stderr, "Stored "); dump_mode();
+#endif
+}
+
+/*****************************************************************
+
+ Restore desktop screen mode if we are in full screen mode.
+
+*****************************************************************/
+
+void RISCOS_RestoreWimpMode()
+{
+ _kernel_swi_regs regs;
+
+ /* Only need to restore if we are in full screen mode */
+ if (stored_mode == -1) return;
+
+#if DUMP_MODE
+ fprintf(stderr, "Restored"); dump_mode();
+#endif
+
+ regs.r[0] = stored_mode;
+ _kernel_swi(Wimp_SetMode, &regs, &regs);
+ if (stored_mode < 0 || stored_mode > 256)
+ {
+ SDL_free((int *)stored_mode);
+ }
+ stored_mode = -1;
+
+ /* Flush keyboard buffer to dump the keystrokes we've already polled */
+ regs.r[0] = 21;
+ regs.r[1] = 0; /* Keyboard buffer number */
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+ mouseInWindow = 0;
+
+}
+
+/*********************************************************************
+
+ Get version of Wimp running when task was initialised.
+
+*********************************************************************/
+
+int RISCOS_GetWimpVersion()
+{
+ return wimp_version;
+}
+
+int RISCOS_GetTaskHandle()
+{
+ return task_handle;
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h
new file mode 100644
index 0000000..5744afa
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h
@@ -0,0 +1,39 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ This file added by Alan Buckley (alan_baa@hotmail.com) to support RISC OS
+ 26 March 2003
+*/
+
+/* Task initialisation/Clean up */
+
+extern int RISCOS_InitTask();
+extern void RISCOS_ExitTask();
+extern int RISCOS_GetWimpVersion();
+extern int RISCOS_GetTaskHandle();
+
+
+/* Wimp mode saveing/restoring */
+extern void RISCOS_StoreWimpMode();
+extern void RISCOS_RestoreWimpMode();
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c
new file mode 100644
index 0000000..bae5e37
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c
@@ -0,0 +1,316 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 23 March 2003
+
+ Implements RISC OS display device management.
+ Routines for full screen and wimp modes are split
+ into other source files.
+*/
+
+#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_riscostask.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+#define RISCOSVID_DRIVER_NAME "riscos"
+
+/* Initialization/Query functions */
+static int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static void RISCOS_VideoQuit(_THIS);
+
+static SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+
+int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
+
+int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
+/* Mouse checking */
+void RISCOS_CheckMouseMode(_THIS);
+extern SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode);
+
+/* Fullscreen mode functions */
+extern SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+extern void FULLSCREEN_BuildModeList(_THIS);
+extern void FULLSCREEN_SetDeviceMode(_THIS);
+extern int FULLSCREEN_ToggleFromWimp(_THIS);
+
+/* Wimp mode functions */
+extern SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+extern void WIMP_DeleteWindow(_THIS);
+extern int WIMP_ToggleFromFullScreen(_THIS);
+
+/* Hardware surface functions - common to WIMP and FULLSCREEN */
+static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface);
+static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* RISC OS driver bootstrap functions */
+
+static int RISCOS_Available(void)
+{
+ return(1);
+}
+
+static void RISCOS_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ 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_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = RISCOS_VideoInit;
+ device->VideoQuit = RISCOS_VideoQuit;
+
+ device->ListModes = RISCOS_ListModes;
+ device->SetVideoMode = RISCOS_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->AllocHWSurface = RISCOS_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = RISCOS_LockHWSurface;
+ device->UnlockHWSurface = RISCOS_UnlockHWSurface;
+ device->FreeHWSurface = RISCOS_FreeHWSurface;
+
+ device->FreeWMCursor = RISCOS_FreeWMCursor;
+ device->CreateWMCursor = RISCOS_CreateWMCursor;
+ device->CheckMouseMode = RISCOS_CheckMouseMode;
+ device->GrabInput = RISCOS_GrabInput;
+
+ device->InitOSKeymap = RISCOS_InitOSKeymap;
+
+ device->GetWMInfo = RISCOS_GetWmInfo;
+
+ device->free = RISCOS_DeleteDevice;
+
+/* Can't get Toggle screen to work if program starts up in Full screen mode so
+ disable it here and re-enable it when a wimp screen is chosen */
+ device->ToggleFullScreen = NULL; /*RISCOS_ToggleFullScreen;*/
+
+ /* Set other entries for fullscreen mode */
+ FULLSCREEN_SetDeviceMode(device);
+
+ /* Mouse pointer needs to use the WIMP ShowCursor version so
+ that it doesn't modify the pointer until the SDL Window is
+ entered or the application goes full screen */
+ device->ShowWMCursor = WIMP_ShowWMCursor;
+
+ return device;
+}
+
+VideoBootStrap RISCOS_bootstrap = {
+ RISCOSVID_DRIVER_NAME, "RISC OS video driver",
+ RISCOS_Available, RISCOS_CreateDevice
+};
+
+
+int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ _kernel_swi_regs regs;
+ int vars[4], vals[3];
+
+ if (RISCOS_InitTask() == 0)
+ {
+ SDL_SetError("Unable to start task");
+ return 0;
+ }
+
+ vars[0] = 9; /* Log base 2 bpp */
+ vars[1] = 11; /* XWndLimit - num x pixels -1 */
+ vars[2] = 12; /* YWndLimit - num y pixels -1 */
+ vars[3] = -1; /* Terminate list */
+ regs.r[0] = (int)vars;
+ regs.r[1] = (int)vals;
+
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+ vformat->BitsPerPixel = (1 << vals[0]);
+
+ /* Determine the current screen size */
+ this->info.current_w = vals[1] + 1;
+ this->info.current_h = vals[2] + 1;
+
+ /* Minimum bpp for SDL is 8 */
+ if (vformat->BitsPerPixel < 8) vformat->BitsPerPixel = 8;
+
+
+ switch (vformat->BitsPerPixel)
+ {
+ case 15:
+ case 16:
+ vformat->Bmask = 0x00007c00;
+ vformat->Gmask = 0x000003e0;
+ vformat->Rmask = 0x0000001f;
+ vformat->BitsPerPixel = 16; /* SDL wants actual number of bits used */
+ vformat->BytesPerPixel = 2;
+ break;
+
+ case 24:
+ case 32:
+ vformat->Bmask = 0x00ff0000;
+ vformat->Gmask = 0x0000ff00;
+ vformat->Rmask = 0x000000ff;
+ vformat->BytesPerPixel = 4;
+ break;
+
+ default:
+ vformat->Bmask = 0;
+ vformat->Gmask = 0;
+ vformat->Rmask = 0;
+ vformat->BytesPerPixel = 1;
+ break;
+ }
+
+ /* Fill in some window manager capabilities */
+ this->info.wm_available = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void RISCOS_VideoQuit(_THIS)
+{
+ RISCOS_ExitTask();
+
+ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
+ this->hidden->alloc_bank = 0;
+}
+
+
+SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if (flags & SDL_FULLSCREEN)
+ {
+ /* Build mode list when first required. */
+ if (SDL_nummodes[0] == 0) FULLSCREEN_BuildModeList(this);
+
+ return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+ } else
+ return (SDL_Rect **)-1;
+}
+
+
+/* Set up video mode */
+SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ if (flags & SDL_FULLSCREEN)
+ {
+ RISCOS_StoreWimpMode();
+ /* Dump wimp window on switch to full screen */
+ if (this->hidden->window_handle) WIMP_DeleteWindow(this);
+
+ return FULLSCREEN_SetVideoMode(this, current, width, height, bpp, flags);
+ } else
+ {
+ RISCOS_RestoreWimpMode();
+ return WIMP_SetVideoMode(this, current, width, height, bpp, flags);
+ }
+}
+
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+
+int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info)
+{
+ SDL_VERSION(&(info->version));
+ info->wimpVersion = RISCOS_GetWimpVersion();
+ info->taskHandle = RISCOS_GetTaskHandle();
+ info->window = this->hidden->window_handle;
+
+ return 1;
+}
+/* Toggle full screen mode.
+ Returns 1 if successful otherwise 0
+*/
+
+int RISCOS_ToggleFullScreen(_THIS, int fullscreen)
+{
+ if (fullscreen)
+ {
+ return FULLSCREEN_ToggleFromWimp(this);
+ } else
+ {
+ return WIMP_ToggleFromFullScreen(this);
+ }
+
+ return 0;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h
new file mode 100644
index 0000000..7c717ad
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h
@@ -0,0 +1,62 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_riscosvideo_h
+#define _SDL_riscosvideo_h
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+
+/* Private display data */
+
+struct SDL_PrivateVideoData {
+ unsigned char *bank[2];
+ int current_bank;
+ unsigned char *alloc_bank;
+ int height;
+ int xeig;
+ int yeig;
+ int screen_bpp;
+ int screen_width;
+ int screen_height;
+ char *pixtrans;
+
+ /* Wimp variables */
+ unsigned int window_handle;
+ char title[256];
+
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+};
+
+/* Old variable names */
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+
+#endif /* _SDL_risosvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c
new file mode 100644
index 0000000..4999664
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c
@@ -0,0 +1,330 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements Pumping of events and WIMP polling
+*/
+
+#include "SDL.h"
+#include "SDL_syswm.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+#include "../../timer/SDL_timer_c.h"
+
+#include "memory.h"
+#include "stdlib.h"
+#include "ctype.h"
+
+#include "kernel.h"
+#include "swis.h"
+#include "unixlib/os.h"
+
+#if !SDL_THREADS_DISABLED
+#include <pthread.h>
+#endif
+
+/* Local functions */
+void WIMP_Poll(_THIS, int waitTime);
+void WIMP_SetFocus(int win);
+
+/* SDL_riscossprite functions */
+void WIMP_PlotSprite(_THIS, int x, int y);
+void WIMP_ModeChanged(_THIS);
+void WIMP_PaletteChanged(_THIS);
+
+
+extern void WIMP_PollMouse(_THIS);
+extern void RISCOS_PollKeyboard();
+
+#if SDL_THREADS_DISABLED
+/* Timer running function */
+extern void RISCOS_CheckTimer();
+#else
+extern int riscos_using_threads;
+#endif
+
+/* Mouse cursor handling */
+extern void WIMP_ReshowCursor(_THIS);
+extern void WIMP_RestoreWimpCursor();
+
+int hasFocus = 0;
+int mouseInWindow = 0;
+
+/* Flag to ensure window is correct size after a mode change */
+static int resizeOnOpen = 0;
+
+void WIMP_PumpEvents(_THIS)
+{
+ WIMP_Poll(this, 0);
+ if (hasFocus) RISCOS_PollKeyboard();
+ if (mouseInWindow) WIMP_PollMouse(this);
+#if SDL_THREADS_DISABLED
+ if (SDL_timer_running) RISCOS_CheckTimer();
+#endif
+}
+
+
+void WIMP_Poll(_THIS, int waitTime)
+{
+ _kernel_swi_regs regs;
+ int message[64];
+ unsigned int code;
+ int pollMask = 0;
+ int doPoll = 1;
+ int sysEvent;
+ int sdlWindow = this->hidden->window_handle;
+
+ if (this->PumpEvents != WIMP_PumpEvents) return;
+
+ if (waitTime > 0)
+ {
+ _kernel_swi(OS_ReadMonotonicTime, &regs, &regs);
+ waitTime += regs.r[0];
+ }
+
+ while (doPoll)
+ {
+#if !SDL_THREADS_DISABLED
+ /* Stop thread callbacks while program is paged out */
+ if (riscos_using_threads) __pthread_stop_ticker();
+#endif
+
+ if (waitTime <= 0)
+ {
+ regs.r[0] = pollMask; /* Poll Mask */
+ /* For no wait time mask out null event so we wait until something happens */
+ if (waitTime < 0) regs.r[0] |= 1;
+ regs.r[1] = (int)message;
+ _kernel_swi(Wimp_Poll, &regs, &regs);
+ } else
+ {
+ regs.r[0] = pollMask;
+ regs.r[1] = (int)message;
+ regs.r[2] = waitTime;
+ _kernel_swi(Wimp_PollIdle, &regs, &regs);
+ }
+
+ /* Flag to specify if we post a SDL_SysWMEvent */
+ sysEvent = 0;
+
+ code = (unsigned int)regs.r[0];
+
+ switch(code)
+ {
+ case 0: /* Null Event - drop out for standard processing*/
+ doPoll = 0;
+ break;
+
+ case 1: /* Redraw window */
+ _kernel_swi(Wimp_RedrawWindow, &regs,&regs);
+ if (message[0] == sdlWindow)
+ {
+ while (regs.r[0])
+ {
+ WIMP_PlotSprite(this, message[1], message[2]);
+ _kernel_swi(Wimp_GetRectangle, &regs, &regs);
+ }
+ } else
+ {
+ /* TODO: Currently we just eat them - we may need to pass them on */
+ while (regs.r[0])
+ {
+ _kernel_swi(Wimp_GetRectangle, &regs, &regs);
+ }
+ }
+ break;
+
+ case 2: /* Open window */
+ if ( resizeOnOpen && message[0] == sdlWindow)
+ {
+ /* Ensure window is correct size */
+ resizeOnOpen = 0;
+ message[3] = message[1] + (this->screen->w << this->hidden->xeig);
+ message[4] = message[2] + (this->screen->h << this->hidden->yeig);
+ }
+ _kernel_swi(Wimp_OpenWindow, &regs, &regs);
+ break;
+
+ case 3: /* Close window */
+ if (message[0] == sdlWindow)
+ {
+ /* Documentation makes it looks as if the following line is correct:
+ ** if (SDL_PrivateQuit() == 1) _kernel_swi(Wimp_CloseWindow, &regs, &regs);
+ ** However some programs don't process this message and so sit there invisibly
+ ** in the background so I just post the quit message and hope the application
+ ** does the correct thing.
+ */
+ SDL_PrivateQuit();
+ } else
+ sysEvent = 1;
+ doPoll = 0;
+ break;
+
+ case 4: /* Pointer_Leaving_Window */
+ if (message[0] == sdlWindow)
+ {
+ mouseInWindow = 0;
+ //TODO: Lose buttons / dragging
+ /* Reset to default pointer */
+ WIMP_RestoreWimpCursor();
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ } else
+ sysEvent = 1;
+ break;
+
+ case 5: /* Pointer_Entering_Window */
+ if (message[0] == sdlWindow)
+ {
+ mouseInWindow = 1;
+ WIMP_ReshowCursor(this);
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ } else sysEvent = 1;
+ break;
+
+ case 6: /* Mouse_Click */
+ if (hasFocus == 0)
+ {
+ /* First click gives focus if it's not a menu */
+ /* we only count non-menu clicks on a window that has the focus */
+ WIMP_SetFocus(message[3]);
+ } else
+ doPoll = 0; // So PollMouse gets a chance to pick it up
+ break;
+
+ case 7: /* User_Drag_Box - Used for mouse release */
+ //TODO: May need to implement this in the future
+ sysEvent = 1;
+ break;
+
+ case 8: /* Keypressed */
+ doPoll = 0; /* PollKeyboard should pick it up */
+ if (message[0] != sdlWindow) sysEvent = 1;
+ /*TODO: May want to always pass F12 etc to the wimp
+ {
+ regs.r[0] = message[6];
+ _kernel_swi(Wimp_ProcessKey, &regs, &regs);
+ }
+ */
+ break;
+
+ case 11: /* Lose Caret */
+ hasFocus = 0;
+ if (message[0] == sdlWindow) SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
+ else sysEvent = 1;
+ break;
+
+ case 12: /* Gain Caret */
+ hasFocus = 1;
+ if (message[0] == sdlWindow) SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+ else sysEvent = 1;
+ break;
+
+ case 17:
+ case 18:
+ sysEvent = 1; /* All messages are passed on */
+
+ switch(message[4])
+ {
+ case 0: /* Quit Event */
+ /* No choice - have to quit */
+ SDL_Quit();
+ exit(0);
+ break;
+
+ case 8: /* Pre Quit */
+ SDL_PrivateQuit();
+ break;
+
+ case 0x400c1: /* Mode change */
+ WIMP_ModeChanged(this);
+ resizeOnOpen = 1;
+ break;
+
+ case 9: /* Palette changed */
+ WIMP_PaletteChanged(this);
+ break;
+ }
+ break;
+
+ default:
+ /* Pass unknown events on */
+ sysEvent = 1;
+ break;
+ }
+
+ if (sysEvent)
+ {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.eventCode = code;
+ SDL_memcpy(wmmsg.pollBlock, message, 64 * sizeof(int));
+
+ /* Fall out of polling loop if message is successfully posted */
+ if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0;
+ }
+#if !SDL_THREADS_DISABLED
+ if (riscos_using_threads)
+ {
+ /* Restart ticker here so other thread can not interfere
+ with the Redraw processing */
+ if (riscos_using_threads) __pthread_start_ticker();
+ /* Give other threads a better chance of running */
+ pthread_yield();
+ }
+#endif
+ }
+}
+
+/* Set focus to specified window */
+void WIMP_SetFocus(int win)
+{
+ _kernel_swi_regs regs;
+
+ regs.r[0] = win;
+ regs.r[1] = -1; /* Icon handle */
+ regs.r[2] = 0; /* X-offset we just put it at position 0 */
+ regs.r[3] = 0; /* Y-offset as above */
+ regs.r[4] = 1 << 25; /* Caret is invisible */
+ regs.r[5] = 0; /* index into string */
+
+ _kernel_swi(Wimp_SetCaretPosition, &regs, &regs);
+}
+
+/** Run background task while in a sleep command */
+void RISCOS_BackgroundTasks(void)
+{
+ if (current_video && current_video->hidden->window_handle)
+ {
+ WIMP_Poll(current_video, 0);
+ }
+#if SDL_THREADS_DISABLED
+ if (SDL_timer_running) RISCOS_CheckTimer();
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c
new file mode 100644
index 0000000..0f9c545
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c
@@ -0,0 +1,501 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements RISC OS Wimp display.
+*/
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_riscostask.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+/* Initialization/Query functions */
+SDL_Rect **WIMP_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+void WIMP_SetWMCaption(_THIS, const char *title, const char *icon);
+
+
+extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp);
+extern void WIMP_PumpEvents(_THIS);
+extern void WIMP_PlotSprite(_THIS, int x, int y);
+extern void WIMP_SetupPlotInfo(_THIS);
+extern void WIMP_SetFocus(int win);
+
+/* etc. */
+static void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+/* RISC OS Wimp handling helpers */
+void WIMP_ReadModeInfo(_THIS);
+unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface);
+void WIMP_SetDeviceMode(_THIS);
+void WIMP_DeleteWindow(_THIS);
+
+/* FULLSCREEN function required for wimp/fullscreen toggling */
+extern int FULLSCREEN_SetMode(int width, int height, int bpp);
+
+/* Currently need to set this up here as it only works if you
+ start up in a Wimp mode */
+extern int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
+
+extern int riscos_backbuffer;
+extern int mouseInWindow;
+extern int riscos_closeaction;
+
+/* Following needed to ensure window is shown immediately */
+extern int hasFocus;
+extern void WIMP_Poll(_THIS, int waitTime);
+
+SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ Uint32 Rmask = 0;
+ Uint32 Gmask = 0;
+ Uint32 Bmask = 0;
+ char *buffer = NULL;
+ int bytesPerPixel = 1;
+
+ /* Don't support double buffering in Wimp mode */
+ flags &= ~SDL_DOUBLEBUF;
+ flags &= ~SDL_HWSURFACE;
+
+ switch(bpp)
+ {
+ case 8:
+ /* Emulated palette using ColourTrans */
+ flags |= SDL_HWPALETTE;
+ break;
+
+ case 15:
+ case 16:
+ Bmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Rmask = 0x0000001f;
+ bytesPerPixel = 2;
+ break;
+
+ case 32:
+ Bmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Rmask = 0x000000ff;
+ bytesPerPixel = 4;
+ break;
+
+ default:
+ SDL_SetError("Pixel depth not supported");
+ return NULL;
+ break;
+ }
+
+/* printf("Setting mode %dx%d\n", width, height);*/
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->w = width;
+ this->hidden->height = current->h = height;
+
+ if (bpp == 15) bpp = 16;
+ buffer = WIMP_CreateBuffer(width, height, bpp);
+ if (buffer == NULL)
+ {
+ SDL_SetError("Couldn't create sprite for video memory");
+ return (NULL);
+ }
+
+ this->hidden->bank[0] = buffer + 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+
+ this->hidden->bank[1] = buffer; /* Start of buffer */
+
+ /* Remember sprite buffer so it can be freed later */
+ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
+ this->hidden->alloc_bank = buffer;
+
+ current->pitch = width * bytesPerPixel;
+ if ((current->pitch & 3))
+ {
+ /* Sprites are 32bit word aligned */
+ current->pitch += (4 - (current->pitch & 3));
+ }
+
+ current->flags = flags | SDL_PREALLOC;
+
+ WIMP_ReadModeInfo(this);
+
+ SDL_memset(this->hidden->bank[0], 0, height * current->pitch);
+
+ this->hidden->current_bank = 0;
+ current->pixels = this->hidden->bank[0];
+
+
+ if (WIMP_SetupWindow(this, current) == 0)
+ {
+ SDL_SetError("Unable to create window to display surface");
+ return NULL;
+ }
+
+ /* Reset device functions for the wimp */
+ WIMP_SetDeviceMode(this);
+
+ /* Needs to set up plot info after window has been created */
+ /* Not sure why, but plots don't work if I do it earlier */
+ WIMP_SetupPlotInfo(this);
+
+ /* Poll until window is shown */
+ {
+ /* We wait until it gets the focus, but give up after 5 seconds
+ in case the focus is prevented in any way.
+ */
+ Uint32 now = SDL_GetTicks();
+ while (!hasFocus && SDL_GetTicks() - now < 5000)
+ {
+ WIMP_Poll(this, 0);
+ }
+ }
+
+ /* We're done */
+ return(current);
+}
+
+
+void WIMP_ReadModeInfo(_THIS)
+{
+ _kernel_swi_regs regs;
+ int vars[6];
+ int vals[5];
+
+ vars[0] = 4; /* XEig */
+ vars[1] = 5; /* YEig */
+ vars[2] = 9; /* Log base 2 bpp */
+ vars[3] = 11; /* Screen Width - 1 */
+ vars[4] = 12; /* Screen Depth - 1 */
+ vars[5] = -1; /* Terminate list */
+
+ regs.r[0] = (int)vars;
+ regs.r[1] = (int)vals;
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+ this->hidden->xeig = vals[0];
+ this->hidden->yeig = vals[1];
+ this->hidden->screen_bpp = 1 << vals[2];
+ this->hidden->screen_width = vals[3] + 1;
+ this->hidden->screen_height = vals[4] + 1;
+}
+
+/* Set device function to call the correct versions for running
+ in a wimp window */
+
+void WIMP_SetDeviceMode(_THIS)
+{
+ if (this->UpdateRects == WIMP_UpdateRects) return; /* Already set up */
+
+ this->SetColors = WIMP_SetColors;
+ this->UpdateRects = WIMP_UpdateRects;
+
+ this->FlipHWSurface = NULL;
+
+ this->SetCaption = WIMP_SetWMCaption;
+ this->SetIcon = NULL;
+ this->IconifyWindow = NULL;
+
+ this->ShowWMCursor = WIMP_ShowWMCursor;
+ this->WarpWMCursor = WIMP_WarpWMCursor;
+
+ this->ToggleFullScreen = RISCOS_ToggleFullScreen;
+
+ this->PumpEvents = WIMP_PumpEvents;
+}
+
+/* Setup the Window to display the surface */
+unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface)
+{
+ _kernel_swi_regs regs;
+ int window_data[23];
+ int *window_block = window_data+1;
+ int x = (this->hidden->screen_width - surface->w) / 2;
+ int y = (this->hidden->screen_height - surface->h) / 2;
+ int xeig = this->hidden->xeig;
+ int yeig = this->hidden->yeig;
+
+ mouseInWindow = 0;
+
+ /* Always delete the window and recreate on a change */
+ if (this->hidden->window_handle) WIMP_DeleteWindow(this);
+
+ /* Setup window co-ordinates */
+ window_block[0] = x << xeig;
+ window_block[1] = y << yeig;
+ window_block[2] = window_block[0] + (surface->w << xeig);
+ window_block[3] = window_block[1] + (surface->h << yeig);
+
+
+ window_block[4] = 0; /* Scroll offsets */
+ window_block[5] = 0;
+ window_block[6] = -1; /* Open on top of window stack */
+
+ window_block[7] = 0x85040042; /* Window flags */
+ if (riscos_closeaction != 0) window_block[7] |= 0x2000000;
+
+ /* TODO: Take into account surface->flags */
+
+ window_block[8] = 0xff070207; /* Window colours */
+ window_block[9] = 0x000c0103;
+ window_block[10] = 0; /* Work area minimum */
+ window_block[11] = -surface->h << yeig;
+ window_block[12] = surface->w << xeig; /* Work area maximum */
+ window_block[13] = 0;
+ window_block[14] = 0x2700013d; /* Title icon flags */
+ window_block[15] = 0x00003000; /* Work area flags - Mouse click down reported */
+ window_block[16] = 1; /* Sprite area control block pointer */
+ window_block[17] = 0x00100010; /* Minimum window size (width & height) (16x16)*/
+ window_block[18] = (int)this->hidden->title; /* Title data */
+ window_block[19] = -1;
+ window_block[20] = 256;
+ window_block[21] = 0; /* Number of icons */
+
+ regs.r[1] = (unsigned int)(window_block);
+
+ /* Create the window */
+ if (_kernel_swi(Wimp_CreateWindow, &regs, &regs) == NULL)
+ {
+ this->hidden->window_handle = window_data[0] = regs.r[0];
+
+ /* Show the window on the screen */
+ regs.r[1] = (unsigned int)window_data;
+ if (_kernel_swi(Wimp_OpenWindow, &regs, &regs) == NULL)
+ {
+ WIMP_SetFocus(this->hidden->window_handle);
+ } else
+ {
+ WIMP_DeleteWindow(this);
+ }
+ }
+
+ return this->hidden->window_handle;
+}
+
+/* Destroy the Window */
+
+void WIMP_DeleteWindow(_THIS)
+{
+ _kernel_swi_regs regs;
+ regs.r[1] = (unsigned int)&(this->hidden->window_handle);
+ _kernel_swi(Wimp_DeleteWindow, &regs, &regs);
+ this->hidden->window_handle = 0;
+}
+
+
+void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ _kernel_swi_regs regs;
+ int update_block[12];
+ int xeig = this->hidden->xeig;
+ int yeig = this->hidden->yeig;
+ int j;
+ update_block[0] = this->hidden->window_handle;
+
+ for (j = 0; j < numrects; j++)
+ {
+ update_block[1] = rects[j].x << xeig; /* Min X */
+ update_block[4] = -(rects[j].y << yeig);
+ update_block[3] = update_block[1] + (rects[j].w << xeig);
+ update_block[2] = update_block[4] - (rects[j].h << yeig);
+
+ regs.r[1] = (int)update_block;
+ /* Update window can fail if called before first poll */
+ if (_kernel_swi(Wimp_UpdateWindow, &regs, &regs) == 0)
+ {
+ while (regs.r[0])
+ {
+ WIMP_PlotSprite(this, update_block[1], update_block[2]);
+ _kernel_swi(Wimp_GetRectangle, &regs, &regs);
+ }
+ }
+ }
+}
+
+
+int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ unsigned int *pal = (unsigned int *)(this->hidden->bank[1]+60);
+ int j;
+ SDL_Rect update;
+
+ pal += firstcolor*2;
+ for (j = 0; j < ncolors; j++)
+ {
+ *pal = (((unsigned int)colors->r) << 8)
+ + (((unsigned int)colors->g) << 16)
+ + (((unsigned int)colors->b) << 24);
+ pal[1] = *pal;
+ pal += 2;
+ colors++;
+ }
+
+ WIMP_SetupPlotInfo(this);
+
+ /* Need to refresh the window */
+ update.x = 0;
+ update.y = 0;
+ update.w = SDL_VideoSurface->w;
+ update.h = SDL_VideoSurface->h;
+ WIMP_UpdateRects(this, 1, &update);
+
+ return 1;
+}
+
+void WIMP_SetWMCaption(_THIS, const char *title, const char *icon)
+{
+ _kernel_swi_regs regs;
+
+ SDL_strlcpy(this->hidden->title, title, SDL_arraysize(this->hidden->title));
+
+ if (RISCOS_GetWimpVersion() < 380)
+ {
+ int block[6];
+
+ regs.r[1] = (int)block;
+ _kernel_swi(Wimp_GetCaretPosition, &regs, &regs);
+ if (block[0] == (int)this->hidden->window_handle)
+ {
+ regs.r[0] = -1;
+ _kernel_swi(Wimp_SetCaretPosition, &regs,&regs);
+ } else
+ {
+ regs.r[0] = this->hidden->window_handle;
+ regs.r[1] = -1;
+ regs.r[2] = -1;
+ regs.r[3] = -1;
+ _kernel_swi(Wimp_SetCaretPosition, &regs,&regs);
+ }
+ regs.r[0] = block[0];
+ regs.r[1] = block[1];
+ regs.r[2] = block[2];
+ regs.r[3] = block[3];
+ regs.r[4] = block[4];
+ regs.r[5] = block[5];
+ _kernel_swi(Wimp_SetCaretPosition, &regs,&regs);
+ } else
+ {
+ regs.r[0] = this->hidden->window_handle;
+ regs.r[1] = 0x4b534154; /* "TASK" */
+ regs.r[2] = 3; /* Redraw title */
+ _kernel_swi(Wimp_ForceRedraw, &regs, &regs);
+ }
+}
+
+void WIMP_RefreshDesktop(_THIS)
+{
+ int width = this->hidden->screen_width << this->hidden->xeig;
+ int height = this->hidden->screen_height << this->hidden->yeig;
+ _kernel_swi_regs regs;
+ regs.r[0] = -1; /* Whole screen */
+ regs.r[1] = 0;
+ regs.r[2] = 0;
+ regs.r[3] = width;
+ regs.r[4] = height;
+ _kernel_swi(Wimp_ForceRedraw, &regs, &regs);
+}
+
+/* Toggle to window from full screen */
+int WIMP_ToggleFromFullScreen(_THIS)
+{
+ int width = this->screen->w;
+ int height = this->screen->h;
+ int bpp = this->screen->format->BitsPerPixel;
+ char *buffer = NULL;
+ char *old_bank[2];
+ char *old_alloc_bank;
+
+ /* Ensure flags are OK */
+ this->screen->flags &= ~(SDL_DOUBLEBUF|SDL_HWSURFACE);
+
+ if (this->hidden->bank[0] == this->hidden->alloc_bank || riscos_backbuffer == 0)
+ {
+ /* Need to create a sprite for the screen and copy the data to it */
+ char *data;
+ buffer = WIMP_CreateBuffer(width, height, bpp);
+ data = buffer + 60; /* Start of sprite data */
+ if (bpp == 8) data += 2048; /* 8bpp sprite have palette first */
+
+ if (buffer == NULL) return 0;
+ SDL_memcpy(data, this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel);
+ }
+ /* else We've switch to full screen before so we already have a sprite */
+
+ old_bank[0] = this->hidden->bank[0];
+ old_bank[1] = this->hidden->bank[1];
+ old_alloc_bank = this->hidden->alloc_bank;
+
+ if (buffer != NULL) this->hidden->alloc_bank = buffer;
+
+ this->hidden->bank[1] = this->hidden->alloc_bank;
+ this->hidden->bank[0] = this->hidden->bank[1] + 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+
+ this->hidden->current_bank = 0;
+ this->screen->pixels = this->hidden->bank[0];
+
+ RISCOS_RestoreWimpMode();
+ WIMP_ReadModeInfo(this);
+ if (WIMP_SetupWindow(this, this->screen))
+ {
+ WIMP_SetDeviceMode(this);
+ WIMP_SetupPlotInfo(this);
+
+ if (riscos_backbuffer == 0) riscos_backbuffer = 1;
+
+ if (buffer && old_alloc_bank) SDL_free(old_alloc_bank);
+
+ return 1;
+ } else
+ {
+ /* Drop back to full screen mode on failure */
+ this->hidden->bank[0] = old_bank[0];
+ this->hidden->bank[1] = old_bank[1];
+ this->hidden->alloc_bank = old_alloc_bank;
+ if (buffer) SDL_free(buffer);
+
+ RISCOS_StoreWimpMode();
+ FULLSCREEN_SetMode(width, height, bpp);
+ }
+
+ return 0;
+}