diff options
Diffstat (limited to 'distrib/sdl-1.2.15/src/video/riscos')
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S | 116 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c | 777 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c | 549 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h | 34 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c | 371 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h | 44 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c | 265 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c | 350 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h | 39 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c | 316 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h | 62 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c | 330 | ||||
-rw-r--r-- | distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c | 501 |
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, ®s, ®s); + + current->pitch = regs.r[2]; + + if (flags & SDL_DOUBLEBUF) + { + regs.r[0] = 2; /* Screen area */ + _kernel_swi(OS_ReadDynamicArea, ®s, ®s); + + /* 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, ®s, ®s) != 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, ®s, ®s); + + 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, ®s, ®s); + + 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, ®s, ®s); + + 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, ®s, ®s)) != 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, ®s, ®s); + + 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, ®s, ®s); + + 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, ®s, ®s); +} + +void FULLSCREEN_SetDisplayBank(int bank) +{ + _kernel_swi_regs regs; + regs.r[0] = 113; + regs.r[1] = bank+1; + _kernel_swi(OS_Byte, ®s, ®s); +} + + +/** 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, ®s, ®s); + +} + +/** 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, ®s, ®s); + +} + +/** 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, ®s, ®s) != 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, ®s, ®s); + + 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, ®s, ®s) == 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, ®s, ®s); + + 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, ®s, ®s); + } + } + } 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, ®s, ®s); + + 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, ®s, ®s); + + 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, ®s, ®s); + 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, ®s, ®s); + + 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, ®s, ®s); + } + + 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, ®s, ®s) == 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, ®s, ®s); + + 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, ®s, ®s) == 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, ®s, ®s); + 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, ®s, ®s); + } +} + +/* 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, ®s, ®s)) != 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, ®s, ®s); + + 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, ®s, ®s); + + /*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, ®s, ®s) == 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, ®s, ®s); + 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, ®s, ®s) == 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, ®s, ®s); + 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, ®s, ®s); + 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, ®s, ®s); + + 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, ®s, ®s); + 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, ®s, ®s); + 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, ®s, ®s); + } else + { + regs.r[0] = pollMask; + regs.r[1] = (int)message; + regs.r[2] = waitTime; + _kernel_swi(Wimp_PollIdle, ®s, ®s); + } + + /* 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, ®s,®s); + if (message[0] == sdlWindow) + { + while (regs.r[0]) + { + WIMP_PlotSprite(this, message[1], message[2]); + _kernel_swi(Wimp_GetRectangle, ®s, ®s); + } + } else + { + /* TODO: Currently we just eat them - we may need to pass them on */ + while (regs.r[0]) + { + _kernel_swi(Wimp_GetRectangle, ®s, ®s); + } + } + 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, ®s, ®s); + 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, ®s, ®s); + ** 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, ®s, ®s); + } + */ + 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, ®s, ®s); +} + +/** 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, ®s, ®s); + 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, ®s, ®s) == 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, ®s, ®s) == 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, ®s, ®s); + 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, ®s, ®s) == 0) + { + while (regs.r[0]) + { + WIMP_PlotSprite(this, update_block[1], update_block[2]); + _kernel_swi(Wimp_GetRectangle, ®s, ®s); + } + } + } +} + + +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, ®s, ®s); + if (block[0] == (int)this->hidden->window_handle) + { + regs.r[0] = -1; + _kernel_swi(Wimp_SetCaretPosition, ®s,®s); + } else + { + regs.r[0] = this->hidden->window_handle; + regs.r[1] = -1; + regs.r[2] = -1; + regs.r[3] = -1; + _kernel_swi(Wimp_SetCaretPosition, ®s,®s); + } + 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, ®s,®s); + } else + { + regs.r[0] = this->hidden->window_handle; + regs.r[1] = 0x4b534154; /* "TASK" */ + regs.r[2] = 3; /* Redraw title */ + _kernel_swi(Wimp_ForceRedraw, ®s, ®s); + } +} + +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, ®s, ®s); +} + +/* 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; +} |