Frank Zago to SDL
authorSam Lantinga <slouken@libsdl.org>
Sun, 13 Feb 2011 14:01:02 -0800
changeset 5289 1916a9e9714d
parent 5288 d4381f3b0d1e
child 5290 25af68c1901d
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
README.ds
src/atomic/SDL_spinlock.c
src/render/SDL_render.c
src/video/nds/SDL_ndsvideo.c
--- a/Makefile.ds	Sun Feb 13 13:46:10 2011 -0800
+++ b/Makefile.ds	Sun Feb 13 14:01:02 2011 -0800
@@ -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=<path to>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=<path to>devkitPro")
+endif
+ifeq ($(strip $(DEVKITARM)),)
 DEVKITARM = $(DEVKITPRO)/devkitARM
-endif
+endif
 PATH := $(PATH):$(DEVKITARM)/bin
 
 CC = arm-eabi-gcc
@@ -40,6 +40,7 @@
 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 @@
 
 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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.ds	Sun Feb 13 14:01:02 2011 -0800
@@ -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.
--- a/src/atomic/SDL_spinlock.c	Sun Feb 13 13:46:10 2011 -0800
+++ b/src/atomic/SDL_spinlock.c	Sun Feb 13 14:01:02 2011 -0800
@@ -62,7 +62,7 @@
 #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"
--- a/src/render/SDL_render.c	Sun Feb 13 13:46:10 2011 -0800
+++ b/src/render/SDL_render.c	Sun Feb 13 14:01:02 2011 -0800
@@ -60,9 +60,6 @@
 #if SDL_VIDEO_RENDER_DIRECTFB
     &DirectFB_RenderDriver,
 #endif
-#if SDL_VIDEO_RENDER_NDS
-	&NDS_RenderDriver,
-#endif
     &SW_RenderDriver
 #endif /* !SDL_RENDER_DISABLED */
 };
--- a/src/video/nds/SDL_ndsvideo.c	Sun Feb 13 13:46:10 2011 -0800
+++ b/src/video/nds/SDL_ndsvideo.c	Sun Feb 13 14:01:02 2011 -0800
@@ -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 @@
     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,17 +196,27 @@
     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;
+    }
+
     /* Set the function pointers */
     device->VideoInit = NDS_VideoInit;
     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 */