a Nintendo ds update
authorSam Lantinga
Sun, 06 Mar 2011 21:12:19 -0800
changeset 5423b69fa50e80d7
parent 5422 8e46c54a04d4
child 5424 2a206577656f
a Nintendo ds update

Frank Zago to SDL

For those interested, here's a snapshot of the current port. I did away with
most of the previous attempt which was based of the sprite engine, because the
support is limited to 128 64x64 sprites. Instead I'm using the gl engine.
The drawback is that either the frame buffer or the gl engine can be used
because there's not that much video memory on a DS.

With minimal changes to their code, it can now run the following tests: ,
testspriteminimal, testscale and testsprite2. The last 2 only run under the
emulator for some reason. The tests are not included in this patch for size
reason.

In 16 bits mode, the 16th bit indicated transparency/opacity. If 0, the color
is not displayed. So I had to patch a few core file to set that bit to 1. See
patch for src/video/SDL_RLEaccel.c and src/video/SDL_blit.h. Is that ok, or is
there a better way ?

The nds also doesn't support windowed mode, so I force the fullscreen in
src/video/SDL_video.c. Is that ok, or is there a better way ?

To get a smaller library, I also tried to not compile the software renderer
when the hardware renderer is compiled in, and define SDL_NO_COMPAT; however
the compilation eventually fails in SDL_surface.c because SDL_SRCCOLORKEY is
defined in SDL_compat.h. Is SDL_NO_COMPAT only for application and not SDL
itself ?
Makefile.ds
README.ds
include/SDL_config_nintendods.h
src/render/SDL_render.c
src/render/SDL_sysrender.h
src/render/nds/SDL_ndsrender.c
src/video/SDL_RLEaccel.c
src/video/SDL_blit.h
src/video/SDL_video.c
src/video/nds/SDL_ndsrender.c
src/video/nds/SDL_ndsrender_c.h
src/video/nds/SDL_ndsvideo.c
src/video/nds/SDL_ndsvideo.h
     1.1 --- a/Makefile.ds	Sat Mar 05 10:03:57 2011 -0800
     1.2 +++ b/Makefile.ds	Sun Mar 06 21:12:19 2011 -0800
     1.3 @@ -1,140 +1,236 @@
     1.4 -
     1.5 -#LibSDL 1.3 porting and enhancements by Darren Alton (lifning)
     1.6 -#LibSDL 1.2.9 DS porting by Troy Davis(GPF)
     1.7 +#---------------------------------------------------------------------------------
     1.8 +.SUFFIXES:
     1.9 +#---------------------------------------------------------------------------------
    1.10  
    1.11 -ifeq ($(strip $(DEVKITPRO)),)
    1.12 -$(error "Please set DEVKITPRO in your environment (available from http://www.devkitpro.org). export DEVKITPRO=<path to>devkitPro")
    1.13 -endif
    1.14  ifeq ($(strip $(DEVKITARM)),)
    1.15 -DEVKITARM = $(DEVKITPRO)/devkitARM
    1.16 +$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
    1.17  endif
    1.18 -PATH := $(PATH):$(DEVKITARM)/bin
    1.19 +
    1.20 +include $(DEVKITARM)/ds_rules
    1.21  
    1.22 -CC = arm-eabi-gcc
    1.23 -AR = arm-eabi-ar
    1.24 -RANLIB = arm-eabi-ranlib
    1.25 +#---------------------------------------------------------------------------------
    1.26 +# TARGET is the name of the output
    1.27 +# BUILD is the directory where object files & intermediate files will be placed
    1.28 +# SOURCES is a list of directories containing source code
    1.29 +# DATA is a list of directories containing data files
    1.30 +# INCLUDES is a list of directories containing header files
    1.31 +#---------------------------------------------------------------------------------
    1.32 +TARGET		:=	$(shell basename $(CURDIR))
    1.33 +BUILD		:=	src
    1.34 +SOURCES		:=	source
    1.35 +DATA		:=	data
    1.36 +INCLUDES	:=	include
    1.37 +
    1.38 +#---------------------------------------------------------------------------------
    1.39 +# options for code generation
    1.40 +#---------------------------------------------------------------------------------
    1.41 +ARCH	:=	-mthumb -mthumb-interwork \
    1.42 +		-D__NDS__ -DENABLE_NDS -DNO_SIGNAL_H -DDISABLE_THREADS -DPACKAGE=\"SDL\" \
    1.43 +		 -DVERSION=\"1.3\" -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1  
    1.44 +
    1.45 +CFLAGS	:=	-g -Wall -O2\
    1.46 +		-march=armv5te -mtune=arm946e-s \
    1.47 +		-fomit-frame-pointer -ffast-math \
    1.48 +		$(ARCH)
    1.49  
    1.50 -#ifdef GL
    1.51 -#DEFS += -DSDL_VIDEO_OPENGL=1
    1.52 -#TARGET = libSDL_gl.a
    1.53 -#else
    1.54 -TARGET = libSDL.a
    1.55 -#endif
    1.56 +CFLAGS	+=	$(INCLUDE) -DARM9
    1.57 +CXXFLAGS	:= $(CFLAGS) -fno-rtti -fno-exceptions
    1.58 +
    1.59 +ASFLAGS	:=	-g $(ARCH) -march=armv5te -mtune=arm946e-s
    1.60 +LDFLAGS	=	-specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
    1.61 +
    1.62 +# Set to 0 to use a framer buffer, or 1 to use the hardware
    1.63 +# renderer. Alas, both cannot be used at the same time for lack of
    1.64 +# display/texture memory.
    1.65 +USE_HW_RENDERER := 1
    1.66 +
    1.67 +ifeq ($(USE_HW_RENDERER),1)
    1.68 +CFLAGS += -DUSE_HW_RENDERER
    1.69 +else
    1.70 +endif
    1.71  
    1.72 -#CFLAGS=$(DEFS) -Iinclude
    1.73 -CFLAGS	=	-mthumb -mthumb-interwork \
    1.74 -		-march=armv5te -mtune=arm946e-s \
    1.75 -		-O2 -Wall -Wwrite-strings -Wpointer-arith  \
    1.76 -		-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
    1.77 +#---------------------------------------------------------------------------------
    1.78 +# list of directories containing libraries, this must be the top level containing
    1.79 +# include and lib
    1.80 +#---------------------------------------------------------------------------------
    1.81 +LIBDIRS	:=	$(LIBNDS)
    1.82  
    1.83 -#src/audio/disk/SDL_diskaudio.c \
    1.84 -#src/audio/dummy/SDL_dummyaudio.c \
    1.85 +#---------------------------------------------------------------------------------
    1.86 +# no real need to edit anything past this point unless you need to add additional
    1.87 +# rules for different file extensions
    1.88 +#---------------------------------------------------------------------------------
    1.89 +ifneq ($(BUILD),$(notdir $(CURDIR)))
    1.90 +#---------------------------------------------------------------------------------
    1.91 +
    1.92 +export OUTPUT	:=	$(CURDIR)/lib/lib$(TARGET).a
    1.93 +
    1.94 +export VPATH	:=	$(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
    1.95 +			$(foreach dir,$(DATA),$(CURDIR)/$(dir))
    1.96 +
    1.97 +export DEPSDIR	:=	$(CURDIR)/$(BUILD)
    1.98  
    1.99 -SRCS = \
   1.100 -src/SDL.c \
   1.101 -src/SDL_assert.c \
   1.102 -src/SDL_compat.c \
   1.103 -src/SDL_error.c \
   1.104 -src/SDL_fatal.c \
   1.105 -src/SDL_hints.c \
   1.106 -src/SDL_log.c \
   1.107 -src/atomic/SDL_atomic.c \
   1.108 -src/atomic/SDL_spinlock.c \
   1.109 -src/audio/SDL_audio.c \
   1.110 -src/audio/SDL_audiocvt.c \
   1.111 -src/audio/SDL_audiodev.c \
   1.112 -src/audio/SDL_audiotypecvt.c \
   1.113 -src/audio/SDL_mixer.c \
   1.114 -src/audio/SDL_mixer_MMX.c \
   1.115 -src/audio/SDL_mixer_MMX_VC.c \
   1.116 -src/audio/SDL_mixer_m68k.c \
   1.117 -src/audio/SDL_wave.c \
   1.118 -src/audio/nds/SDL_ndsaudio.c \
   1.119 -src/cpuinfo/SDL_cpuinfo.c \
   1.120 -src/events/SDL_events.c \
   1.121 -src/events/SDL_keyboard.c \
   1.122 -src/events/SDL_mouse.c \
   1.123 -src/events/SDL_quit.c \
   1.124 -src/events/SDL_touch.c \
   1.125 -src/events/SDL_windowevents.c \
   1.126 -src/events/nds/SDL_ndsgesture.c \
   1.127 -src/file/SDL_rwops.c \
   1.128 -src/haptic/SDL_haptic.c \
   1.129 -src/haptic/nds/SDL_syshaptic.c \
   1.130 -src/joystick/SDL_joystick.c \
   1.131 -src/joystick/nds/SDL_sysjoystick.c \
   1.132 -src/power/SDL_power.c \
   1.133 -src/power/nds/SDL_syspower.c \
   1.134 -src/render/SDL_render.c \
   1.135 -src/render/SDL_yuv_sw.c \
   1.136 -src/render/software/SDL_render_sw.c \
   1.137 -src/render/software/SDL_blendpoint.c \
   1.138 -src/render/software/SDL_drawline.c \
   1.139 -src/render/software/SDL_blendline.c \
   1.140 -src/render/software/SDL_blendfillrect.c \
   1.141 -src/render/software/SDL_drawpoint.c \
   1.142 -src/stdlib/SDL_getenv.c \
   1.143 -src/stdlib/SDL_iconv.c \
   1.144 -src/stdlib/SDL_malloc.c \
   1.145 -src/stdlib/SDL_qsort.c \
   1.146 -src/stdlib/SDL_stdlib.c \
   1.147 -src/stdlib/SDL_string.c \
   1.148 -src/thread/SDL_thread.c \
   1.149 -src/thread/nds/SDL_syscond.c \
   1.150 -src/thread/nds/SDL_sysmutex.c \
   1.151 -src/thread/nds/SDL_syssem.c \
   1.152 -src/thread/nds/SDL_systhread.c \
   1.153 -src/timer/SDL_timer.c \
   1.154 -src/timer/nds/SDL_systimer.c \
   1.155 -src/video/SDL_RLEaccel.c \
   1.156 -src/video/SDL_blit.c \
   1.157 -src/video/SDL_blit_0.c \
   1.158 -src/video/SDL_blit_1.c \
   1.159 -src/video/SDL_blit_A.c \
   1.160 -src/video/SDL_blit_N.c \
   1.161 -src/video/SDL_blit_auto.c \
   1.162 -src/video/SDL_blit_copy.c \
   1.163 -src/video/SDL_blit_slow.c \
   1.164 -src/video/SDL_bmp.c \
   1.165 -src/video/SDL_fillrect.c \
   1.166 -src/video/SDL_pixels.c \
   1.167 -src/video/SDL_rect.c \
   1.168 -src/video/SDL_stretch.c \
   1.169 -src/video/SDL_surface.c \
   1.170 -src/video/SDL_video.c \
   1.171 -src/video/dummy/SDL_nullevents.c \
   1.172 -src/video/dummy/SDL_nullvideo.c \
   1.173 -src/video/nds/SDL_ndsevents.c \
   1.174 -src/video/nds/SDL_ndsrender.c \
   1.175 -src/video/nds/SDL_ndsvideo.c \
   1.176 -
   1.177 -OBJS = $(SRCS:.c=.o)
   1.178 -
   1.179 -TEST = \
   1.180 -test/nds-test-progs/general/general.nds \
   1.181 -test/nds-test-progs/sprite/sprite.nds \
   1.182 -test/nds-test-progs/sprite2/sprite2.nds \
   1.183 +CFILES		:=	\
   1.184 +			SDL.c \
   1.185 +			SDL_assert.c \
   1.186 +			SDL_compat.c \
   1.187 +			SDL_error.c \
   1.188 +			SDL_fatal.c \
   1.189 +			SDL_hints.c \
   1.190 +			SDL_log.c \
   1.191 +			atomic/SDL_atomic.c \
   1.192 +			atomic/SDL_spinlock.arm.c \
   1.193 +			audio/SDL_audio.c \
   1.194 +			audio/SDL_audiocvt.c \
   1.195 +			audio/SDL_audiodev.c \
   1.196 +			audio/SDL_audiotypecvt.c \
   1.197 +			audio/SDL_mixer.c \
   1.198 +			audio/SDL_mixer_MMX.c \
   1.199 +			audio/SDL_mixer_MMX_VC.c \
   1.200 +			audio/SDL_mixer_m68k.c \
   1.201 +			audio/SDL_wave.c \
   1.202 +			audio/nds/SDL_ndsaudio.c \
   1.203 +			cpuinfo/SDL_cpuinfo.c \
   1.204 +			events/SDL_events.c \
   1.205 +			events/SDL_keyboard.c \
   1.206 +			events/SDL_mouse.c \
   1.207 +			events/SDL_quit.c \
   1.208 +			events/SDL_touch.c \
   1.209 +			events/SDL_windowevents.c \
   1.210 +			events/nds/SDL_ndsgesture.c \
   1.211 +			file/SDL_rwops.c \
   1.212 +			haptic/SDL_haptic.c \
   1.213 +			haptic/nds/SDL_syshaptic.c \
   1.214 +			joystick/SDL_joystick.c \
   1.215 +			joystick/nds/SDL_sysjoystick.c \
   1.216 +			power/SDL_power.c \
   1.217 +			power/nds/SDL_syspower.c \
   1.218 +			render/SDL_render.c \
   1.219 +			render/SDL_yuv_sw.c \
   1.220 +			render/software/SDL_blendfillrect.c \
   1.221 +			render/software/SDL_blendline.c \
   1.222 +			render/software/SDL_blendpoint.c \
   1.223 +			render/software/SDL_drawline.c \
   1.224 +			render/software/SDL_drawpoint.c \
   1.225 +			render/software/SDL_render_sw.c \
   1.226 +			stdlib/SDL_getenv.c \
   1.227 +			stdlib/SDL_iconv.c \
   1.228 +			stdlib/SDL_malloc.c \
   1.229 +			stdlib/SDL_qsort.c \
   1.230 +			stdlib/SDL_stdlib.c \
   1.231 +			stdlib/SDL_string.c \
   1.232 +			thread/SDL_thread.c \
   1.233 +			thread/nds/SDL_syscond.c \
   1.234 +			thread/nds/SDL_sysmutex.c \
   1.235 +			thread/nds/SDL_syssem.c \
   1.236 +			thread/nds/SDL_systhread.c \
   1.237 +			timer/SDL_timer.c \
   1.238 +			timer/nds/SDL_systimer.c \
   1.239 +			video/SDL_RLEaccel.c \
   1.240 +			video/SDL_blit.c \
   1.241 +			video/SDL_blit_0.c \
   1.242 +			video/SDL_blit_1.c \
   1.243 +			video/SDL_blit_A.c \
   1.244 +			video/SDL_blit_N.c \
   1.245 +			video/SDL_blit_auto.c \
   1.246 +			video/SDL_blit_copy.c \
   1.247 +			video/SDL_blit_slow.c \
   1.248 +			video/SDL_bmp.c \
   1.249 +			video/SDL_clipboard.c \
   1.250 +			video/SDL_fillrect.c \
   1.251 +			video/SDL_pixels.c \
   1.252 +			video/SDL_rect.c \
   1.253 +			video/SDL_stretch.c \
   1.254 +			video/SDL_surface.c \
   1.255 +			video/SDL_video.c \
   1.256 +			video/nds/SDL_ndsevents.c \
   1.257 +			video/nds/SDL_ndsvideo.c
   1.258  
   1.259  
   1.260 -all: $(TARGET) install nds_test
   1.261 +ifeq ($(USE_HW_RENDERER),1)
   1.262 +# Ideally we should be able to not include the SW renderer at set
   1.263 +# SDL_NO_COMPAT. However that breaks the build.
   1.264 +CFILES +=	render/nds/SDL_ndsrender.c
   1.265 +else
   1.266 +endif
   1.267  
   1.268 -# That file must be compiled in arm mode, not thumb mode.
   1.269 -src/atomic/SDL_spinlock.o: src/atomic/SDL_spinlock.c
   1.270 -	$(CC) $(CFLAGS) -mno-thumb -o $@ -c $^
   1.271 +#CPPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
   1.272 +#SFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
   1.273 +#BINFILES	:=	$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
   1.274  
   1.275 -$(TARGET): $(OBJS)
   1.276 -	$(AR) rc $(TARGET) $(OBJS)
   1.277 -	-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
   1.278 +#---------------------------------------------------------------------------------
   1.279 +# use CXX for linking C++ projects, CC for standard C
   1.280 +#---------------------------------------------------------------------------------
   1.281 +ifeq ($(strip $(CPPFILES)),)
   1.282 +#---------------------------------------------------------------------------------
   1.283 +	export LD	:=	$(CC)
   1.284 +#---------------------------------------------------------------------------------
   1.285 +else
   1.286 +#---------------------------------------------------------------------------------
   1.287 +	export LD	:=	$(CXX)
   1.288 +#---------------------------------------------------------------------------------
   1.289 +endif
   1.290 +#---------------------------------------------------------------------------------
   1.291 +
   1.292 +export OFILES	:=	$(addsuffix .o,$(BINFILES)) \
   1.293 +			$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
   1.294  
   1.295 -install: $(TARGET)
   1.296 -	@cp libSDL.a $(DEVKITPRO)/libnds/lib/
   1.297 +export INCLUDE	:=	$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
   1.298 +			$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
   1.299 +			-I$(CURDIR)/$(BUILD)
   1.300 +
   1.301 +.PHONY: $(BUILD) clean all
   1.302 +
   1.303 +#---------------------------------------------------------------------------------
   1.304 +all: arm_only $(BUILD) install nds_test
   1.305 +
   1.306 +lib:
   1.307 +	@[ -d $@ ] || mkdir -p $@
   1.308 +
   1.309 +$(BUILD): lib
   1.310 +	@[ -d $@ ] || mkdir -p $@
   1.311 +	@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.ds -s
   1.312 +
   1.313 +install: $(BUILD)
   1.314 +	@cp $(OUTPUT) $(DEVKITPRO)/libnds/lib/
   1.315  	@mkdir -p $(DEVKITPRO)/libnds/include/SDL/
   1.316  	@cp include/*.h $(DEVKITPRO)/libnds/include/SDL/
   1.317  
   1.318  nds_test:
   1.319 -	$(MAKE) -C test/nds-test-progs/general
   1.320 -#	$(MAKE) -C test/nds-test-progs/sprite
   1.321 -#	$(MAKE) -C test/nds-test-progs/sprite2
   1.322 +	$(MAKE) -C test/nds-test-progs
   1.323 +
   1.324 +tags:
   1.325 +	etags $(SRCS)
   1.326 +
   1.327 +# This file must be compiled with the ARM instruction set, not
   1.328 +# thumb. Use devkitpro way of doing things.
   1.329 +arm_only: src/atomic/SDL_spinlock.arm.c
   1.330 +src/atomic/SDL_spinlock.arm.c: src/atomic/SDL_spinlock.c
   1.331 +	@cp $< $@
   1.332 +
   1.333 +#---------------------------------------------------------------------------------
   1.334 +clean:
   1.335 +	@echo clean ...
   1.336 +	@cd src; rm -fr $(OFILES) $(OFILES:.o=.d) lib
   1.337 +
   1.338 +#---------------------------------------------------------------------------------
   1.339 +else
   1.340  
   1.341 -clean:
   1.342 -	rm -f $(OBJS)
   1.343 +DEPENDS	:=	$(OFILES:.o=.d)
   1.344 +
   1.345 +#---------------------------------------------------------------------------------
   1.346 +# main targets
   1.347 +#---------------------------------------------------------------------------------
   1.348 +$(OUTPUT)	:	$(OFILES)
   1.349 +
   1.350 +#---------------------------------------------------------------------------------
   1.351 +%.bin.o	:	%.bin
   1.352 +#---------------------------------------------------------------------------------
   1.353 +	@echo $(notdir $<)
   1.354 +	@$(bin2o)
   1.355 +
   1.356 +
   1.357 +-include $(DEPENDS)
   1.358 +
   1.359 +#---------------------------------------------------------------------------------------
   1.360 +endif
   1.361 +#---------------------------------------------------------------------------------------
     2.1 --- a/README.ds	Sat Mar 05 10:03:57 2011 -0800
     2.2 +++ b/README.ds	Sun Mar 06 21:12:19 2011 -0800
     2.3 @@ -3,17 +3,37 @@
     2.4  ================================================================================
     2.5  
     2.6  -Requirements-
     2.7 -The devkitpro SDK available at http://devkitpro.org.
     2.8 -Read the information at http://devkitpro.org/wiki/Getting_Started/devkitARM
     2.9 -The necessary packages are devkitARM, libnds and default arm7.
    2.10 +* The devkitpro SDK available at http://devkitpro.org.
    2.11 +  Read the information at http://devkitpro.org/wiki/Getting_Started/devkitARM
    2.12 +  The necessary packages are devkitARM, libnds and default arm7.
    2.13 +* The hardware renderer is using the libgl2d abstraction library that can be found at:
    2.14 +    http://rel.phatcode.net/junk.php?id=117
    2.15 +  Build it, and install the library and the header where SDL can find them (ie. in
    2.16 +  the libnds/lib and libnds/include directories).
    2.17 +
    2.18  
    2.19  -Building SDL-
    2.20 -After setting the devkitpro environment, type:
    2.21 +
    2.22 +After setting the devkitpro environment, cd into your SDL directory and type:
    2.23    make -f Makefile.ds
    2.24  
    2.25 -This will compile and install the library and headers into the proper libnds directories.
    2.26 -Additionnaly it will compile the general test, that you can run either on the DS or with desmume:
    2.27 +This will compile and install the library and headers into the proper libnds
    2.28 +directories. Additionnaly it will compile several tests that you can run
    2.29 +either on the DS or with desmume. For instance:
    2.30    desmume test/nds-test-progs/general/general.nds
    2.31  
    2.32 +-Notes-
    2.33 +* The renderer code is based on the gl like engine. It's not using the sprite engine.
    2.34 +* The port is very basic and incomplete:
    2.35 +  - SDL currently has to be compiled for either framebuffer mode or render mode.
    2.36 +     See USE_HW_RENDERER in Makefile.ds.
    2.37 +  - some optionnal renderer functions are not implemented.
    2.38  
    2.39 -Note that the port is very basic and incomplete.
    2.40 +-Limitations-
    2.41 +* in hardware renderer mode, don't load too many textures. The internal format is
    2.42 +  2 bytes per pixel. And there is only 256KB reserved for the textures. For instance,
    2.43 +  testscale won't display sample.bmp, unless it's resized to a smaller picture.
    2.44 +* the screen size is 256 x 384. Anything else won't work.
    2.45 +* there is no 8 bits/pixel mode because SDL 1.3 doesn't support palettes.
    2.46 +
    2.47 +
     3.1 --- a/include/SDL_config_nintendods.h	Sat Mar 05 10:03:57 2011 -0800
     3.2 +++ b/include/SDL_config_nintendods.h	Sun Mar 06 21:12:19 2011 -0800
     3.3 @@ -115,7 +115,11 @@
     3.4  
     3.5  /* Enable various video drivers */
     3.6  #define SDL_VIDEO_DRIVER_NDS	1
     3.7 +#ifdef USE_HW_RENDERER
     3.8  #define SDL_VIDEO_RENDER_NDS	1
     3.9 +#else
    3.10 +#define SDL_VIDEO_RENDER_NDS	0
    3.11 +#endif
    3.12  
    3.13  /* Enable system power support */
    3.14  #define SDL_POWER_NINTENDODS 1
    3.15 @@ -123,4 +127,6 @@
    3.16  /* Enable haptic support */
    3.17  #define SDL_HAPTIC_NDS 1
    3.18  
    3.19 +#define SDL_BYTEORDER   SDL_LIL_ENDIAN
    3.20 +
    3.21  #endif /* _SDL_config_nintendods_h */
     4.1 --- a/src/render/SDL_render.c	Sat Mar 05 10:03:57 2011 -0800
     4.2 +++ b/src/render/SDL_render.c	Sun Mar 06 21:12:19 2011 -0800
     4.3 @@ -60,6 +60,9 @@
     4.4  #if SDL_VIDEO_RENDER_DIRECTFB
     4.5      &DirectFB_RenderDriver,
     4.6  #endif
     4.7 +#if SDL_VIDEO_RENDER_NDS
     4.8 +    &NDS_RenderDriver,
     4.9 +#endif
    4.10      &SW_RenderDriver
    4.11  #endif /* !SDL_RENDER_DISABLED */
    4.12  };
     5.1 --- a/src/render/SDL_sysrender.h	Sat Mar 05 10:03:57 2011 -0800
     5.2 +++ b/src/render/SDL_sysrender.h	Sun Mar 06 21:12:19 2011 -0800
     5.3 @@ -139,6 +139,9 @@
     5.4  #if SDL_VIDEO_RENDER_DIRECTFB
     5.5  extern SDL_RenderDriver DirectFB_RenderDriver;
     5.6  #endif
     5.7 +#if SDL_VIDEO_RENDER_NDS
     5.8 +extern SDL_RenderDriver NDS_RenderDriver;
     5.9 +#endif
    5.10  extern SDL_RenderDriver SW_RenderDriver;
    5.11  
    5.12  #endif /* !SDL_RENDER_DISABLED */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/render/nds/SDL_ndsrender.c	Sun Mar 06 21:12:19 2011 -0800
     6.3 @@ -0,0 +1,364 @@
     6.4 +/*
     6.5 +    SDL - Simple DirectMedia Layer
     6.6 +    Copyright (C) 1997-2011 Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Lesser General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2.1 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Lesser General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Lesser General Public
    6.19 +    License along with this library; if not, write to the Free Software
    6.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    6.21 +
    6.22 +    Sam Lantinga
    6.23 +    slouken@libsdl.org
    6.24 +*/
    6.25 +
    6.26 +#include <stdio.h>
    6.27 +#include <stdlib.h>
    6.28 +#include <nds.h>
    6.29 +
    6.30 +#include <gl2d.h>
    6.31 +
    6.32 +#include "SDL_config.h"
    6.33 +
    6.34 +#include "SDL_video.h"
    6.35 +#include "../../video/SDL_sysvideo.h"
    6.36 +#include "SDL_render.h"
    6.37 +#include "../SDL_sysrender.h"
    6.38 +#include "SDL_log.h"
    6.39 +
    6.40 +/* SDL NDS renderer implementation */
    6.41 +
    6.42 +extern SDL_RenderDriver NDS_RenderDriver;
    6.43 +
    6.44 +typedef struct
    6.45 +{
    6.46 +	/* Whether current 3D engine is on the main or sub screen. */
    6.47 +	int is_sub;
    6.48 +} NDS_RenderData;
    6.49 +
    6.50 +typedef struct
    6.51 +{
    6.52 +	glImage image[1];
    6.53 +} NDS_TextureData;
    6.54 +
    6.55 +
    6.56 +static int NDS_UpdateViewport(SDL_Renderer *renderer)
    6.57 +{
    6.58 +	/* Nothing to do. */
    6.59 +	return 0;
    6.60 +}
    6.61 +
    6.62 +static int
    6.63 +NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
    6.64 +               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
    6.65 +{
    6.66 +    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
    6.67 +    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
    6.68 +	int dest_y;
    6.69 +
    6.70 +	if (data->is_sub) {
    6.71 +		dest_y = dstrect->y;
    6.72 +	} else {
    6.73 +		dest_y = dstrect->y-SCREEN_HEIGHT;
    6.74 +	}
    6.75 +
    6.76 +	if (texture->w == dstrect->w && texture->h == dstrect->h) {
    6.77 +		/* No scaling */
    6.78 +		glSprite(dstrect->x, dest_y, GL_FLIP_NONE, txdat->image);
    6.79 +	} else {
    6.80 +		/* Convert the scaling proportion into a 20.12 value. */
    6.81 +		s32 scale_w = divf32(dstrect->w << 12, texture->w << 12);
    6.82 +		s32 scale_h = divf32(dstrect->h << 12, texture->h << 12);
    6.83 +
    6.84 +		glSpriteScaleXY(dstrect->x, dest_y, scale_w, scale_h, GL_FLIP_NONE, txdat->image);
    6.85 +	}
    6.86 +
    6.87 +    return 0;
    6.88 +}
    6.89 +
    6.90 +static int NDS_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
    6.91 +{
    6.92 +    NDS_TextureData *txdat = NULL;
    6.93 +    int i;
    6.94 +
    6.95 +	SDL_Log("NDS_CreateTexture: NDS_CreateTexture.\n");
    6.96 +
    6.97 +	/* Sanity checks. */
    6.98 +	for (i=0; i<NDS_RenderDriver.info.num_texture_formats; i++) {
    6.99 +		if (texture->format == NDS_RenderDriver.info.texture_formats[i])
   6.100 +			break;
   6.101 +	}
   6.102 +	if (i == NDS_RenderDriver.info.num_texture_formats) {
   6.103 +		SDL_SetError("Unsupported texture format (%x)", texture->format);
   6.104 +		return -1;
   6.105 +	}
   6.106 +
   6.107 +	if (texture->w > NDS_RenderDriver.info.max_texture_width) {
   6.108 +		SDL_SetError("Texture too large (%d)", texture->w);
   6.109 +		return -1;
   6.110 +	}
   6.111 +
   6.112 +	if (texture->h > NDS_RenderDriver.info.max_texture_height) {
   6.113 +		SDL_SetError("Texture too tall (%d)", texture->h);
   6.114 +		return -1;
   6.115 +	}
   6.116 +
   6.117 +	texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
   6.118 +	txdat = (NDS_TextureData *) texture->driverdata;
   6.119 +	if (!txdat) {
   6.120 +		SDL_OutOfMemory();
   6.121 +		return -1;
   6.122 +	}
   6.123 +
   6.124 +    return 0;
   6.125 +}
   6.126 +
   6.127 +static void
   6.128 +NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   6.129 +{
   6.130 +    NDS_TextureData *txdat = texture->driverdata;
   6.131 +
   6.132 +    /* free anything else allocated for texture */
   6.133 +    SDL_free(txdat);
   6.134 +}
   6.135 +
   6.136 +/* size is no more than 1024. */
   6.137 +static int get_gltexture_size(unsigned int size)
   6.138 +{
   6.139 +	if (size > 256)
   6.140 +		return TEXTURE_SIZE_512;
   6.141 +	else if (size > 128)
   6.142 +		return TEXTURE_SIZE_256;
   6.143 +	else if (size > 64)
   6.144 +		return TEXTURE_SIZE_128;
   6.145 +	else if (size > 32)
   6.146 +		return TEXTURE_SIZE_64;
   6.147 +	else if (size > 16)
   6.148 +		return TEXTURE_SIZE_32;
   6.149 +	else if (size > 8)
   6.150 +		return TEXTURE_SIZE_16;
   6.151 +	else
   6.152 +		return TEXTURE_SIZE_8;
   6.153 +}
   6.154 +
   6.155 +static int NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   6.156 +							 const SDL_Rect * rect, const void *pixels, int pitch)
   6.157 +{
   6.158 +    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
   6.159 +
   6.160 +	SDL_Log("enter %s\n", __func__);
   6.161 +
   6.162 +	glLoadTileSet(txdat->image,
   6.163 +				  rect->w, rect->h,
   6.164 +				  rect->w, rect->h,
   6.165 +				  GL_RGBA,
   6.166 +				  get_gltexture_size(rect->w),
   6.167 +				  get_gltexture_size(rect->h),
   6.168 +				  TEXGEN_OFF, 0, NULL,
   6.169 +				  pixels);
   6.170 +
   6.171 +    return 0;
   6.172 +}
   6.173 +
   6.174 +static int NDS_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
   6.175 +						   const SDL_Rect *rect, void **pixels, int *pitch)
   6.176 +{
   6.177 +	SDL_Log("enter %s (todo)\n", __func__);
   6.178 +
   6.179 +    return 0;
   6.180 +}
   6.181 +
   6.182 +static void NDS_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
   6.183 +{
   6.184 +	SDL_Log("enter %s\n", __func__);
   6.185 +    /* stub! */
   6.186 +}
   6.187 +
   6.188 +static int NDS_RenderClear(SDL_Renderer *renderer)
   6.189 +{
   6.190 +    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
   6.191 +
   6.192 +	/* wait for capture unit to be ready */
   6.193 +	while(REG_DISPCAPCNT & DCAP_ENABLE);
   6.194 +
   6.195 +	/* 3D engine can only work on one screen at a time. */
   6.196 +	data->is_sub = !data->is_sub;
   6.197 +	if (data->is_sub) {
   6.198 +		lcdMainOnBottom();
   6.199 +		vramSetBankC(VRAM_C_LCD);
   6.200 +		vramSetBankD(VRAM_D_SUB_SPRITE);
   6.201 +		REG_DISPCAPCNT = DCAP_BANK(2) | DCAP_ENABLE | DCAP_SIZE(3);
   6.202 +	} else {
   6.203 +		lcdMainOnTop();
   6.204 +		vramSetBankD(VRAM_D_LCD);
   6.205 +		vramSetBankC(VRAM_C_SUB_BG);
   6.206 +		REG_DISPCAPCNT = DCAP_BANK(3) | DCAP_ENABLE | DCAP_SIZE(3);
   6.207 +	}
   6.208 +
   6.209 +	glBegin2D();
   6.210 +
   6.211 +    glClearColor(renderer->r >> 3,
   6.212 +                 renderer->g >> 3,
   6.213 +                 renderer->b >> 3,
   6.214 +                 renderer->a >> 3);
   6.215 +
   6.216 +	return 0;
   6.217 +}
   6.218 +
   6.219 +static void NDS_RenderPresent(SDL_Renderer * renderer)
   6.220 +{
   6.221 +//	SDL_Log("enter %s\n", __func__);
   6.222 +
   6.223 +	glEnd2D();
   6.224 +		
   6.225 +	glFlush( 0 );
   6.226 +}
   6.227 +
   6.228 +static int NDS_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points,
   6.229 +								int count)
   6.230 +{
   6.231 +    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
   6.232 +	int i;
   6.233 +	int color = RGB15(renderer->r >> 3,
   6.234 +					  renderer->g >> 3,
   6.235 +					  renderer->b >> 3);
   6.236 +
   6.237 +	for (i=0; i < count; i++) {
   6.238 +		if (data->is_sub) {
   6.239 +			glPutPixel(points[i].x, points[i].y, color);
   6.240 +		} else {
   6.241 +			glPutPixel(points[i].x, points[i].y - SCREEN_HEIGHT, color);
   6.242 +		}
   6.243 +	}
   6.244 +
   6.245 +	return 0;
   6.246 +}
   6.247 +
   6.248 +static int NDS_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points,
   6.249 +							   int count)
   6.250 +{
   6.251 +    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
   6.252 +	int i;
   6.253 +	int color = RGB15(renderer->r >> 3,
   6.254 +					  renderer->g >> 3,
   6.255 +					  renderer->b >> 3);
   6.256 +
   6.257 +	for (i=0; i < count-1; i++) {
   6.258 +		if (data->is_sub) {
   6.259 +			glLine(points[i].x, points[i].y, points[i+1].x, points[i+1].y, color);
   6.260 +		} else {
   6.261 +			glLine(points[i].x, points[i].y - SCREEN_HEIGHT, 
   6.262 +				   points[i+1].x, points[i+1].y - SCREEN_HEIGHT, color);
   6.263 +		}
   6.264 +	}
   6.265 +
   6.266 +	return 0;
   6.267 +}
   6.268 +
   6.269 +static int NDS_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects,
   6.270 +							   int count)
   6.271 +{
   6.272 +    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
   6.273 +	int i;
   6.274 +	int color = RGB15(renderer->r >> 3,
   6.275 +					  renderer->g >> 3,
   6.276 +					  renderer->b >> 3);
   6.277 +
   6.278 +	for (i=0; i<count; i++) {
   6.279 +		if (data->is_sub) {
   6.280 +			glBoxFilled(rects[i].x, rects[i].y, 
   6.281 +						rects[i].x + rects[i].w,
   6.282 +						rects[i].y + rects[i].h, color);
   6.283 +	} else {
   6.284 +			glBoxFilled(rects[i].x, rects[i].y - SCREEN_HEIGHT,
   6.285 +						rects[i].x + rects[i].w,
   6.286 +						rects[i].y + rects[i].h - SCREEN_HEIGHT,
   6.287 +						color);
   6.288 +		}
   6.289 +	}
   6.290 +
   6.291 +	return 0;
   6.292 +}
   6.293 +
   6.294 +static SDL_Renderer *
   6.295 +NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
   6.296 +{
   6.297 +    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
   6.298 +    SDL_DisplayMode *displayMode = &display->current_mode;
   6.299 +    SDL_Renderer *renderer;
   6.300 +    NDS_RenderData *data;
   6.301 +    int bpp;
   6.302 +    Uint32 Rmask, Gmask, Bmask, Amask;
   6.303 +
   6.304 +	if (displayMode->format != SDL_PIXELFORMAT_ABGR1555) {
   6.305 +		SDL_SetError("Unsupported pixel format (%x)", displayMode->format);
   6.306 +		return NULL;
   6.307 +	}
   6.308 +
   6.309 +    if (!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp,
   6.310 +                                    &Rmask, &Gmask, &Bmask, &Amask)) {
   6.311 +        SDL_SetError("Unknown display format");
   6.312 +        return NULL;
   6.313 +    }
   6.314 +
   6.315 +    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
   6.316 +    if (!renderer) {
   6.317 +        SDL_OutOfMemory();
   6.318 +        return NULL;
   6.319 +    }
   6.320 +
   6.321 +    data = (NDS_RenderData *) SDL_calloc(1, sizeof(*data));
   6.322 +    if (!data) {
   6.323 +        SDL_free(renderer);
   6.324 +        SDL_OutOfMemory();
   6.325 +        return NULL;
   6.326 +    }
   6.327 +
   6.328 +    renderer->info.name = NDS_RenderDriver.info.name;
   6.329 +    renderer->info.flags = 0;
   6.330 +    renderer->info.num_texture_formats = NDS_RenderDriver.info.num_texture_formats;
   6.331 +    SDL_memcpy(renderer->info.texture_formats,
   6.332 +			   NDS_RenderDriver.info.texture_formats,
   6.333 +               sizeof(renderer->info.texture_formats));
   6.334 +    renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width;
   6.335 +    renderer->info.max_texture_height = NDS_RenderDriver.info.max_texture_height;
   6.336 +
   6.337 +	renderer->UpdateViewport = NDS_UpdateViewport;
   6.338 +    renderer->CreateTexture = NDS_CreateTexture;
   6.339 +	renderer->DestroyTexture = NDS_DestroyTexture;
   6.340 +	renderer->RenderCopy = NDS_RenderCopy;	
   6.341 +	renderer->UpdateTexture = NDS_UpdateTexture;
   6.342 +	renderer->LockTexture = NDS_LockTexture;
   6.343 +	renderer->UnlockTexture = NDS_UnlockTexture;
   6.344 +	renderer->RenderClear = NDS_RenderClear;
   6.345 +	renderer->RenderPresent = NDS_RenderPresent;
   6.346 +	renderer->RenderDrawPoints = NDS_RenderDrawPoints;
   6.347 +	renderer->RenderDrawLines = NDS_RenderDrawLines;
   6.348 +	renderer->RenderFillRects = NDS_RenderFillRects;
   6.349 +
   6.350 +    return renderer;
   6.351 +}
   6.352 +
   6.353 +SDL_RenderDriver NDS_RenderDriver = {
   6.354 +	.CreateRenderer = NDS_CreateRenderer,
   6.355 +    .info = {
   6.356 +		.name = "nds",
   6.357 +		.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC,
   6.358 +		.num_texture_formats = 1,
   6.359 +		.texture_formats = { [0] = SDL_PIXELFORMAT_ABGR1555,
   6.360 +							 [1] = SDL_PIXELFORMAT_BGR555,
   6.361 +		},
   6.362 +		.max_texture_width = 512,
   6.363 +		.max_texture_height = 512,
   6.364 +     }
   6.365 +};
   6.366 +
   6.367 +/* vi: set ts=4 sw=4 expandtab: */
     7.1 --- a/src/video/SDL_RLEaccel.c	Sat Mar 05 10:03:57 2011 -0800
     7.2 +++ b/src/video/SDL_RLEaccel.c	Sun Mar 06 21:12:19 2011 -0800
     7.3 @@ -891,6 +891,9 @@
     7.4          unsigned r, g, b;
     7.5          RGB_FROM_PIXEL(*src, sfmt, r, g, b);
     7.6          PIXEL_FROM_RGB(*d, dfmt, r, g, b);
     7.7 +#ifdef __NDS__
     7.8 +		*d |= NDS_BIT15;
     7.9 +#endif
    7.10          src++;
    7.11          d++;
    7.12      }
    7.13 @@ -948,7 +951,7 @@
    7.14          Uint16 pix;
    7.15          RGBA_FROM_8888(*src, sfmt, r, g, b, a);
    7.16          PIXEL_FROM_RGB(pix, dfmt, r, g, b);
    7.17 -        *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0);
    7.18 +        *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0) | NDS_BIT15;
    7.19          src++;
    7.20          d++;
    7.21      }
     8.1 --- a/src/video/SDL_blit.h	Sat Mar 05 10:03:57 2011 -0800
     8.2 +++ b/src/video/SDL_blit.h	Sun Mar 06 21:12:19 2011 -0800
     8.3 @@ -114,6 +114,16 @@
     8.4  #define DECLARE_ALIGNED(t,v,a)  t v
     8.5  #endif
     8.6  
     8.7 +/* The Nintendo surfaces are special. Bit 15 is the transparency
     8.8 + * bit. It must be set for the pixel to be displayed. By setting that
     8.9 + * value to 0 for other platforms, their compiler should optimize it
    8.10 + * out. */
    8.11 +#ifdef __NDS__
    8.12 +#define NDS_BIT15 0x8000
    8.13 +#else
    8.14 +#define NDS_BIT15 0
    8.15 +#endif
    8.16 +
    8.17  /* Load pixel of the specified format from a buffer and get its R-G-B values */
    8.18  /* FIXME: rescale values to 0..255 here? */
    8.19  #define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)				\
    8.20 @@ -241,7 +251,7 @@
    8.21  			Uint16 Pixel;					\
    8.22  									\
    8.23  			PIXEL_FROM_RGB(Pixel, fmt, r, g, b);		\
    8.24 -			*((Uint16 *)(buf)) = Pixel;			\
    8.25 +			*((Uint16 *)(buf)) = Pixel | NDS_BIT15;		\
    8.26  		}							\
    8.27  		break;							\
    8.28  									\
    8.29 @@ -396,7 +406,7 @@
    8.30  			Uint16 Pixel;					\
    8.31  									\
    8.32  			PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a);	\
    8.33 -			*((Uint16 *)(buf)) = Pixel;			\
    8.34 +			*((Uint16 *)(buf)) = Pixel | NDS_BIT15;		\
    8.35  		}							\
    8.36  		break;							\
    8.37  									\
     9.1 --- a/src/video/SDL_video.c	Sat Mar 05 10:03:57 2011 -0800
     9.2 +++ b/src/video/SDL_video.c	Sun Mar 06 21:12:19 2011 -0800
     9.3 @@ -1131,6 +1131,10 @@
     9.4  #if (SDL_VIDEO_OPENGL && __MACOSX__) || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     9.5      flags |= SDL_WINDOW_OPENGL;
     9.6  #endif
     9.7 +#ifdef __NDS__
     9.8 +	/* Always for Nintendo DS. */
     9.9 +	flags |= SDL_WINDOW_FULLSCREEN;
    9.10 +#endif
    9.11      if (flags & SDL_WINDOW_OPENGL) {
    9.12          if (!_this->GL_CreateContext) {
    9.13              SDL_SetError("No OpenGL support in video driver");
    10.1 --- a/src/video/nds/SDL_ndsrender.c	Sat Mar 05 10:03:57 2011 -0800
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,522 +0,0 @@
    10.4 -/*
    10.5 -    SDL - Simple DirectMedia Layer
    10.6 -    Copyright (C) 1997-2011 Sam Lantinga
    10.7 -
    10.8 -    This library is free software; you can redistribute it and/or
    10.9 -    modify it under the terms of the GNU Lesser General Public
   10.10 -    License as published by the Free Software Foundation; either
   10.11 -    version 2.1 of the License, or (at your option) any later version.
   10.12 -
   10.13 -    This library is distributed in the hope that it will be useful,
   10.14 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   10.16 -    Lesser General Public License for more details.
   10.17 -
   10.18 -    You should have received a copy of the GNU Lesser General Public
   10.19 -    License along with this library; if not, write to the Free Software
   10.20 -    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   10.21 -
   10.22 -    Sam Lantinga
   10.23 -    slouken@libsdl.org
   10.24 -*/
   10.25 -
   10.26 -#include <stdio.h>
   10.27 -#include <stdlib.h>
   10.28 -#include <nds.h>
   10.29 -//#include <nds/arm9/video.h>
   10.30 -//#include <nds/arm9/sprite.h>
   10.31 -//#include <nds/arm9/trig_lut.h>
   10.32 -
   10.33 -#include "SDL_config.h"
   10.34 -
   10.35 -#include "SDL_video.h"
   10.36 -#include "../SDL_sysvideo.h"
   10.37 -#include "SDL_render.h"
   10.38 -#include "../../render/SDL_sysrender.h"
   10.39 -
   10.40 -/* SDL NDS renderer implementation */
   10.41 -
   10.42 -static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags);
   10.43 -static int NDS_ActivateRenderer(SDL_Renderer * renderer);
   10.44 -static int NDS_DisplayModeChanged(SDL_Renderer * renderer);
   10.45 -static int NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
   10.46 -#if 0
   10.47 -static int NDS_QueryTexturePixels(SDL_Renderer * renderer,
   10.48 -                                  SDL_Texture * texture, void **pixels,
   10.49 -                                  int *pitch);
   10.50 -#endif
   10.51 -static int NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   10.52 -                             const SDL_Rect * rect, const void *pixels,
   10.53 -                             int pitch);
   10.54 -static int NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   10.55 -                           const SDL_Rect * rect, int markDirty,
   10.56 -                           void **pixels, int *pitch);
   10.57 -static void NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
   10.58 -static int NDS_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
   10.59 -							   int count);
   10.60 -static int NDS_RenderCopy(SDL_Renderer * renderer,
   10.61 -                          SDL_Texture * texture,
   10.62 -                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
   10.63 -static void NDS_RenderPresent(SDL_Renderer * renderer);
   10.64 -static void NDS_DestroyTexture(SDL_Renderer * renderer,
   10.65 -                               SDL_Texture * texture);
   10.66 -static void NDS_DestroyRenderer(SDL_Renderer * renderer);
   10.67 -
   10.68 -
   10.69 -SDL_RenderDriver NDS_RenderDriver = {
   10.70 -    NDS_CreateRenderer,
   10.71 -    {"nds",                     /* char* name */
   10.72 -     (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),  /* u32 flags */
   10.73 -     2,                         /* u32 num_texture_formats */
   10.74 -     {
   10.75 -      SDL_PIXELFORMAT_ABGR1555,
   10.76 -      SDL_PIXELFORMAT_BGR555,
   10.77 -      },                        /* u32 texture_formats[20] */
   10.78 -     (256),                     /* int max_texture_width */
   10.79 -     (256),                     /* int max_texture_height */
   10.80 -     }
   10.81 -};
   10.82 -
   10.83 -typedef struct
   10.84 -{
   10.85 -    u8 bg_taken[4];
   10.86 -    OamState *oam;
   10.87 -    int sub;
   10.88 -} NDS_RenderData;
   10.89 -
   10.90 -typedef struct
   10.91 -{
   10.92 -    enum
   10.93 -    { NDSTX_BG, NDSTX_SPR } type;       /* represented in a bg or sprite. */
   10.94 -    int hw_index;               /* index of sprite in OAM or bg from libnds */
   10.95 -    int pitch, bpp;             /* useful information about the texture */
   10.96 -    struct
   10.97 -    {
   10.98 -        int x, y;
   10.99 -    } scale;                    /* x/y stretch (24.8 fixed point) */
  10.100 -    struct
  10.101 -    {
  10.102 -        int x, y;
  10.103 -    } scroll;                   /* x/y offset */
  10.104 -    int rotate;                 /* -32768 to 32767, texture rotation */
  10.105 -    u16 *vram_pixels;           /* where the pixel data is stored (a pointer into VRAM) */
  10.106 -    u16 *vram_palette;          /* where the palette data is stored if it's indexed. */
  10.107 -    /*int size; */
  10.108 -} NDS_TextureData;
  10.109 -
  10.110 -
  10.111 -
  10.112 -SDL_Renderer *
  10.113 -NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
  10.114 -{
  10.115 -    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  10.116 -    SDL_DisplayMode *displayMode = &display->current_mode;
  10.117 -    SDL_Renderer *renderer;
  10.118 -    NDS_RenderData *data;
  10.119 -    int i, n;
  10.120 -    int bpp;
  10.121 -    Uint32 Rmask, Gmask, Bmask, Amask;
  10.122 -
  10.123 -    if (!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp,
  10.124 -                                    &Rmask, &Gmask, &Bmask, &Amask)) {
  10.125 -        SDL_SetError("Unknown display format");
  10.126 -        return NULL;
  10.127 -    }
  10.128 -    switch (displayMode->format) {
  10.129 -    case SDL_PIXELFORMAT_ABGR1555:
  10.130 -    case SDL_PIXELFORMAT_BGR555:
  10.131 -        /* okay */
  10.132 -        break;
  10.133 -    case SDL_PIXELFORMAT_RGB555:
  10.134 -    case SDL_PIXELFORMAT_RGB565:
  10.135 -    case SDL_PIXELFORMAT_ARGB1555:
  10.136 -        /* we'll take these too for now */
  10.137 -        break;
  10.138 -    default:
  10.139 -        SDL_SetError("Warning: wrong display format for NDS!\n");
  10.140 -        break;
  10.141 -    }
  10.142 -
  10.143 -    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
  10.144 -    if (!renderer) {
  10.145 -        SDL_OutOfMemory();
  10.146 -        return NULL;
  10.147 -    }
  10.148 -
  10.149 -    data = (NDS_RenderData *) SDL_malloc(sizeof(*data));
  10.150 -    if (!data) {
  10.151 -        NDS_DestroyRenderer(renderer);
  10.152 -        SDL_OutOfMemory();
  10.153 -        return NULL;
  10.154 -    }
  10.155 -    SDL_zerop(data);
  10.156 -
  10.157 -    renderer->RenderFillRects = NDS_RenderFillRects;
  10.158 -    renderer->RenderCopy = NDS_RenderCopy;
  10.159 -    renderer->RenderPresent = NDS_RenderPresent;
  10.160 -    renderer->DestroyRenderer = NDS_DestroyRenderer;
  10.161 -    renderer->info.name = NDS_RenderDriver.info.name;
  10.162 -    renderer->info.flags = 0;
  10.163 -    renderer->window = window;
  10.164 -    renderer->driverdata = data;
  10.165 -    renderer->CreateTexture = NDS_CreateTexture;
  10.166 -//  renderer->QueryTexturePixels = NDS_QueryTexturePixels;
  10.167 -    renderer->UpdateTexture = NDS_UpdateTexture;
  10.168 -    renderer->LockTexture = NDS_LockTexture;
  10.169 -    renderer->UnlockTexture = NDS_UnlockTexture;
  10.170 -    renderer->DestroyTexture = NDS_DestroyTexture;
  10.171 -
  10.172 -    renderer->info.num_texture_formats =
  10.173 -        NDS_RenderDriver.info.num_texture_formats;
  10.174 -    SDL_memcpy(renderer->info.texture_formats,
  10.175 -               NDS_RenderDriver.info.texture_formats,
  10.176 -               sizeof(renderer->info.texture_formats));
  10.177 -    renderer->info.max_texture_width =
  10.178 -        NDS_RenderDriver.info.max_texture_width;
  10.179 -    renderer->info.max_texture_height =
  10.180 -        NDS_RenderDriver.info.max_texture_height;
  10.181 -
  10.182 -    data->sub = 0;              /* TODO: this is hard-coded to the "main" screen.
  10.183 -                                   figure out how to detect whether to set it to
  10.184 -                                   "sub" screen.  window->id, perhaps? */
  10.185 -    data->bg_taken[2] = data->bg_taken[3] = 0;
  10.186 -
  10.187 -    return renderer;
  10.188 -}
  10.189 -
  10.190 -static int
  10.191 -NDS_ActivateRenderer(SDL_Renderer * renderer)
  10.192 -{
  10.193 -    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
  10.194 -
  10.195 -    return 0;
  10.196 -}
  10.197 -
  10.198 -static int
  10.199 -NDS_DisplayModeChanged(SDL_Renderer * renderer)
  10.200 -{
  10.201 -    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
  10.202 -
  10.203 -    return 0;
  10.204 -}
  10.205 -
  10.206 -static int
  10.207 -NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  10.208 -{
  10.209 -    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
  10.210 -    NDS_TextureData *txdat = NULL;
  10.211 -    int i;
  10.212 -    int bpp;
  10.213 -    Uint32 Rmask, Gmask, Bmask, Amask;
  10.214 -
  10.215 -    if (!SDL_PixelFormatEnumToMasks
  10.216 -        (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
  10.217 -        SDL_SetError("Unknown texture format");
  10.218 -        return -1;
  10.219 -    }
  10.220 -
  10.221 -    /* conditional statements on w/h to place it as bg/sprite
  10.222 -       depending on which one it fits. */
  10.223 -    if (texture->w <= 64 && texture->h <= 64) {
  10.224 -        int whichspr = -1;
  10.225 -        printf("NDS_CreateTexture: Tried to make a sprite.\n");
  10.226 -        txdat->type = NDSTX_SPR;
  10.227 -#if 0
  10.228 -        for (i = 0; i < SPRITE_COUNT; ++i) {
  10.229 -            if (data->oam_copy.spriteBuffer[i].attribute[0] & ATTR0_DISABLED) {
  10.230 -                whichspr = i;
  10.231 -                break;
  10.232 -            }
  10.233 -        }
  10.234 -        if (whichspr >= 0) {
  10.235 -            SpriteEntry *sprent = &(data->oam_copy.spriteBuffer[whichspr]);
  10.236 -            int maxside = texture->w > texture->h ? texture->w : texture->h;
  10.237 -            int pitch;
  10.238 -
  10.239 -            texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
  10.240 -            txdat = (NDS_TextureData *) texture->driverdata;
  10.241 -            if (!txdat) {
  10.242 -                SDL_OutOfMemory();
  10.243 -                return -1;
  10.244 -            }
  10.245 -
  10.246 -            sprent->objMode = OBJMODE_BITMAP;
  10.247 -            sprent->posX = 0;
  10.248 -            sprent->posY = 0;
  10.249 -            sprent->colMode = OBJCOLOR_16;      /* OBJCOLOR_256 for INDEX8 */
  10.250 -
  10.251 -            /* the first 32 sprites get transformation matrices.
  10.252 -               first come, first served */
  10.253 -            if (whichspr < MATRIX_COUNT) {
  10.254 -                sprent->isRotoscale = 1;
  10.255 -                sprent->rsMatrixIdx = whichspr;
  10.256 -            }
  10.257 -
  10.258 -            /* containing shape (square or 2:1 rectangles) */
  10.259 -            sprent->objShape = OBJSHAPE_SQUARE;
  10.260 -            if (texture->w / 2 >= texture->h) {
  10.261 -                sprent->objShape = OBJSHAPE_WIDE;
  10.262 -            } else if (texture->h / 2 >= texture->w) {
  10.263 -                sprent->objShape = OBJSHAPE_TALL;
  10.264 -            }
  10.265 -
  10.266 -            /* size in pixels */
  10.267 -            /* FIXME: "pitch" is hardcoded for 2bytes per pixel. */
  10.268 -            sprent->objSize = OBJSIZE_64;
  10.269 -            pitch = 128;
  10.270 -            if (maxside <= 8) {
  10.271 -                sprent->objSize = OBJSIZE_8;
  10.272 -                pitch = 16;
  10.273 -            } else if (maxside <= 16) {
  10.274 -                sprent->objSize = OBJSIZE_16;
  10.275 -                pitch = 32;
  10.276 -            } else if (maxside <= 32) {
  10.277 -                sprent->objSize = OBJSIZE_32;
  10.278 -                pitch = 64;
  10.279 -            }
  10.280 -
  10.281 -            /* FIXME: this is hard-coded and will obviously only work for one
  10.282 -               sprite-texture.  tells it to look at the beginning of SPRITE_GFX
  10.283 -               for its pixels. */
  10.284 -            sprent->tileIdx = 0;
  10.285 -
  10.286 -            /* now for the texture data */
  10.287 -            txdat->type = NDSTX_SPR;
  10.288 -            txdat->hw_index = whichspr;
  10.289 -            txdat->dim.hdx = 0x100;
  10.290 -            txdat->dim.hdy = 0;
  10.291 -            txdat->dim.vdx = 0;
  10.292 -            txdat->dim.vdy = 0x100;
  10.293 -            txdat->dim.pitch = pitch;
  10.294 -            txdat->dim.bpp = bpp;
  10.295 -            txdat->vram_pixels =
  10.296 -                (u16 *) (data->sub ? SPRITE_GFX_SUB : SPRITE_GFX);
  10.297 -            /* FIXME: use tileIdx*boundary
  10.298 -               to point to proper location */
  10.299 -        } else {
  10.300 -            SDL_SetError("Out of NDS sprites.");
  10.301 -        }
  10.302 -#endif
  10.303 -    } else if (texture->w <= 256 && texture->h <= 256) {
  10.304 -        int whichbg = -1, base = 0;
  10.305 -        if (!data->bg_taken[2]) {
  10.306 -            whichbg = 2;
  10.307 -        } else if (!data->bg_taken[3]) {
  10.308 -            whichbg = 3;
  10.309 -            base = 4;
  10.310 -        }
  10.311 -        if (whichbg >= 0) {
  10.312 -            texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
  10.313 -            txdat = (NDS_TextureData *) texture->driverdata;
  10.314 -            if (!txdat) {
  10.315 -                SDL_OutOfMemory();
  10.316 -                return -1;
  10.317 -            }
  10.318 -// hard-coded for 256x256 for now...
  10.319 -// TODO: a series of if-elseif-else's to find the closest but larger size.
  10.320 -            if (!data->sub) {
  10.321 -                if (bpp == 8) {
  10.322 -                    txdat->hw_index =
  10.323 -                        bgInit(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
  10.324 -                } else {
  10.325 -                    txdat->hw_index =
  10.326 -                        bgInit(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0,
  10.327 -                               0);
  10.328 -                }
  10.329 -            } else {
  10.330 -                if (bpp == 8) {
  10.331 -                    txdat->hw_index =
  10.332 -                        bgInitSub(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0,
  10.333 -                                  0);
  10.334 -                } else {
  10.335 -                    txdat->hw_index =
  10.336 -                        bgInitSub(whichbg, BgType_Bmp16, BgSize_B16_256x256,
  10.337 -                                  0, 0);
  10.338 -                }
  10.339 -            }
  10.340 -
  10.341 -/*   useful functions
  10.342 -        bgGetGfxPtr(bg3);            
  10.343 -		bgSetCenter(bg3, rcX, rcY);
  10.344 -		bgSetRotateScale(bg3, angle, scaleX, scaleY);
  10.345 -		bgSetScroll(bg3, scrollX, scrollY);
  10.346 -		bgUpdate(bg3);
  10.347 -*/
  10.348 -            txdat->type = NDSTX_BG;
  10.349 -            txdat->pitch = (texture->w) * ((bpp+1) / 8);
  10.350 -            txdat->bpp = bpp;
  10.351 -            txdat->rotate = 0;
  10.352 -            txdat->scale.x = 0x100;
  10.353 -            txdat->scale.y = 0x100;
  10.354 -            txdat->scroll.x = 0;
  10.355 -            txdat->scroll.y = 0;
  10.356 -            txdat->vram_pixels = (u16 *) bgGetGfxPtr(txdat->hw_index);
  10.357 -
  10.358 -            bgSetCenter(txdat->hw_index, 0, 0);
  10.359 -            bgSetRotateScale(txdat->hw_index, txdat->rotate, txdat->scale.x,
  10.360 -                             txdat->scale.y);
  10.361 -            bgSetScroll(txdat->hw_index, txdat->scroll.x, txdat->scroll.y);
  10.362 -            bgUpdate();
  10.363 -
  10.364 -            data->bg_taken[whichbg] = 1;
  10.365 -            /*txdat->size = txdat->dim.pitch * texture->h; */
  10.366 -        } else {
  10.367 -            SDL_SetError("Out of NDS backgrounds.");
  10.368 -        }
  10.369 -    } else {
  10.370 -        SDL_SetError("Texture too big for NDS hardware.");
  10.371 -    }
  10.372 -
  10.373 -    if (!texture->driverdata) {
  10.374 -        return -1;
  10.375 -    }
  10.376 -
  10.377 -    return 0;
  10.378 -}
  10.379 -
  10.380 -#if 0
  10.381 -static int
  10.382 -NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
  10.383 -                       void **pixels, int *pitch)
  10.384 -{
  10.385 -    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
  10.386 -    *pixels = txdat->vram_pixels;
  10.387 -    *pitch = txdat->pitch;
  10.388 -    return 0;
  10.389 -}
  10.390 -#endif
  10.391 -
  10.392 -static int
  10.393 -NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  10.394 -                  const SDL_Rect * rect, const void *pixels, int pitch)
  10.395 -{
  10.396 -    NDS_TextureData *txdat;
  10.397 -    Uint8 *src, *dst;
  10.398 -    int row;
  10.399 -    size_t length;
  10.400 -
  10.401 -    txdat = (NDS_TextureData *) texture->driverdata;
  10.402 -
  10.403 -    src = (Uint8 *) pixels;
  10.404 -    dst =
  10.405 -        (Uint8 *) txdat->vram_pixels + rect->y * txdat->pitch + rect->x *
  10.406 -        ((txdat->bpp + 1) / 8);
  10.407 -    length = rect->w * ((txdat->bpp + 1) / 8);
  10.408 -
  10.409 -    if (rect->w == texture->w) {
  10.410 -        dmaCopy(src, dst, length * rect->h);
  10.411 -    } else {
  10.412 -        for (row = 0; row < rect->h; ++row) {
  10.413 -            dmaCopy(src, dst, length);
  10.414 -            src += pitch;
  10.415 -            dst += txdat->pitch;
  10.416 -        }
  10.417 -    }
  10.418 -
  10.419 -    return 0;
  10.420 -}
  10.421 -
  10.422 -static int
  10.423 -NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  10.424 -                const SDL_Rect * rect, int markDirty, void **pixels,
  10.425 -                int *pitch)
  10.426 -{
  10.427 -    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
  10.428 -
  10.429 -    *pixels = (void *) ((u8 *) txdat->vram_pixels + rect->y * txdat->pitch +
  10.430 -                        rect->x * ((txdat->bpp + 1) / 8));
  10.431 -    *pitch = txdat->pitch;
  10.432 -
  10.433 -    return 0;
  10.434 -}
  10.435 -
  10.436 -static void
  10.437 -NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  10.438 -{
  10.439 -    /* stub! */
  10.440 -}
  10.441 -
  10.442 -static int
  10.443 -NDS_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
  10.444 -					int count)
  10.445 -{
  10.446 -    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
  10.447 -
  10.448 -    printf("NDS_RenderFill: stub\n");
  10.449 -
  10.450 -    /* TODO: make a single-color sprite and stretch it.
  10.451 -       calculate the "HDX" width modifier of the sprite by:
  10.452 -       let S be the actual sprite's width (like, 32 pixels for example)
  10.453 -       let R be the rectangle's width (maybe 50 pixels)
  10.454 -       HDX = (R<<8) / S;
  10.455 -       (it's fixed point, hence the bit shift.  same goes for vertical.
  10.456 -       be sure to use 32-bit int's for the bit shift before the division!)
  10.457 -     */
  10.458 -
  10.459 -    return 0;
  10.460 -}
  10.461 -
  10.462 -static int
  10.463 -NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
  10.464 -               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
  10.465 -{
  10.466 -    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
  10.467 -    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
  10.468 -    SDL_Window *window = renderer->window;
  10.469 -    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  10.470 -    int Bpp = SDL_BYTESPERPIXEL(texture->format);
  10.471 -
  10.472 -    if (txdat->type == NDSTX_BG) {
  10.473 -        txdat->scroll.x = dstrect->x;
  10.474 -        txdat->scroll.y = dstrect->y;
  10.475 -    } else {
  10.476 -        /* sprites not fully implemented yet */
  10.477 -        printf("NDS_RenderCopy: used sprite!\n");
  10.478 -//        SpriteEntry *spr = &(data->oam_copy.spriteBuffer[txdat->hw_index]);
  10.479 -//        spr->posX = dstrect->x;
  10.480 -//        spr->posY = dstrect->y;
  10.481 -//        if (txdat->hw_index < MATRIX_COUNT && spr->isRotoscale) {          
  10.482 -//        }
  10.483 -    }
  10.484 -
  10.485 -    return 0;
  10.486 -}
  10.487 -
  10.488 -
  10.489 -static void
  10.490 -NDS_RenderPresent(SDL_Renderer * renderer)
  10.491 -{
  10.492 -    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
  10.493 -    SDL_Window *window = renderer->window;
  10.494 -    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  10.495 -
  10.496 -    /* update sprites */
  10.497 -//    NDS_OAM_Update(&(data->oam_copy), data->sub);
  10.498 -    /* vsync for NDS */
  10.499 -    if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
  10.500 -        swiWaitForVBlank();
  10.501 -    }
  10.502 -}
  10.503 -
  10.504 -static void
  10.505 -NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  10.506 -{
  10.507 -    NDS_TextureData *txdat = texture->driverdata;
  10.508 -    /* free anything else allocated for texture */
  10.509 -    SDL_free(txdat);
  10.510 -}
  10.511 -
  10.512 -static void
  10.513 -NDS_DestroyRenderer(SDL_Renderer * renderer)
  10.514 -{
  10.515 -    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
  10.516 -    int i;
  10.517 -
  10.518 -    if (data) {
  10.519 -        /* free anything else relevant if anything else is allocated. */
  10.520 -        SDL_free(data);
  10.521 -    }
  10.522 -    SDL_free(renderer);
  10.523 -}
  10.524 -
  10.525 -/* vi: set ts=4 sw=4 expandtab: */
    11.1 --- a/src/video/nds/SDL_ndsrender_c.h	Sat Mar 05 10:03:57 2011 -0800
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,28 +0,0 @@
    11.4 -/*
    11.5 -    SDL - Simple DirectMedia Layer
    11.6 -    Copyright (C) 1997-2011 Sam Lantinga
    11.7 -
    11.8 -    This library is free software; you can redistribute it and/or
    11.9 -    modify it under the terms of the GNU Lesser General Public
   11.10 -    License as published by the Free Software Foundation; either
   11.11 -    version 2.1 of the License, or (at your option) any later version.
   11.12 -
   11.13 -    This library is distributed in the hope that it will be useful,
   11.14 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   11.16 -    Lesser General Public License for more details.
   11.17 -
   11.18 -    You should have received a copy of the GNU Lesser General Public
   11.19 -    License along with this library; if not, write to the Free Software
   11.20 -    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   11.21 -
   11.22 -    Sam Lantinga
   11.23 -    slouken@libsdl.org
   11.24 -*/
   11.25 -#include "SDL_config.h"
   11.26 -
   11.27 -/* SDL surface based renderer implementation */
   11.28 -
   11.29 -extern SDL_RenderDriver NDS_RenderDriver;
   11.30 -
   11.31 -/* vi: set ts=4 sw=4 expandtab: */
    12.1 --- a/src/video/nds/SDL_ndsvideo.c	Sat Mar 05 10:03:57 2011 -0800
    12.2 +++ b/src/video/nds/SDL_ndsvideo.c	Sun Mar 06 21:12:19 2011 -0800
    12.3 @@ -31,110 +31,135 @@
    12.4  #include <stdio.h>
    12.5  #include <stdlib.h>
    12.6  #include <nds.h>
    12.7 -#include <nds/arm9/video.h>
    12.8 +#include <fat.h>
    12.9 +#include <gl2d.h>
   12.10  
   12.11  #include "SDL_video.h"
   12.12 -#include "SDL_mouse.h"
   12.13 -#include "../SDL_sysvideo.h"
   12.14 -#include "../SDL_pixels_c.h"
   12.15 -#include "../../events/SDL_events_c.h"
   12.16 -#include "SDL_render.h"
   12.17  #include "SDL_ndsvideo.h"
   12.18  #include "SDL_ndsevents_c.h"
   12.19 +#include "../../render/SDL_sysrender.h"
   12.20 +#include "SDL_log.h"
   12.21  
   12.22  #define NDSVID_DRIVER_NAME "nds"
   12.23  
   12.24 -/* Per Window information. */
   12.25 -struct NDS_WindowData {
   12.26 -    int hw_index;               /* index of sprite in OAM or bg from libnds */
   12.27 -	int bg;						/* which bg is that attached to (2 or 3) */
   12.28 -    int pitch, bpp;             /* useful information about the texture */
   12.29 -    struct {
   12.30 -        int x, y;
   12.31 -    } scale;                    /* x/y stretch (24.8 fixed point) */
   12.32 -    struct {
   12.33 -        int x, y;
   12.34 -    } scroll;                   /* x/y offset */
   12.35 -    int rotate;                 /* -32768 to 32767, texture rotation */
   12.36 -    u16 *vram_pixels;           /* where the pixel data is stored (a pointer into VRAM) */
   12.37 +static SDL_DisplayMode display_modes[] =
   12.38 +{
   12.39 +	/* Only one screen */
   12.40 +	{
   12.41 +		.format = SDL_PIXELFORMAT_ABGR1555,
   12.42 +		.w = SCREEN_WIDTH,
   12.43 +		.h = SCREEN_HEIGHT,
   12.44 +		.refresh_rate = 60,
   12.45 +	},
   12.46 +
   12.47 +	/* Aggregated display (two screens) with no gap. */
   12.48 +	{
   12.49 +		.format = SDL_PIXELFORMAT_ABGR1555,
   12.50 +		.w = SCREEN_WIDTH,
   12.51 +		.h = 2*SCREEN_HEIGHT+SCREEN_GAP,
   12.52 +		.refresh_rate = 60,
   12.53 +	},
   12.54 +
   12.55 +	/* Aggregated display (two screens) with a gap. */
   12.56 +	{
   12.57 +		.format = SDL_PIXELFORMAT_ABGR1555,
   12.58 +		.w = SCREEN_WIDTH,
   12.59 +		.h = 2*SCREEN_HEIGHT,
   12.60 +		.refresh_rate = 60,
   12.61 +	},
   12.62 +
   12.63 +	/* Last entry */
   12.64 +	{
   12.65 +		.w = 0,
   12.66 +	}
   12.67  };
   12.68  
   12.69 -/* Per device information. */
   12.70 -struct NDS_DeviceData {
   12.71 -	int has_bg2;				/* backgroud 2 has been attached */
   12.72 -	int has_bg3;				/* backgroud 3 has been attached */
   12.73 -    int sub;
   12.74 -};
   12.75 +/* This function must not be optimized nor inlined, else the pointer
   12.76 + * to the message will be in the wrong register, and the emulator won't
   12.77 + * find the string. */
   12.78 +__attribute__ ((noinline, optimize (0)))
   12.79 +static void NDS_DebugOutput2(const char* message) 
   12.80 +{
   12.81 +#ifdef __thumb__
   12.82 +	asm volatile ("swi #0xfc");
   12.83 +#else
   12.84 +	asm volatile ("swi #0xfc0000");
   12.85 +#endif
   12.86 +}
   12.87  
   12.88 -/* Initialization/Query functions */
   12.89 -static int NDS_VideoInit(_THIS);
   12.90 -static int NDS_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
   12.91 -							  SDL_DisplayMode *mode);
   12.92 -static void NDS_VideoQuit(_THIS);
   12.93 -
   12.94 +static void NDS_DebugOutput(void *userdata, int category, SDL_LogPriority priority, const char *message)
   12.95 +{
   12.96 +	NDS_DebugOutput2(message);
   12.97 +}
   12.98  
   12.99  /* SDL NDS driver bootstrap functions */
  12.100 -static int
  12.101 -NDS_Available(void)
  12.102 +static int NDS_Available(void)
  12.103  {
  12.104 -    return (1);                 /* always here */
  12.105 +    return 1;                 /* always here */
  12.106  }
  12.107  
  12.108 -static int NDS_CreateWindowFramebuffer(_THIS, SDL_Window * window,
  12.109 -									   Uint32 * format, void ** pixels,
  12.110 +#ifndef USE_HW_RENDERER
  12.111 +static int NDS_CreateWindowFramebuffer(_THIS, SDL_Window *window,
  12.112 +									   Uint32 *format, void **pixels,
  12.113  									   int *pitch)
  12.114  {
  12.115 -	struct NDS_DeviceData *data = _this->driverdata;
  12.116  	struct NDS_WindowData *wdata;
  12.117      int bpp;
  12.118      Uint32 Rmask, Gmask, Bmask, Amask;
  12.119 -	int whichbg = -1;
  12.120 +	const SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  12.121 +	const SDL_DisplayMode *mode = display->driverdata;
  12.122 +	const Uint32 fmt = mode->format;
  12.123  
  12.124 -	*format = SDL_PIXELFORMAT_BGR555;
  12.125 +	if (fmt != SDL_PIXELFORMAT_ABGR1555) {
  12.126 +		SDL_SetError("Unsupported pixel format (%x)", fmt);
  12.127 +		return -1;
  12.128 +	}
  12.129  
  12.130      if (!SDL_PixelFormatEnumToMasks
  12.131 -        (*format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
  12.132 +        (fmt, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
  12.133          SDL_SetError("Unknown texture format");
  12.134          return -1;
  12.135      }
  12.136  
  12.137 -	if (!data->has_bg2)
  12.138 -		whichbg = 2;
  12.139 -	else if (!data->has_bg3)
  12.140 -		whichbg = 3;
  12.141 -	else {
  12.142 -		SDL_SetError("Out of NDS backgrounds.");
  12.143 -		return -1;
  12.144 -	}
  12.145 -
  12.146  	wdata = SDL_calloc(1, sizeof(struct NDS_WindowData));
  12.147  	if (!wdata) {
  12.148  		SDL_OutOfMemory();
  12.149  		return -1;
  12.150  	}
  12.151  
  12.152 -	if (!data->sub) {
  12.153 -		if (bpp == 8) {
  12.154 -			wdata->hw_index =
  12.155 -				bgInit(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
  12.156 -		} else {
  12.157 -			wdata->hw_index =
  12.158 -				bgInit(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0,
  12.159 -					   0);
  12.160 -		}
  12.161 +	if (bpp == 8) {
  12.162 +		wdata->pixels_length = (SCREEN_HEIGHT+SCREEN_GAP+SCREEN_HEIGHT)*SCREEN_WIDTH;
  12.163  	} else {
  12.164 -		if (bpp == 8) {
  12.165 -			wdata->hw_index =
  12.166 -				bgInitSub(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0,
  12.167 -						  0);
  12.168 -		} else {
  12.169 -			wdata->hw_index =
  12.170 -				bgInitSub(whichbg, BgType_Bmp16, BgSize_B16_256x256,
  12.171 -						  0, 0);
  12.172 -		}
  12.173 +		wdata->pixels_length = (SCREEN_HEIGHT+SCREEN_GAP+SCREEN_HEIGHT)*SCREEN_WIDTH*2;
  12.174 +	}
  12.175 +	wdata->pixels = SDL_calloc(1, wdata->pixels_length);
  12.176 +	if (!wdata->pixels) {
  12.177 +		SDL_free(wdata);
  12.178 +		SDL_SetError("Not enough memory");
  12.179 +        return -1;
  12.180 +    }
  12.181 +
  12.182 +	if (bpp == 8) {
  12.183 +		wdata->main.bg_id = bgInit(2, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
  12.184 +		wdata->sub.bg_id = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
  12.185 +
  12.186 +		wdata->main.length = SCREEN_HEIGHT*SCREEN_WIDTH;
  12.187 +		wdata->main.pixels = wdata->pixels;
  12.188 +
  12.189 +		wdata->sub.length = SCREEN_HEIGHT*SCREEN_WIDTH;
  12.190 +		wdata->sub.pixels = (u8 *)wdata->pixels + wdata->main.length;	/* or ...+SCREEN_GAP */
  12.191 +			
  12.192 +	} else {
  12.193 +		wdata->main.bg_id = bgInit(2, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
  12.194 +		wdata->sub.bg_id = bgInitSub(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
  12.195 +
  12.196 +		wdata->main.length = SCREEN_HEIGHT*SCREEN_WIDTH*2;
  12.197 +		wdata->main.pixels = wdata->pixels;
  12.198 +
  12.199 +		wdata->sub.length = SCREEN_HEIGHT*SCREEN_WIDTH*2;
  12.200 +		wdata->sub.pixels = (u8 *)wdata->pixels + wdata->main.length;	/* or ...+SCREEN_GAP */
  12.201  	}
  12.202  
  12.203 -	wdata->bg = whichbg;
  12.204  	wdata->pitch = (window->w) * ((bpp+1) / 8);
  12.205  	wdata->bpp = bpp;
  12.206  	wdata->rotate = 0;
  12.207 @@ -142,22 +167,30 @@
  12.208  	wdata->scale.y = 0x100;
  12.209  	wdata->scroll.x = 0;
  12.210  	wdata->scroll.y = 0;
  12.211 -	wdata->vram_pixels = (u16 *) bgGetGfxPtr(wdata->hw_index);
  12.212 +
  12.213 +	wdata->main.vram_pixels = bgGetGfxPtr(wdata->main.bg_id);
  12.214 +	wdata->sub.vram_pixels = bgGetGfxPtr(wdata->sub.bg_id);
  12.215  
  12.216 -	bgSetCenter(wdata->hw_index, 0, 0);
  12.217 -	bgSetRotateScale(wdata->hw_index, wdata->rotate, wdata->scale.x,
  12.218 +#if 0
  12.219 +	bgSetCenter(wdata->main.bg_id, 0, 0);
  12.220 +	bgSetRotateScale(wdata->main.bg_id, wdata->rotate, wdata->scale.x,
  12.221  					 wdata->scale.y);
  12.222 -	bgSetScroll(wdata->hw_index, wdata->scroll.x, wdata->scroll.y);
  12.223 +	bgSetScroll(wdata->main.bg_id, wdata->scroll.x, wdata->scroll.y);
  12.224 +#endif
  12.225 +
  12.226 +#if 0
  12.227 +	bgSetCenter(wdata->sub.bg_id, 0, 0);
  12.228 +	bgSetRotateScale(wdata->sub.bg_id, wdata->rotate, wdata->scale.x,
  12.229 +					 wdata->scale.y);
  12.230 +	bgSetScroll(wdata->sub.bg_id, wdata->scroll.x, wdata->scroll.y);
  12.231 +#endif
  12.232 +
  12.233  	bgUpdate();
  12.234  
  12.235 -	*pixels = wdata->vram_pixels;
  12.236 +	*format = fmt;
  12.237 +	*pixels = wdata->pixels;
  12.238  	*pitch = wdata->pitch;
  12.239  
  12.240 -	if (!data->has_bg2)
  12.241 -		data->has_bg2 = 1;
  12.242 -	else 
  12.243 -		data->has_bg3 = 1;
  12.244 -
  12.245  	window->driverdata = wdata;
  12.246  
  12.247  	return 0;
  12.248 @@ -166,35 +199,163 @@
  12.249  static int NDS_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
  12.250  									   SDL_Rect * rects, int numrects)
  12.251  {
  12.252 -	/* Nothing to do because writes are done directly into the
  12.253 -	 * framebuffer. */
  12.254 +	struct NDS_WindowData *wdata = window->driverdata;
  12.255 +
  12.256 +	/* Copy everything. TODO: use rects/numrects. */
  12.257 +	DC_FlushRange(wdata->pixels, wdata->pixels_length);
  12.258 +
  12.259 +	swiWaitForVBlank();
  12.260 +
  12.261 +	dmaCopy(wdata->main.pixels, wdata->main.vram_pixels, wdata->main.length);
  12.262 +	dmaCopy(wdata->sub.pixels, wdata->sub.vram_pixels, wdata->sub.length);
  12.263 +
  12.264      return 0;
  12.265  }
  12.266  
  12.267 -static void NDS_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
  12.268 +static void NDS_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
  12.269  {
  12.270 -	struct NDS_DeviceData *data = _this->driverdata;
  12.271      struct NDS_WindowData *wdata = window->driverdata;
  12.272  
  12.273 -	if (wdata->bg == 2)
  12.274 -		data->has_bg2 = 0;
  12.275 -	else
  12.276 -		data->has_bg3 = 0;
  12.277 -
  12.278 +    SDL_free(wdata->pixels);
  12.279      SDL_free(wdata);
  12.280  }
  12.281 +#endif
  12.282  
  12.283 -static void
  12.284 -NDS_DeleteDevice(SDL_VideoDevice * device)
  12.285 +#ifdef USE_HW_RENDERER
  12.286 +/* Set up a 2D layer construced of bitmap sprites. This holds the
  12.287 + * image when rendering to the top screen. From libnds example. 
  12.288 + */
  12.289 +static void initSubSprites(void)
  12.290 +{
  12.291 +    oamInit(&oamSub, SpriteMapping_Bmp_2D_256, false);
  12.292 + 
  12.293 +    int x = 0;
  12.294 +    int y = 0;
  12.295 + 
  12.296 +    int id = 0;
  12.297 +
  12.298 +    //set up a 4x3 grid of 64x64 sprites to cover the screen
  12.299 +    for(y = 0; y < 3; y++)
  12.300 +    for(x = 0; x < 4; x++)
  12.301 +    {
  12.302 +        oamSub.oamMemory[id].attribute[0] = ATTR0_BMP | ATTR0_SQUARE | (64 * y);
  12.303 +        oamSub.oamMemory[id].attribute[1] = ATTR1_SIZE_64 | (64 * x);
  12.304 +        oamSub.oamMemory[id].attribute[2] = ATTR2_ALPHA(1) | (8 * 32 * y) | (8 * x);
  12.305 +        id++;
  12.306 +    }
  12.307 + 
  12.308 +    swiWaitForVBlank();
  12.309 + 
  12.310 +    oamUpdate(&oamSub);
  12.311 +}
  12.312 +#endif
  12.313 +
  12.314 +static int NDS_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
  12.315 +{
  12.316 +	display->driverdata = mode->driverdata;
  12.317 +
  12.318 +#ifdef USE_HW_RENDERER
  12.319 +
  12.320 +	videoSetMode(MODE_5_3D);
  12.321 +	videoSetModeSub(MODE_5_2D);
  12.322 +
  12.323 +	/* initialize gl2d */
  12.324 +	glScreen2D();
  12.325 +	
  12.326 +    vramSetBankA(VRAM_A_TEXTURE);
  12.327 +	vramSetBankB(VRAM_B_TEXTURE );
  12.328 +    vramSetBankC(VRAM_C_SUB_BG_0x06200000);
  12.329 +	vramSetBankE(VRAM_E_TEX_PALETTE);
  12.330 +
  12.331 +    powerOn(POWER_ALL_2D);
  12.332 +
  12.333 +    irqInit();
  12.334 +    irqEnable(IRQ_VBLANK);
  12.335 +
  12.336 +    // sub sprites hold the bottom image when 3D directed to top
  12.337 +    initSubSprites();
  12.338 + 
  12.339 +    // sub background holds the top image when 3D directed to bottom
  12.340 +    bgInitSub(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
  12.341 +#else
  12.342 +
  12.343 +	/* Select mode 5 for both screens. Can do Extended Rotation
  12.344 +	 * Background on both (BG 2 and 3). */
  12.345 +	videoSetMode(MODE_5_2D);
  12.346 +	videoSetModeSub(MODE_5_2D);
  12.347 +
  12.348 +    vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
  12.349 +	vramSetBankB(VRAM_B_TEXTURE );
  12.350 +    vramSetBankC(VRAM_C_SUB_BG_0x06200000);
  12.351 +	vramSetBankE(VRAM_E_TEX_PALETTE);
  12.352 +
  12.353 +    powerOn(POWER_ALL_2D);
  12.354 +
  12.355 +    irqInit();
  12.356 +    irqEnable(IRQ_VBLANK);
  12.357 +
  12.358 +#endif
  12.359 +
  12.360 +    return 0;
  12.361 +}
  12.362 +
  12.363 +void NDS_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
  12.364 +{
  12.365 +    SDL_DisplayMode *mode;
  12.366 +
  12.367 +	for (mode = display_modes; mode->w; mode++) {
  12.368 +		mode->driverdata = mode; /* point back to self */
  12.369 +		SDL_AddDisplayMode(display, mode);
  12.370 +	}
  12.371 +}
  12.372 +
  12.373 +static int NDS_VideoInit(_THIS)
  12.374 +{
  12.375 +	SDL_VideoDisplay display;
  12.376 +    SDL_DisplayMode mode;
  12.377 +
  12.378 +	SDL_zero(mode);
  12.379 +
  12.380 +    mode.format = SDL_PIXELFORMAT_UNKNOWN; // shoud be SDL_PIXELFORMAT_ABGR1555;
  12.381 +    mode.w = SCREEN_WIDTH;
  12.382 +    mode.h = 2*SCREEN_HEIGHT+SCREEN_GAP;
  12.383 +    mode.refresh_rate = 60;
  12.384 +
  12.385 +	SDL_zero(display);
  12.386 +
  12.387 +	display.desktop_mode = mode;
  12.388 +
  12.389 +	SDL_AddVideoDisplay(&display);
  12.390 +
  12.391 +    return 0;
  12.392 +}
  12.393 +
  12.394 +static void NDS_VideoQuit(_THIS)
  12.395 +{
  12.396 +    videoSetMode(DISPLAY_SCREEN_OFF);
  12.397 +    videoSetModeSub(DISPLAY_SCREEN_OFF);
  12.398 +    vramSetBankA(VRAM_A_LCD);
  12.399 +    vramSetBankB(VRAM_B_LCD);
  12.400 +    vramSetBankC(VRAM_C_LCD);
  12.401 +    vramSetBankD(VRAM_D_LCD);
  12.402 +    vramSetBankE(VRAM_E_LCD);
  12.403 +    vramSetBankF(VRAM_F_LCD);
  12.404 +    vramSetBankG(VRAM_G_LCD);
  12.405 +    vramSetBankH(VRAM_H_LCD);
  12.406 +    vramSetBankI(VRAM_I_LCD);
  12.407 +}
  12.408 +
  12.409 +static void NDS_DeleteDevice(SDL_VideoDevice * device)
  12.410  {
  12.411      SDL_free(device);
  12.412  }
  12.413  
  12.414 -static SDL_VideoDevice *
  12.415 -NDS_CreateDevice(int devindex)
  12.416 +static SDL_VideoDevice *NDS_CreateDevice(int devindex)
  12.417  {
  12.418      SDL_VideoDevice *device;
  12.419  
  12.420 +    fatInitDefault();
  12.421 +
  12.422      /* Initialize all variables that we clean on shutdown */
  12.423      device = SDL_calloc(1, sizeof(SDL_VideoDevice));
  12.424      if (!device) {
  12.425 @@ -212,15 +373,20 @@
  12.426      /* Set the function pointers */
  12.427      device->VideoInit = NDS_VideoInit;
  12.428      device->VideoQuit = NDS_VideoQuit;
  12.429 +	device->GetDisplayModes = NDS_GetDisplayModes;
  12.430      device->SetDisplayMode = NDS_SetDisplayMode;
  12.431      device->PumpEvents = NDS_PumpEvents;
  12.432 +#ifndef USE_HW_RENDERER
  12.433  	device->CreateWindowFramebuffer = NDS_CreateWindowFramebuffer;
  12.434  	device->UpdateWindowFramebuffer = NDS_UpdateWindowFramebuffer;
  12.435  	device->DestroyWindowFramebuffer = NDS_DestroyWindowFramebuffer;
  12.436 +#endif
  12.437 +    device->free = NDS_DeleteDevice;
  12.438  
  12.439 -    device->num_displays = 2;   /* DS = dual screens */
  12.440 -
  12.441 -    device->free = NDS_DeleteDevice;
  12.442 +	/* Set the debug output. Use only for under an emulator. Will crash the DS. */
  12.443 +#if 1
  12.444 +	SDL_LogSetOutputFunction(NDS_DebugOutput, NULL);
  12.445 +#endif
  12.446  
  12.447      return device;
  12.448  }
  12.449 @@ -230,71 +396,4 @@
  12.450      NDS_Available, NDS_CreateDevice
  12.451  };
  12.452  
  12.453 -int
  12.454 -NDS_VideoInit(_THIS)
  12.455 -{
  12.456 -    SDL_DisplayMode mode;
  12.457 -
  12.458 -    /* simple 256x192x16x60 for now */
  12.459 -    mode.w = 256;
  12.460 -    mode.h = 192;
  12.461 -    mode.format = SDL_PIXELFORMAT_ABGR1555;
  12.462 -    mode.refresh_rate = 60;
  12.463 -    mode.driverdata = NULL;
  12.464 -
  12.465 -    if (SDL_AddBasicVideoDisplay(&mode) < 0) {
  12.466 -        return -1;
  12.467 -    }
  12.468 -
  12.469 -    SDL_zero(mode);
  12.470 -	SDL_AddDisplayMode(&_this->displays[0], &mode);
  12.471 -
  12.472 -    powerOn(POWER_ALL_2D);
  12.473 -    irqEnable(IRQ_VBLANK);
  12.474 -    NDS_SetDisplayMode(_this, &_this->displays[0], &mode);
  12.475 -
  12.476 -    return 0;
  12.477 -}
  12.478 -
  12.479 -static int
  12.480 -NDS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
  12.481 -{
  12.482 -    /* right now this function is just hard-coded for 256x192 ABGR1555 */
  12.483 -    videoSetMode(MODE_5_2D | DISPLAY_BG2_ACTIVE | DISPLAY_BG3_ACTIVE | DISPLAY_BG_EXT_PALETTE | DISPLAY_SPR_1D_LAYOUT | DISPLAY_SPR_1D_BMP | DISPLAY_SPR_1D_BMP_SIZE_256 |      /* (try 128 if 256 is trouble.) */
  12.484 -                 DISPLAY_SPR_ACTIVE | DISPLAY_SPR_EXT_PALETTE); /* display on main core
  12.485 -                                                                   with lots of flags set for
  12.486 -                                                                   flexibility/capacity to render */
  12.487 -
  12.488 -    /* hopefully these cover all the various things we might need to do */
  12.489 -    vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
  12.490 -    vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
  12.491 -    vramSetBankC(VRAM_C_SUB_BG_0x06200000);
  12.492 -    vramSetBankD(VRAM_D_MAIN_BG_0x06040000);    /* not a typo. vram d can't sub */
  12.493 -    vramSetBankE(VRAM_E_MAIN_SPRITE);
  12.494 -    vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE);
  12.495 -    vramSetBankG(VRAM_G_BG_EXT_PALETTE);
  12.496 -    vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
  12.497 -    vramSetBankI(VRAM_I_SUB_SPRITE);
  12.498 -
  12.499 -    videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);    /* debug text on sub
  12.500 -                                                           TODO: this will change
  12.501 -                                                           when multi-head is
  12.502 -                                                           introduced in render */
  12.503 -
  12.504 -    return 0;
  12.505 -}
  12.506 -
  12.507 -void
  12.508 -NDS_VideoQuit(_THIS)
  12.509 -{
  12.510 -    videoSetMode(DISPLAY_SCREEN_OFF);
  12.511 -    videoSetModeSub(DISPLAY_SCREEN_OFF);
  12.512 -    vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
  12.513 -    vramSetBankE(VRAM_E_LCD);
  12.514 -    vramSetBankF(VRAM_F_LCD);
  12.515 -    vramSetBankG(VRAM_G_LCD);
  12.516 -    vramSetBankH(VRAM_H_LCD);
  12.517 -    vramSetBankI(VRAM_I_LCD);
  12.518 -}
  12.519 -
  12.520  /* vi: set ts=4 sw=4 expandtab: */
    13.1 --- a/src/video/nds/SDL_ndsvideo.h	Sat Mar 05 10:03:57 2011 -0800
    13.2 +++ b/src/video/nds/SDL_ndsvideo.h	Sun Mar 06 21:12:19 2011 -0800
    13.3 @@ -26,6 +26,33 @@
    13.4  
    13.5  #include "../SDL_sysvideo.h"
    13.6  
    13.7 +#define SCREEN_GAP 92			/* line-equivalent gap between the 2 screens  */
    13.8 +
    13.9 +/* Per Window information. */
   13.10 +struct NDS_WindowData {
   13.11 +	struct {
   13.12 +		int bg_id;
   13.13 +		void *vram_pixels;           /* where the pixel data is stored (a pointer into VRAM) */
   13.14 +		void *pixels;				 /* area in user frame buffer */
   13.15 +		int length;
   13.16 +	} main, sub;
   13.17 +
   13.18 +    int pitch, bpp;             /* useful information about the texture */
   13.19 +    struct {
   13.20 +        int x, y;
   13.21 +    } scale;                    /* x/y stretch (24.8 fixed point) */
   13.22 +
   13.23 +    struct {
   13.24 +        int x, y;
   13.25 +    } scroll;                   /* x/y offset */
   13.26 +    int rotate;                 /* -32768 to 32767, texture rotation */
   13.27 +
   13.28 +	/* user frame buffer - todo: better way to do double buffering */
   13.29 +	void *pixels;
   13.30 +	int pixels_length;
   13.31 +};
   13.32 +
   13.33 +
   13.34  #endif /* _SDL_ndsvideo_h */
   13.35  
   13.36  /* vi: set ts=4 sw=4 expandtab: */