Mercurial > sdl-ios-xcode
diff src/video/riscos/SDL_riscostask.c @ 630:550bccdf04bd
Added initial support for RISC OS (thanks Peter Naulls!)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 29 May 2003 04:44:13 +0000 |
parents | |
children | b8d311d90021 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/riscos/SDL_riscostask.c Thu May 29 04:44:13 2003 +0000 @@ -0,0 +1,356 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com +*/ + +/* + This file added by Alan Buckley (alan_baa@hotmail.com) to support RISCOS + 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 <stdlib.h> +#include <string.h> + +#include "kernel.h" +#include "swis.h" + +#include "SDL_riscostask.h" + +/* RISCOS 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 */ +int riscos_audiobuffer = 0; /* Audio buffer size */ + +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); + +/* 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 RISCOS Wimp task + +*******************************************************************/ + +int RISCOS_InitTask() +{ + char task_name[32]; + _kernel_swi_regs regs; + int messages[4]; + + if (RISCOS_GetTaskName(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; + } + + 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 riscos 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 + + SDL$<name>$AudioBuffer - set to number of samples to buffer + in advance. Will default to a minimum of 1024 or twice + amount requested by program whichever is largest. + If not specified default is amount for 10 csecs. + Time that will be pre-buffered can be calculated as + sample to buffer * 1000 / freq milliseconds. + +***************************************************************************/ + +int RISCOS_GetTaskName(char *task_name) +{ + _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]; + char *buffer = malloc(strlen(command_line)+1); + char *env_var; + char *p; + + strcpy(buffer, command_line); + p = strchr(buffer, ' '); + if (p) *p = 0; + p = strrchr(buffer, '.'); + if (p == 0) p = buffer; + if (stricmp(p+1,"!RunImage") == 0) + { + *p = 0; + p = 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 = strchr(p, '$'); + if (q == 0) q = strchr(p,'>'); /* Use variable name if not */ + if (q) *q = 0; + p++; /* Move over the < */ + } + + if (*p) + { + /* Read variables that effect the RISCOS SDL engine for this task */ + env_var = malloc(strlen(p) + 18); /* 18 is larger than the biggest variable name */ + if (env_var) + { + char *env_val; + + /* See if a variable of form SDL$<dirname>$TaskName exists */ + + strcpy(env_var, "SDL$"); + strcat(env_var, p); + strcat(env_var, "$TaskName"); + + env_val = getenv(env_var); + if (env_val) strncpy(task_name, env_val, 31); + + strcpy(env_var, "SDL$"); + strcat(env_var, p); + strcat(env_var, "$BackBuffer"); + + env_val = getenv(env_var); + if (env_val && strcmp(env_val,"1") == 0) riscos_backbuffer = 1; + + strcpy(env_var, "SDL$"); + strcat(env_var, p); + strcat(env_var, "$CloseAction"); + + env_val = getenv(env_var); + if (env_val && strcmp(env_val,"0") == 0) riscos_closeaction = 0; + + strcpy(env_var, "SDL$"); + strcat(env_var, p); + strcat(env_var, "$AudioBuffer"); + + env_val = getenv(env_var); + riscos_audiobuffer = atoi(env_val); + + free(env_var); + } + + if (task_name[0] == 0) strncpy(task_name, p, 31); + task_name[31] = 0; + } + + free(buffer); + } + + if (task_name[0] == 0) strcpy(task_name, "SDL Task"); + + 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 *)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) + { + 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; +}