From a855d6202536ff28e5aae4f22a0f31d8f5b325d0 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 21 Jan 2017 15:18:31 -0500 Subject: Port of Duke Nukem 3D This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL for Rockbox. Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9 --- apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S | 116 +++ .../src/video/riscos/SDL_riscosFullScreenVideo.c | 777 +++++++++++++++++++++ .../sdl/src/video/riscos/SDL_riscosevents.c | 549 +++++++++++++++ .../sdl/src/video/riscos/SDL_riscosevents_c.h | 34 + .../plugins/sdl/src/video/riscos/SDL_riscosmouse.c | 371 ++++++++++ .../sdl/src/video/riscos/SDL_riscosmouse_c.h | 44 ++ .../sdl/src/video/riscos/SDL_riscossprite.c | 265 +++++++ apps/plugins/sdl/src/video/riscos/SDL_riscostask.c | 350 ++++++++++ apps/plugins/sdl/src/video/riscos/SDL_riscostask.h | 39 ++ .../plugins/sdl/src/video/riscos/SDL_riscosvideo.c | 316 +++++++++ .../plugins/sdl/src/video/riscos/SDL_riscosvideo.h | 62 ++ apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c | 330 +++++++++ apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c | 501 +++++++++++++ 13 files changed, 3754 insertions(+) create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosevents_c.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosmouse.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosmouse_c.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscossprite.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscostask.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscostask.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_riscosvideo.h create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_wimppoll.c create mode 100644 apps/plugins/sdl/src/video/riscos/SDL_wimpvideo.c (limited to 'apps/plugins/sdl/src/video/riscos') diff --git a/apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S b/apps/plugins/sdl/src/video/riscos/SDL_riscosASM.S new file mode 100644 index 0000000000..fae32f84d6 --- /dev/null +++ b/apps/plugins/sdl/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/apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c b/apps/plugins/sdl/src/video/riscos/SDL_riscosFullScreenVideo.c new file mode 100644 index 0000000000..b8c3cf786b --- /dev/null +++ b/apps/plugins/sdl/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$$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 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; iw == 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/apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c b/apps/plugins/sdl/src/video/riscos/SDL_riscosevents.c new file mode 100644 index 0000000000..54875076ab --- /dev/null +++ b/apps/plugins/sdl/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