From c3d6b3c7afed9189acc3e2397ad96cf6fc2a08a7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 13 Feb 2011 14:01:02 -0800 Subject: [PATCH] Frank Zago to SDL On 02/12/2011 01:44 PM, Sam Lantinga wrote: > BTW, you probably want to nuke the NDS renderer and just implement these three > functions instead: > int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * > format, void ** pixels, int *pitch); > int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, int numrects, > SDL_Rect * rects); > void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window); Patch attached. The renderer for the DS is not used anymore, but I left the file in place if someone wants to finish it. I've also added a README.ds and fixed the spinlocks. --- Makefile.ds | 21 +++-- README.ds | 19 +++++ src/atomic/SDL_spinlock.c | 2 +- src/render/SDL_render.c | 3 - src/video/nds/SDL_ndsvideo.c | 147 +++++++++++++++++++++++++++++++++-- 5 files changed, 173 insertions(+), 19 deletions(-) create mode 100644 README.ds diff --git a/Makefile.ds b/Makefile.ds index 7e408fc9c..1fa79b661 100644 --- a/Makefile.ds +++ b/Makefile.ds @@ -1,13 +1,13 @@ -#LibSDL 1.3 porting and enhancements by Darren Alton (lifning) -#LibSDL 1.2.9 DS porting by Troy Davis(GPF) - -ifeq ($(strip $(DEVKITPRO)),) -$(error "Please set DEVKITPRO in your environment (available from http://www.devkitpro.org). export DEVKITPRO=devkitPro") -endif -ifeq ($(strip $(DEVKITARM)),) +#LibSDL 1.3 porting and enhancements by Darren Alton (lifning) +#LibSDL 1.2.9 DS porting by Troy Davis(GPF) + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment (available from http://www.devkitpro.org). export DEVKITPRO=devkitPro") +endif +ifeq ($(strip $(DEVKITARM)),) DEVKITARM = $(DEVKITPRO)/devkitARM -endif +endif PATH := $(PATH):$(DEVKITARM)/bin CC = arm-eabi-gcc @@ -40,6 +40,7 @@ src/SDL_fatal.c \ src/SDL_hints.c \ src/SDL_log.c \ src/atomic/SDL_atomic.c \ +src/atomic/SDL_spinlock.c \ src/audio/SDL_audio.c \ src/audio/SDL_audiocvt.c \ src/audio/SDL_audiodev.c \ @@ -118,6 +119,10 @@ test/nds-test-progs/sprite2/sprite2.nds \ all: $(TARGET) install nds_test +# That file must be compiled in arm mode, not thumb mode. +src/atomic/SDL_spinlock.o: src/atomic/SDL_spinlock.c + $(CC) $(CFLAGS) -mno-thumb -o $@ -c $^ + $(TARGET): copy_config \ $(OBJS) $(AR) rc $(TARGET) $(OBJS) diff --git a/README.ds b/README.ds new file mode 100644 index 000000000..2118620b6 --- /dev/null +++ b/README.ds @@ -0,0 +1,19 @@ +================================================================================ +Simple DirectMedia Layer for Nintendo DS +================================================================================ + +-Requirements- +The devkitpro SDK available at http://devkitpro.org. +Read the information at http://devkitpro.org/wiki/Getting_Started/devkitARM +The necessary packages are devkitARM, libnds and default arm7. + +-Building SDL- +After setting the devkitpro environment, type: + make -f Makefile.ds + +This will compile and install the library and headers into the proper libnds directories. +Additionnaly it will compile the general test, that you can run either on the DS or with desmume: + desmume test/nds-test-progs/general/general.nds + + +Note that the port is very basic and incomplete. diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index 6380bcf4f..151686076 100644 --- a/src/atomic/SDL_spinlock.c +++ b/src/atomic/SDL_spinlock.c @@ -62,7 +62,7 @@ SDL_AtomicTryLock(SDL_SpinLock *lock) #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET return (__sync_lock_test_and_set(lock, 1) == 0); -#elif defined(__GNUC__) && defined(__arm__) && defined(__ARM_ARCH_5__) +#elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__)) int result; __asm__ __volatile__ ( "swp %0, %1, [%2]\n" diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 09f97b448..2ff7a10da 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -59,9 +59,6 @@ static const SDL_RenderDriver *render_drivers[] = { #endif #if SDL_VIDEO_RENDER_DIRECTFB &DirectFB_RenderDriver, -#endif -#if SDL_VIDEO_RENDER_NDS - &NDS_RenderDriver, #endif &SW_RenderDriver #endif /* !SDL_RENDER_DISABLED */ diff --git a/src/video/nds/SDL_ndsvideo.c b/src/video/nds/SDL_ndsvideo.c index 9eaca2111..9e0cd2244 100644 --- a/src/video/nds/SDL_ndsvideo.c +++ b/src/video/nds/SDL_ndsvideo.c @@ -35,18 +35,37 @@ #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_sysvideo.h" +#include "SDL_pixels_c.h" +#include "SDL_events_c.h" #include "SDL_render.h" -#include "../../render/SDL_sysrender.h" - #include "SDL_ndsvideo.h" #include "SDL_ndsevents_c.h" -#include "SDL_ndsrender_c.h" #define NDSVID_DRIVER_NAME "nds" +/* Per Window information. */ +struct NDS_WindowData { + int hw_index; /* index of sprite in OAM or bg from libnds */ + int bg; /* which bg is that attached to (2 or 3) */ + int pitch, bpp; /* useful information about the texture */ + struct { + int x, y; + } scale; /* x/y stretch (24.8 fixed point) */ + struct { + int x, y; + } scroll; /* x/y offset */ + int rotate; /* -32768 to 32767, texture rotation */ + u16 *vram_pixels; /* where the pixel data is stored (a pointer into VRAM) */ +}; + +/* Per device information. */ +struct NDS_DeviceData { + int has_bg2; /* backgroud 2 has been attached */ + int has_bg3; /* backgroud 3 has been attached */ + int sub; +}; + /* Initialization/Query functions */ static int NDS_VideoInit(_THIS); static int NDS_SetDisplayMode(_THIS, SDL_VideoDisplay *display, @@ -61,6 +80,110 @@ NDS_Available(void) return (1); /* always here */ } +static int NDS_CreateWindowFramebuffer(_THIS, SDL_Window * window, + Uint32 * format, void ** pixels, + int *pitch) +{ + struct NDS_DeviceData *data = _this->driverdata; + struct NDS_WindowData *wdata; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + int whichbg = -1; + + *format = SDL_PIXELFORMAT_BGR555; + + if (!SDL_PixelFormatEnumToMasks + (*format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + SDL_SetError("Unknown texture format"); + return -1; + } + + if (!data->has_bg2) + whichbg = 2; + else if (!data->has_bg3) + whichbg = 3; + else { + SDL_SetError("Out of NDS backgrounds."); + return -1; + } + + wdata = SDL_calloc(1, sizeof(struct NDS_WindowData)); + if (!wdata) { + SDL_OutOfMemory(); + return -1; + } + + if (!data->sub) { + if (bpp == 8) { + wdata->hw_index = + bgInit(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0); + } else { + wdata->hw_index = + bgInit(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0, + 0); + } + } else { + if (bpp == 8) { + wdata->hw_index = + bgInitSub(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, + 0); + } else { + wdata->hw_index = + bgInitSub(whichbg, BgType_Bmp16, BgSize_B16_256x256, + 0, 0); + } + } + + wdata->bg = whichbg; + wdata->pitch = (window->w) * ((bpp+1) / 8); + wdata->bpp = bpp; + wdata->rotate = 0; + wdata->scale.x = 0x100; + wdata->scale.y = 0x100; + wdata->scroll.x = 0; + wdata->scroll.y = 0; + wdata->vram_pixels = (u16 *) bgGetGfxPtr(wdata->hw_index); + + bgSetCenter(wdata->hw_index, 0, 0); + bgSetRotateScale(wdata->hw_index, wdata->rotate, wdata->scale.x, + wdata->scale.y); + bgSetScroll(wdata->hw_index, wdata->scroll.x, wdata->scroll.y); + bgUpdate(); + + *pixels = wdata->vram_pixels; + *pitch = wdata->pitch; + + if (!data->has_bg2) + data->has_bg2 = 1; + else + data->has_bg3 = 1; + + window->driverdata = wdata; + + return 0; +} + +static int NDS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, int numrects, + SDL_Rect * rects) +{ + /* Nothing to do because writes are done directly into the + * framebuffer. */ + return 0; +} + +static void NDS_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + struct NDS_DeviceData *data = _this->driverdata; + struct NDS_WindowData *wdata = window->driverdata; + + if (wdata->bg == 2) + data->has_bg2 = 0; + else + data->has_bg3 = 0; + + SDL_free(wdata); +} + static void NDS_DeleteDevice(SDL_VideoDevice * device) { @@ -73,8 +196,15 @@ NDS_CreateDevice(int devindex) SDL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + device = SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return NULL; + } + + device->driverdata = SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { + SDL_free(device); SDL_OutOfMemory(); return NULL; } @@ -84,6 +214,9 @@ NDS_CreateDevice(int devindex) device->VideoQuit = NDS_VideoQuit; device->SetDisplayMode = NDS_SetDisplayMode; device->PumpEvents = NDS_PumpEvents; + device->CreateWindowFramebuffer = NDS_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = NDS_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = NDS_DestroyWindowFramebuffer; device->num_displays = 2; /* DS = dual screens */