From e1bfa2dda4fece0845a1eea08a3906a0ff5d584f Mon Sep 17 00:00:00 2001 From: Darren Alton Date: Tue, 10 Jun 2008 06:57:57 +0000 Subject: [PATCH] Fix for the previous commit: actually 'svn add'ed some files. --- Makefile.ds | 139 ++++++++++++++ include/SDL_config_nintendods.h | 117 ++++++++++++ src/joystick/nds/SDL_sysjoystick.c | 154 ++++++++++++++++ src/thread/nds/SDL_syscond.c | 223 ++++++++++++++++++++++ src/thread/nds/SDL_syscond_c.h | 27 +++ src/thread/nds/SDL_sysmutex.c | 137 ++++++++++++++ src/thread/nds/SDL_sysmutex_c.h | 27 +++ src/thread/nds/SDL_syssem.c | 214 ++++++++++++++++++++++ src/thread/nds/SDL_syssem_c.h | 27 +++ src/thread/nds/SDL_systhread.c | 59 ++++++ src/thread/nds/SDL_systhread_c.h | 28 +++ src/video/nds/SDL_ndsevents.c | 44 +++++ src/video/nds/SDL_ndsevents_c.h | 28 +++ src/video/nds/SDL_ndsrender.c | 285 +++++++++++++++++++++++++++++ src/video/nds/SDL_ndsrender_c.h | 28 +++ src/video/nds/SDL_ndsvideo.c | 174 ++++++++++++++++++ src/video/nds/SDL_ndsvideo.h | 31 ++++ 17 files changed, 1742 insertions(+) create mode 100644 Makefile.ds create mode 100644 include/SDL_config_nintendods.h create mode 100644 src/joystick/nds/SDL_sysjoystick.c create mode 100644 src/thread/nds/SDL_syscond.c create mode 100644 src/thread/nds/SDL_syscond_c.h create mode 100644 src/thread/nds/SDL_sysmutex.c create mode 100644 src/thread/nds/SDL_sysmutex_c.h create mode 100644 src/thread/nds/SDL_syssem.c create mode 100644 src/thread/nds/SDL_syssem_c.h create mode 100644 src/thread/nds/SDL_systhread.c create mode 100644 src/thread/nds/SDL_systhread_c.h create mode 100644 src/video/nds/SDL_ndsevents.c create mode 100644 src/video/nds/SDL_ndsevents_c.h create mode 100644 src/video/nds/SDL_ndsrender.c create mode 100644 src/video/nds/SDL_ndsrender_c.h create mode 100644 src/video/nds/SDL_ndsvideo.c create mode 100644 src/video/nds/SDL_ndsvideo.h diff --git a/Makefile.ds b/Makefile.ds new file mode 100644 index 000000000..80875fa1e --- /dev/null +++ b/Makefile.ds @@ -0,0 +1,139 @@ + +#LibSDL 1.3 porting and enhancements by Darren Alton (lifning) +#LibSDL 1.2.9 DS porting by Troy Davis(GPF) + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM) +endif + +CC = arm-eabi-gcc +AR = arm-eabi-ar +RANLIB = arm-eabi-ranlib + +#ifdef GL +#DEFS += -DSDL_VIDEO_OPENGL=1 +#TARGET = libSDL_gl.a +#else +TARGET = libSDL.a +#endif + +#CFLAGS=$(DEFS) -Iinclude +CFLAGS = -mthumb -mthumb-interwork \ + -march=armv5te -mtune=arm946e-s \ + -O2 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -DARM9 -D__NDS__ -I$(DEVKITPRO)/libnds/include -DENABLE_NDS -DNO_SIGNAL_H -DDISABLE_THREADS -DPACKAGE=\"SDL\" -DVERSION=\"1.3\" -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 \ + -Iinclude -Isrc -Isrc/audio -Isrc/cdrom -Isrc/endian -Isrc/events -Isrc/joystick -Isrc/thread/nds -Isrc/thread -Isrc/timer -Isrc/video + +SRCS = \ +src/SDL.c \ +src/SDL_compat.c \ +src/SDL_error.c \ +src/SDL_fatal.c \ +src/audio/disk/SDL_diskaudio.c \ +src/audio/dummy/SDL_dummyaudio.c \ +src/audio/SDL_audio.c \ +src/audio/SDL_audiocvt.c \ +src/audio/SDL_audiodev.c \ +src/audio/SDL_audiotypecvt.c \ +src/audio/SDL_mixer.c \ +src/audio/SDL_mixer_m68k.c \ +src/audio/SDL_mixer_MMX.c \ +src/audio/SDL_mixer_MMX_VC.c \ +src/audio/SDL_wave.c \ +src/cdrom/dummy/SDL_syscdrom.c \ +src/cdrom/SDL_cdrom.c \ +src/cpuinfo/SDL_cpuinfo.c \ +src/events/SDL_events.c \ +src/events/SDL_keyboard.c \ +src/events/SDL_mouse.c \ +src/events/SDL_quit.c \ +src/events/SDL_windowevents.c \ +src/file/SDL_rwops.c \ +src/joystick/dummy/SDL_sysjoystick.c \ +src/joystick/SDL_joystick.c \ +src/stdlib/SDL_getenv.c \ +src/stdlib/SDL_iconv.c \ +src/stdlib/SDL_malloc.c \ +src/stdlib/SDL_qsort.c \ +src/stdlib/SDL_stdlib.c \ +src/stdlib/SDL_string.c \ +src/thread/SDL_thread.c \ +src/thread/nds/SDL_syscond.c \ +src/thread/nds/SDL_sysmutex.c \ +src/thread/nds/SDL_syssem.c \ +src/thread/nds/SDL_systhread.c \ +src/timer/dummy/SDL_systimer.c \ +src/timer/SDL_timer.c \ +src/video/dummy/SDL_nullevents.c \ +src/video/dummy/SDL_nullrender.c \ +src/video/dummy/SDL_nullvideo.c \ +src/video/nds/SDL_ndsevents.c \ +src/video/nds/SDL_ndsrender.c \ +src/video/nds/SDL_ndsvideo.c \ +src/video/SDL_blit_0.c \ +src/video/SDL_blit_1.c \ +src/video/SDL_blit_A.c \ +src/video/SDL_blit_auto.c \ +src/video/SDL_blit.c \ +src/video/SDL_blit_copy.c \ +src/video/SDL_blit_N.c \ +src/video/SDL_blit_slow.c \ +src/video/SDL_bmp.c \ +src/video/SDL_fill.c \ +src/video/SDL_gamma.c \ +src/video/SDL_pixels.c \ +src/video/SDL_rect.c \ +src/video/SDL_renderer_gl.c \ +src/video/SDL_renderer_sw.c \ +src/video/SDL_RLEaccel.c \ +src/video/SDL_stretch.c \ +src/video/SDL_surface.c \ +src/video/SDL_video.c \ +src/video/SDL_yuv_mmx.c \ +src/video/SDL_yuv_sw.c \ + +OBJS = $(SRCS:.c=.o) + +TEST = \ + test/checkkeys.c \ + test/graywin.c \ + test/loopwave.c \ + test/testalpha.c \ + test/testbitmap.c \ + test/testcdrom.c \ + test/testerror.c \ + test/testgamma.c \ + test/testgl.c \ + test/testhread.c \ + test/testjoystick.c \ + test/testkeys.c \ + test/testlock.c \ + test/testoverlay.c \ + test/testpalette.c \ + test/testsem.c \ + test/testsprite.c \ + test/testtimer.c \ + test/testtypes.c \ + test/testver.c \ + test/testvidinfo.c \ + test/testwin.c \ + test/testwm.c \ + test/threadwin.c \ + test/torturethread.c \ + +all: $(TARGET) + +$(TARGET): copy_config \ + $(OBJS) + $(AR) rc $(TARGET) $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +install: $(TARGET) + @cp libSDL.a $(DEVKITPRO)/libnds/lib/ + +copy_config: + @cp include/SDL_config.h.default include/SDL_config.h + +clean: + rm -f include/SDL_config.h $(OBJS) + diff --git a/include/SDL_config_nintendods.h b/include/SDL_config_nintendods.h new file mode 100644 index 000000000..b001487ed --- /dev/null +++ b/include/SDL_config_nintendods.h @@ -0,0 +1,117 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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 +*/ + +#ifndef _SDL_config_nintendods_h +#define _SDL_config_nintendods_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; + +/* LiF: __PTRDIFF_TYPE__ was causing errors of conflicting typedefs with the + shipping with devkitARM. copied a similar ifdef from it. */ +#ifndef __PTRDIFF_TYPE__ +typedef unsigned long uintptr_t; +#else +typedef unsigned __PTRDIFF_TYPE__ uintptr_t; +#endif + + +#define SDL_HAS_64BIT_TYPE 1 + +/* Useful headers */ +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRDUP 1 +#define HAVE_INDEX 1 +#define HAVE_RINDEX 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRICMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 + +/* DS isn't that sophisticated */ +#define LACKS_SYS_MMAN_H 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* DS doesn't have optical media */ +#define SDL_CDROM_DISABLED 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DISABLED 1 + +/* DS has no dynamic linking afaik */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable various threading systems */ +/*#define SDL_THREAD_NDS 1*/ +#define SDL_THREADS_DISABLED 1 + +/* Enable various timer systems */ +#define SDL_TIMERS_DISABLED 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_NDS 1 + +#endif /* _SDL_config_nintendods_h */ + diff --git a/src/joystick/nds/SDL_sysjoystick.c b/src/joystick/nds/SDL_sysjoystick.c new file mode 100644 index 000000000..6b7b521c0 --- /dev/null +++ b/src/joystick/nds/SDL_sysjoystick.c @@ -0,0 +1,154 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysjoystick.c,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* This is the system specific header for the SDL joystick API */ +#include +//#include +#include /* For the definition of NULL */ + +#include "SDL_error.h" +#include "SDL_joystick.h" +#include "SDL_sysjoystick.h" +#include "SDL_joystick_c.h" + +#include "../../video/nds/SDL_ndsevents_c.h" + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + SDL_numjoysticks = 1; + //keysInit(); + + return(1); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + if(!index) + return "NDS builtin joypad"; + SDL_SetError("No joystick available with that index"); + return (NULL); +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + joystick->nbuttons=8; + joystick->nhats=0; + joystick->nballs=0; + joystick->naxes=2; + return 0; +} + + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ + +int prevbutton=0; +int prevkey=0; + +int dc=NULL;int ldc=0; +u32 keysd,keysu=NULL; +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + //dc=keysd; + //if (dc != NULL) + //{ + //fprintf(stderr,"heartbeat= %d\n",REG_VCOUNT); + //swiWaitForVBlank(); + //scanKeys(); + //keysd = keysDown(); + //keysu = keysUp(); + //ldc=keysd; + + //} + /*if (prevkey !=NULL && prevbutton !=NULL) + { + scanKeys(); + } + */ + + //scanKeys(); + keysd = keysDown(); + keysu = keysUp(); + + + short ax=0,v=0,h=0; + if((keysd&KEY_UP)) {ax=1;v=-10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_UP;}//fprintf(stderr,"KEY_UP\n");} + if((keysd&KEY_DOWN)) {ax=1;v=10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_DOWN;}//fprintf(stderr,"KEY_DOWN\n");} + if((keysd&KEY_LEFT)) {ax=0;h=-10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_LEFT;}//fprintf(stderr,"KEY_LEFT\n");} + if((keysd&KEY_RIGHT)) {ax=0;h=10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_RIGHT;}//fprintf(stderr,"KEY_RIGHT\n");} + + if((keysu&KEY_UP)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=NULL;}//fprintf(stderr,"KEY_UP\n");} + if((keysu&KEY_DOWN)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=NULL;}//fprintf(stderr,"KEY_DOWN\n");} + if((keysu&KEY_LEFT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=NULL;}//fprintf(stderr,"KEY_LEFT\n");} + if((keysu&KEY_RIGHT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=NULL;}//fprintf(stderr,"KEY_RIGHT\n");} + + if((keysd&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED);prevbutton=KEY_A;} + if((keysd&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_PRESSED);prevbutton=KEY_B;} + if((keysd&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_PRESSED);prevbutton=KEY_X;} + if((keysd&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_PRESSED);prevbutton=KEY_Y;} + if((keysd&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_PRESSED);prevbutton=KEY_SELECT;} + if((keysd&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_PRESSED);prevbutton=KEY_START;} + if((keysd&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_PRESSED);prevbutton=KEY_L;} + if((keysd&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_PRESSED);prevbutton=KEY_R;} + + if((keysu&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED);prevbutton=NULL;} + if((keysu&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_RELEASED);prevbutton=NULL;} + if((keysu&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_RELEASED);prevbutton=NULL;} + if((keysu&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_RELEASED);prevbutton=NULL;} + if((keysu&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_RELEASED);prevbutton=NULL;} + if((keysu&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_RELEASED);prevbutton=NULL;} + if((keysu&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_RELEASED);prevbutton=NULL;} + if((keysu&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_RELEASED);prevbutton=NULL;} + + + +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ +} + diff --git a/src/thread/nds/SDL_syscond.c b/src/thread/nds/SDL_syscond.c new file mode 100644 index 000000000..a8d801483 --- /dev/null +++ b/src/thread/nds/SDL_syscond.c @@ -0,0 +1,223 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_syscond.c,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* An implementation of condition variables using semaphores and mutexes */ +/* + This implementation borrows heavily from the BeOS condition variable + implementation, written by Christopher Tate and Owen Smith. Thanks! + */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + +struct SDL_cond +{ + SDL_mutex *lock; + int waiting; + int signals; + SDL_sem *wait_sem; + SDL_sem *wait_done; +}; + +/* Create a condition variable */ +SDL_cond * SDL_CreateCond(void) +{ + SDL_cond *cond; + + cond = (SDL_cond *) malloc(sizeof(SDL_cond)); + if ( cond ) { + cond->lock = SDL_CreateMutex(); + cond->wait_sem = SDL_CreateSemaphore(0); + cond->wait_done = SDL_CreateSemaphore(0); + cond->waiting = cond->signals = 0; + if ( ! cond->lock || ! cond->wait_sem || ! cond->wait_done ) { + SDL_DestroyCond(cond); + cond = NULL; + } + } else { + SDL_OutOfMemory(); + } + return(cond); +} + +/* Destroy a condition variable */ +void SDL_DestroyCond(SDL_cond *cond) +{ + if ( cond ) { + if ( cond->wait_sem ) { + SDL_DestroySemaphore(cond->wait_sem); + } + if ( cond->wait_done ) { + SDL_DestroySemaphore(cond->wait_done); + } + if ( cond->lock ) { + SDL_DestroyMutex(cond->lock); + } + free(cond); + } +} + +/* Restart one of the threads that are waiting on the condition variable */ +int SDL_CondSignal(SDL_cond *cond) +{ + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if ( cond->waiting > cond->signals ) { + ++cond->signals; + SDL_SemPost(cond->wait_sem); + SDL_UnlockMutex(cond->lock); + SDL_SemWait(cond->wait_done); + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Restart all threads that are waiting on the condition variable */ +int SDL_CondBroadcast(SDL_cond *cond) +{ + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if ( cond->waiting > cond->signals ) { + int i, num_waiting; + + num_waiting = (cond->waiting - cond->signals); + cond->signals = cond->waiting; + for ( i=0; iwait_sem); + } + /* Now all released threads are blocked here, waiting for us. + Collect them all (and win fabulous prizes!) :-) + */ + SDL_UnlockMutex(cond->lock); + for ( i=0; iwait_done); + } + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Wait on the condition variable for at most 'ms' milliseconds. + The mutex must be locked before entering this function! + The mutex is unlocked during the wait, and locked again after the wait. + +Typical use: + +Thread A: + SDL_LockMutex(lock); + while ( ! condition ) { + SDL_CondWait(cond); + } + SDL_UnlockMutex(lock); + +Thread B: + SDL_LockMutex(lock); + ... + condition = true; + ... + SDL_UnlockMutex(lock); + */ +int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) +{ + int retval; + + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* Obtain the protection mutex, and increment the number of waiters. + This allows the signal mechanism to only perform a signal if there + are waiting threads. + */ + SDL_LockMutex(cond->lock); + ++cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Unlock the mutex, as is required by condition variable semantics */ + SDL_UnlockMutex(mutex); + + /* Wait for a signal */ + if ( ms == SDL_MUTEX_MAXWAIT ) { + retval = SDL_SemWait(cond->wait_sem); + } else { + retval = SDL_SemWaitTimeout(cond->wait_sem, ms); + } + + /* Let the signaler know we have completed the wait, otherwise + the signaler can race ahead and get the condition semaphore + if we are stopped between the mutex unlock and semaphore wait, + giving a deadlock. See the following URL for details: + http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html + */ + SDL_LockMutex(cond->lock); + if ( cond->signals > 0 ) { + /* If we timed out, we need to eat a condition signal */ + if ( retval > 0 ) { + SDL_SemWait(cond->wait_sem); + } + /* We always notify the signal thread that we are done */ + SDL_SemPost(cond->wait_done); + + /* Signal handshake complete */ + --cond->signals; + } + --cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Lock the mutex, as is required by condition variable semantics */ + SDL_LockMutex(mutex); + + return retval; +} + +/* Wait on the condition variable forever */ +int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) +{ + return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); +} diff --git a/src/thread/nds/SDL_syscond_c.h b/src/thread/nds/SDL_syscond_c.h new file mode 100644 index 000000000..7983e5e61 --- /dev/null +++ b/src/thread/nds/SDL_syscond_c.h @@ -0,0 +1,27 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_syscond_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + diff --git a/src/thread/nds/SDL_sysmutex.c b/src/thread/nds/SDL_sysmutex.c new file mode 100644 index 000000000..a32dfe53d --- /dev/null +++ b/src/thread/nds/SDL_sysmutex.c @@ -0,0 +1,137 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysmutex.c,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* An implementation of mutexes using semaphores */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + + +struct SDL_mutex { + int recursive; + Uint32 owner; + SDL_sem *sem; +}; + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + SDL_mutex *mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *)malloc(sizeof(*mutex)); + if ( mutex ) { + /* Create the mutex semaphore, with initial value 1 */ + mutex->sem = SDL_CreateSemaphore(1); + mutex->recursive = 0; + mutex->owner = 0; + if ( ! mutex->sem ) { + free(mutex); + mutex = NULL; + } + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if ( mutex ) { + if ( mutex->sem ) { + SDL_DestroySemaphore(mutex->sem); + } + free(mutex); + } +} + +/* Lock the semaphore */ +int SDL_mutexP(SDL_mutex *mutex) +{ +#ifdef DISABLE_THREADS + return 0; +#else + Uint32 this_thread; + + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + this_thread = SDL_ThreadID(); + if ( mutex->owner == this_thread ) { + ++mutex->recursive; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + SDL_SemWait(mutex->sem); + mutex->owner = this_thread; + mutex->recursive = 0; + } + + return 0; +#endif /* DISABLE_THREADS */ +} + +/* Unlock the mutex */ +int SDL_mutexV(SDL_mutex *mutex) +{ +#ifdef DISABLE_THREADS + return 0; +#else + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + /* If we don't own the mutex, we can't unlock it */ + if ( SDL_ThreadID() != mutex->owner ) { + SDL_SetError("mutex not owned by this thread"); + return -1; + } + + if ( mutex->recursive ) { + --mutex->recursive; + } else { + /* The order of operations is important. + First reset the owner so another thread doesn't lock + the mutex and set the ownership before we reset it, + then release the lock semaphore. + */ + mutex->owner = 0; + SDL_SemPost(mutex->sem); + } + return 0; +#endif /* DISABLE_THREADS */ +} diff --git a/src/thread/nds/SDL_sysmutex_c.h b/src/thread/nds/SDL_sysmutex_c.h new file mode 100644 index 000000000..56fb092a5 --- /dev/null +++ b/src/thread/nds/SDL_sysmutex_c.h @@ -0,0 +1,27 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysmutex_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + diff --git a/src/thread/nds/SDL_syssem.c b/src/thread/nds/SDL_syssem.c new file mode 100644 index 000000000..ad6fe6a98 --- /dev/null +++ b/src/thread/nds/SDL_syssem.c @@ -0,0 +1,214 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_syssem.c,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* An implementation of semaphores using mutexes and condition variables */ + +#include + +#include "SDL_error.h" +#include "SDL_timer.h" +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + + +#ifdef DISABLE_THREADS + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_SetError("SDL not configured with thread support"); + return (SDL_sem *)0; +} + +void SDL_DestroySemaphore(SDL_sem *sem) +{ + return; +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +int SDL_SemWait(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + return 0; +} + +int SDL_SemPost(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +#else + +struct SDL_semaphore +{ + Uint32 count; + Uint32 waiters_count; + SDL_mutex *count_lock; + SDL_cond *count_nonzero; +}; + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem *sem; + + sem = (SDL_sem *)malloc(sizeof(*sem)); + if ( ! sem ) { + SDL_OutOfMemory(); + return(0); + } + sem->count = initial_value; + sem->waiters_count = 0; + + sem->count_lock = SDL_CreateMutex(); + sem->count_nonzero = SDL_CreateCond(); + if ( ! sem->count_lock || ! sem->count_nonzero ) { + SDL_DestroySemaphore(sem); + return(0); + } + + return(sem); +} + +/* WARNING: + You cannot call this function when another thread is using the semaphore. +*/ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if ( sem ) { + sem->count = 0xFFFFFFFF; + while ( sem->waiters_count > 0) { + SDL_CondSignal(sem->count_nonzero); + SDL_Delay(10); + } + SDL_DestroyCond(sem->count_nonzero); + SDL_mutexP(sem->count_lock); + SDL_mutexV(sem->count_lock); + SDL_DestroyMutex(sem->count_lock); + free(sem); + } +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + int retval; + + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + retval = SDL_MUTEX_TIMEDOUT; + SDL_LockMutex(sem->count_lock); + if ( sem->count > 0 ) { + --sem->count; + retval = 0; + } + SDL_UnlockMutex(sem->count_lock); + + return retval; +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + int retval; + + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + /* A timeout of 0 is an easy case */ + if ( timeout == 0 ) { + return SDL_SemTryWait(sem); + } + + SDL_LockMutex(sem->count_lock); + ++sem->waiters_count; + retval = 0; + while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) { + retval = SDL_CondWaitTimeout(sem->count_nonzero, + sem->count_lock, timeout); + } + --sem->waiters_count; + --sem->count; + SDL_UnlockMutex(sem->count_lock); + + return retval; +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + Uint32 value; + + value = 0; + if ( sem ) { + SDL_LockMutex(sem->count_lock); + value = sem->count; + SDL_UnlockMutex(sem->count_lock); + } + return value; +} + +int SDL_SemPost(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + SDL_LockMutex(sem->count_lock); + if ( sem->waiters_count > 0 ) { + SDL_CondSignal(sem->count_nonzero); + } + ++sem->count; + SDL_UnlockMutex(sem->count_lock); + + return 0; +} + +#endif /* DISABLE_THREADS */ diff --git a/src/thread/nds/SDL_syssem_c.h b/src/thread/nds/SDL_syssem_c.h new file mode 100644 index 000000000..7eaa2a3d6 --- /dev/null +++ b/src/thread/nds/SDL_syssem_c.h @@ -0,0 +1,27 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_syssem_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + diff --git a/src/thread/nds/SDL_systhread.c b/src/thread/nds/SDL_systhread.c new file mode 100644 index 000000000..4c4c4d452 --- /dev/null +++ b/src/thread/nds/SDL_systhread.c @@ -0,0 +1,59 @@ +/* + 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 +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_systhread.c,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Thread management routines for SDL */ + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_systhread.h" + +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) +{ + SDL_SetError("Threads are not supported on this platform"); + return(-1); +} + +void SDL_SYS_SetupThread(void) +{ + return; +} + +Uint32 SDL_ThreadID(void) +{ + return(0); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + return; +} + +void SDL_SYS_KillThread(SDL_Thread *thread) +{ + return; +} + diff --git a/src/thread/nds/SDL_systhread_c.h b/src/thread/nds/SDL_systhread_c.h new file mode 100644 index 000000000..c6fe446a6 --- /dev/null +++ b/src/thread/nds/SDL_systhread_c.h @@ -0,0 +1,28 @@ +/* + 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 +*/ + +/* Stub until we implement threads on this platform */ +typedef int SYS_ThreadHandle; + +#ifndef DISABLE_THREADS +#define DISABLE_THREADS +#endif diff --git a/src/video/nds/SDL_ndsevents.c b/src/video/nds/SDL_ndsevents.c new file mode 100644 index 000000000..c72ac1525 --- /dev/null +++ b/src/video/nds/SDL_ndsevents.c @@ -0,0 +1,44 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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" + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include +#include +#include + +#include "SDL.h" +#include "../../events/SDL_sysevents.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_ndsvideo.h" +#include "SDL_ndsevents_c.h" + +void +NDS_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/nds/SDL_ndsevents_c.h b/src/video/nds/SDL_ndsevents_c.h new file mode 100644 index 000000000..03ff73518 --- /dev/null +++ b/src/video/nds/SDL_ndsevents_c.h @@ -0,0 +1,28 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_ndsvideo.h" + +extern void NDS_PumpEvents(_THIS); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/nds/SDL_ndsrender.c b/src/video/nds/SDL_ndsrender.c new file mode 100644 index 000000000..e73a9923a --- /dev/null +++ b/src/video/nds/SDL_ndsrender.c @@ -0,0 +1,285 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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 +#include +#include + +#include "SDL_config.h" + +#include "SDL_video.h" +#include "../SDL_sysvideo.h" +#include "../SDL_yuv_sw_c.h" +#include "../SDL_renderer_sw.h" + + +/* SDL surface based renderer implementation */ + +static SDL_Renderer *SDL_NDS_CreateRenderer(SDL_Window * window, + Uint32 flags); +static int SDL_NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, + Uint8 b, Uint8 a, const SDL_Rect * rect); +static int SDL_NDS_RenderCopy(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); +static void SDL_NDS_RenderPresent(SDL_Renderer * renderer); +static void SDL_NDS_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver SDL_NDS_RenderDriver = { + SDL_NDS_CreateRenderer, + { "nds", SDL_RENDERER_PRESENTCOPY } +/* (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | + SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | + SDL_RENDERER_PRESENTDISCARD),*/ +}; + +typedef struct +{ + int current_screen; + SDL_Surface *screens[3]; + int ultimate_answer; +} SDL_NDS_RenderData; + +SDL_Renderer * +SDL_NDS_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); + SDL_DisplayMode *displayMode = &display->current_mode; + SDL_Renderer *renderer; + SDL_NDS_RenderData *data; + int i, n; + int bpp = 16; + Uint32 Rmask = 0x7C00, Gmask = 0x03E0, Bmask = 0x001F, Amask = 0x8000; + + printf("SDL_NDS_CreateRenderer(window, 0x%x)\n", flags); + printf(" window: (%d,%d), %dx%d\n", window->x, window->y, window->w, window->h); + + /* hard coded this to ARGB1555 for now + if (!SDL_PixelFormatEnumToMasks + (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + SDL_SetError("Unknown display format"); + return NULL; + }*/ + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (SDL_NDS_RenderData *) SDL_malloc(sizeof(*data)); + if (!data) { + SDL_NDS_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + SDL_zerop(data); + + renderer->RenderFill = SDL_NDS_RenderFill; + renderer->RenderCopy = SDL_NDS_RenderCopy; + renderer->RenderPresent = SDL_NDS_RenderPresent; + renderer->DestroyRenderer = SDL_NDS_DestroyRenderer; + renderer->info.name = SDL_NDS_RenderDriver.info.name; + renderer->info.flags = 0; + renderer->window = window->id; + renderer->driverdata = data; + Setup_SoftwareRenderer(renderer); + + if (flags & SDL_RENDERER_PRESENTFLIP2) { + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; + n = 2; + } else if (flags & SDL_RENDERER_PRESENTFLIP3) { + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; + n = 3; + } else { + renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; + n = 1; + } + for (i = 0; i < n; ++i) { + data->screens[i] = + SDL_CreateRGBSurface(0, 256, 192, bpp, Rmask, Gmask, Bmask, Amask); + if (!data->screens[i]) { + SDL_NDS_DestroyRenderer(renderer); + return NULL; + } + SDL_SetSurfacePalette(data->screens[i], display->palette); + } + + data->current_screen = 0; + data->ultimate_answer = 42; +#if 0 +#define blarg (data->screens[0]) + printf("hello?\n"); + if(!data || !(data->screens) || !blarg) { + printf("they're null.\n"); + } else { + printf("not null.\n"); + printf("%d\n%d\n%d\n%d\n%x\n%x\n%x\n%x\n", + blarg->w, blarg->h, blarg->pitch, + blarg->format->BitsPerPixel, + blarg->format->Rmask, + blarg->format->Gmask, + blarg->format->Bmask, + (u32)(blarg->pixels)); /* ARGH WHY DOESN'T THIS PRINT AT ALL? */ + printf("hurr\n"); + } +#undef blarg +#endif + return renderer; +} + +static int +SDL_NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, + Uint8 a, const SDL_Rect * rect) +{ + SDL_NDS_RenderData *data = (SDL_NDS_RenderData *) renderer->driverdata; + SDL_Surface *target = data->screens[data->current_screen]; + Uint32 color; + SDL_Rect real_rect = *rect; + + color = SDL_MapRGBA(target->format, r, g, b, a); + + return SDL_FillRect(target, &real_rect, color); +} + +/* this is mainly for testing stuff to put a surface where I can see it */ +void sdlds_surf2vram(SDL_Surface *s) { + int i; + for(i = 0; i < 256*192; ++i) { + ((u16*)VRAM_A)[i] = ((u16*)(s->pixels))[i]; + } +} + +static int +SDL_NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect) +{ + SDL_NDS_RenderData *data = + (SDL_NDS_RenderData *) renderer->driverdata; + SDL_Window *window = SDL_GetWindowFromID(renderer->window); + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); + printf("SDL_NDS_RenderCopy(renderer, texture, srcrect, dstrect)\n"); + printf(" renderer: %s\n", renderer->info.name); + printf(" texture: %dx%d\n", texture->w, texture->h); + printf(" srcrect: (%d,%d), %dx%d\n", srcrect->x, srcrect->y, srcrect->w, srcrect->h); + printf(" dstrect: (%d,%d), %dx%d\n", dstrect->x, dstrect->y, dstrect->w, dstrect->h); + + if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { + SDL_Surface *target = data->screens[data->current_screen]; + void *pixels = + (Uint8 *) target->pixels + dstrect->y * target->pitch + + dstrect->x * target->format->BytesPerPixel; + return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata, + srcrect, display->current_mode.format, + dstrect->w, dstrect->h, pixels, + target->pitch); + } else { + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + SDL_Surface *target = data->screens[data->current_screen]; + SDL_Rect real_srcrect = *srcrect; + SDL_Rect real_dstrect = *dstrect; + printf("Rmask %x Gmask %x Bmask %x Amask %x\n" + "width %d, height %d, pitch %d\nbpp %d, pixels %x\n", + surface->format->Rmask, surface->format->Gmask, + surface->format->Bmask, surface->format->Amask, + surface->w, surface->h, surface->pitch, + surface->format->BitsPerPixel, (u32)(surface->pixels)); + sdlds_surf2vram(surface); + return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect); + } +#if 0 +/* previous attempt to copy it directly to vram */ + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + int sx = srcrect->x, sy = srcrect->y, sw = srcrect->w, sh = srcrect->h; + int dx = dstrect->x, dy = dstrect->y, dw = dstrect->w, dh = dstrect->h; + int si,sj, di,dj; + /*printf("DEBUG: still alive!\n");*/ + for(sj=0, dj=0; sjpixels)[(sj+sy)*(surface->w) + si+sx]; + } + } + /*printf("DEBUG: still alive!\n");*/ + } + return 0; +#endif +} + +static void +SDL_NDS_RenderPresent(SDL_Renderer * renderer) +{ + SDL_NDS_RenderData *data = + (SDL_NDS_RenderData *) renderer->driverdata; + + printf("SDL_NDS_RenderPresent(renderer)\n"); + printf(" renderer: %s\n", renderer->info.name); + /* Send the data to the display */ + +#if 0 +/*testing to see if rectangles drawn get copied right*/ + { + SDL_Rect ra; + ra.x=0; ra.y=0; ra.w=256; ra.h=192; + SDL_FillRect(data->screens[data->current_screen], &ra, 0x250); + ra.x=32; ra.y=32; ra.w=192; ra.h=128; + SDL_FillRect(data->screens[data->current_screen], &ra, + SDL_MapRGBA(data->screens[data->current_screen]->format, + 255,255,255,255)); + } +/*okay so this works but why not when I do it in the main()? + for some reason the screen I get from screen=SDL_SetVideoMode(...) + doesn't get copied to renderer->driverdata? */ + for(i = 0; i < 30; ++i) swiWaitForVBlank(); /* delay for debug purpose */ +#endif + sdlds_surf2vram(data->screens[data->current_screen]); + + /* Update the flipping chain, if any */ + if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { + data->current_screen = (data->current_screen + 1) % 2; + } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) { + data->current_screen = (data->current_screen + 1) % 3; + } +} + +static void +SDL_NDS_DestroyRenderer(SDL_Renderer * renderer) +{ + SDL_NDS_RenderData *data = (SDL_NDS_RenderData *) renderer->driverdata; + int i; + + printf("SDL_NDS_DestroyRenderer(renderer)\n"); + printf(" renderer: %s\n", renderer->info.name); + if (data) { + for (i = 0; i < SDL_arraysize(data->screens); ++i) { + if (data->screens[i]) { + SDL_FreeSurface(data->screens[i]); + } + } + SDL_free(data); + } + SDL_free(renderer); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/nds/SDL_ndsrender_c.h b/src/video/nds/SDL_ndsrender_c.h new file mode 100644 index 000000000..9ab960775 --- /dev/null +++ b/src/video/nds/SDL_ndsrender_c.h @@ -0,0 +1,28 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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" + +/* SDL surface based renderer implementation */ + +extern SDL_RenderDriver SDL_NDS_RenderDriver; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/nds/SDL_ndsvideo.c b/src/video/nds/SDL_ndsvideo.c new file mode 100644 index 000000000..86041e116 --- /dev/null +++ b/src/video/nds/SDL_ndsvideo.c @@ -0,0 +1,174 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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" + +/* Dummy SDL video driver implementation; this is just enough to make an + * SDL-based application THINK it's got a working video driver, for + * applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it, + * and also for use as a collection of stubs when porting SDL to a new + * platform for which you haven't yet written a valid video driver. + * + * This is also a great way to determine bottlenecks: if you think that SDL + * is a performance problem for a given platform, enable this driver, and + * then see if your application runs faster without video overhead. + * + * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion + * of this was cut-and-pasted from Stephane Peter's work in the AAlib + * SDL video driver. Renamed to "DUMMY" by Sam Lantinga. + */ + +#include +#include +#include + +#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_ndsvideo.h" +#include "SDL_ndsevents_c.h" +#include "SDL_ndsrender_c.h" + +#define NDSVID_DRIVER_NAME "nds" + +/* Initialization/Query functions */ +static int NDS_VideoInit(_THIS); +static int NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode); +static void NDS_VideoQuit(_THIS); + +/* DUMMY driver bootstrap functions */ + +static int +NDS_Available(void) +{ + const char *envr = SDL_getenv("SDL_VIDEODRIVER"); + printf("NDS_Available()\n"); + return (1); +} + +static void +NDS_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_free(device); +} + +static SDL_VideoDevice * +NDS_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + printf("NDS_CreateDevice(%d)\n", devindex); + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + if (device) { + SDL_free(device); + } + return (0); + } + + /* Set the function pointers */ + device->VideoInit = NDS_VideoInit; + device->VideoQuit = NDS_VideoQuit; + device->SetDisplayMode = NDS_SetDisplayMode; + device->PumpEvents = NDS_PumpEvents; + + device->num_displays = 2; /* DS = dual screens */ + + device->free = NDS_DeleteDevice; + + return device; +} + +VideoBootStrap NDS_bootstrap = { + NDSVID_DRIVER_NAME, "SDL NDS video driver", + NDS_Available, NDS_CreateDevice +}; + +int +NDS_VideoInit(_THIS) +{ + SDL_DisplayMode mode; + int i; + + /* simple 256x192x16x60 for now */ + mode.w = 256; mode.h = 192; + mode.format = SDL_PIXELFORMAT_ARGB1555; + mode.refresh_rate = 60; + mode.driverdata = NULL; + + SDL_AddBasicVideoDisplay(&mode); + SDL_AddRenderDriver(0, &SDL_NDS_RenderDriver); + + SDL_zero(mode); + SDL_AddDisplayMode(0, &mode); + + /* hackish stuff to get things up and running for now, and for a console */ + powerON(POWER_ALL); + videoSetMode(MODE_FB0); + videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); /* debug text on sub */ + vramSetBankA(VRAM_A_LCD); + vramSetBankC(VRAM_C_SUB_BG); + irqInit(); + irqEnable(IRQ_VBLANK); + /* set up console for debug text 'n stuff */ + SUB_BG0_CR = BG_MAP_BASE(31); BG_PALETTE_SUB[255] = RGB15(31,31,31); + consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), + (u16*)CHAR_BASE_BLOCK_SUB(0), 16); + for(i = 0; i < 256*192; ++i) { + ((u16*)VRAM_A)[i] = i; + } + for(i = 0; i < 60; ++i) swiWaitForVBlank(); + /*NDS_SetDisplayMode(_this, &mode);*/ + return 0; +} + +static int +NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode) +{ + /* right now this function is just hard-coded for 256x192 ARGB1555 */ +#if 0 + videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE); /* display on main core */ + videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); /* debug text on sub */ + vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_LCD, + VRAM_C_SUB_BG, VRAM_D_LCD); + + /* maps well to the 256x192 screen anyway. note: need VRAM_B for bigger */ + BG3_CR = BG_BMP16_256x256; + /* affine transformation matrix. nothing too fancy here */ + BG3_XDX = 0x100; BG3_XDY = 0; + BG3_YDX = 0; BG3_YDY = 0x100; + /* x/y position */ + BG3_CX = 0; BG3_CY = 0; +#endif + return 0; +} + +void +NDS_VideoQuit(_THIS) +{ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/nds/SDL_ndsvideo.h b/src/video/nds/SDL_ndsvideo.h new file mode 100644 index 000000000..bbd32228f --- /dev/null +++ b/src/video/nds/SDL_ndsvideo.h @@ -0,0 +1,31 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_ndsvideo_h +#define _SDL_ndsvideo_h + +#include "../SDL_sysvideo.h" + +#endif /* _SDL_ndsvideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */