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.
--- 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 */