2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2011 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SDL_config.h"
24 /* SDL Nintendo DS video driver implementation
25 * based on dummy driver:
26 * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion
27 * of this was cut-and-pasted from Stephane Peter's work in the AAlib
28 * SDL video driver. Renamed to "DUMMY" by Sam Lantinga.
34 #include <nds/arm9/video.h>
36 #include "SDL_video.h"
37 #include "SDL_mouse.h"
38 #include "../SDL_sysvideo.h"
39 #include "../SDL_pixels_c.h"
40 #include "../../events/SDL_events_c.h"
41 #include "SDL_render.h"
42 #include "SDL_ndsvideo.h"
43 #include "SDL_ndsevents_c.h"
45 #define NDSVID_DRIVER_NAME "nds"
47 /* Per Window information. */
48 struct NDS_WindowData {
49 int hw_index; /* index of sprite in OAM or bg from libnds */
50 int bg; /* which bg is that attached to (2 or 3) */
51 int pitch, bpp; /* useful information about the texture */
54 } scale; /* x/y stretch (24.8 fixed point) */
57 } scroll; /* x/y offset */
58 int rotate; /* -32768 to 32767, texture rotation */
59 u16 *vram_pixels; /* where the pixel data is stored (a pointer into VRAM) */
62 /* Per device information. */
63 struct NDS_DeviceData {
64 int has_bg2; /* backgroud 2 has been attached */
65 int has_bg3; /* backgroud 3 has been attached */
69 /* Initialization/Query functions */
70 static int NDS_VideoInit(_THIS);
71 static int NDS_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
72 SDL_DisplayMode *mode);
73 static void NDS_VideoQuit(_THIS);
76 /* SDL NDS driver bootstrap functions */
80 return (1); /* always here */
83 static int NDS_CreateWindowFramebuffer(_THIS, SDL_Window * window,
84 Uint32 * format, void ** pixels,
87 struct NDS_DeviceData *data = _this->driverdata;
88 struct NDS_WindowData *wdata;
90 Uint32 Rmask, Gmask, Bmask, Amask;
93 *format = SDL_PIXELFORMAT_BGR555;
95 if (!SDL_PixelFormatEnumToMasks
96 (*format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
97 SDL_SetError("Unknown texture format");
103 else if (!data->has_bg3)
106 SDL_SetError("Out of NDS backgrounds.");
110 wdata = SDL_calloc(1, sizeof(struct NDS_WindowData));
119 bgInit(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
122 bgInit(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0,
128 bgInitSub(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0,
132 bgInitSub(whichbg, BgType_Bmp16, BgSize_B16_256x256,
138 wdata->pitch = (window->w) * ((bpp+1) / 8);
141 wdata->scale.x = 0x100;
142 wdata->scale.y = 0x100;
145 wdata->vram_pixels = (u16 *) bgGetGfxPtr(wdata->hw_index);
147 bgSetCenter(wdata->hw_index, 0, 0);
148 bgSetRotateScale(wdata->hw_index, wdata->rotate, wdata->scale.x,
150 bgSetScroll(wdata->hw_index, wdata->scroll.x, wdata->scroll.y);
153 *pixels = wdata->vram_pixels;
154 *pitch = wdata->pitch;
161 window->driverdata = wdata;
166 static int NDS_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
167 SDL_Rect * rects, int numrects)
169 /* Nothing to do because writes are done directly into the
174 static void NDS_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
176 struct NDS_DeviceData *data = _this->driverdata;
177 struct NDS_WindowData *wdata = window->driverdata;
188 NDS_DeleteDevice(SDL_VideoDevice * device)
193 static SDL_VideoDevice *
194 NDS_CreateDevice(int devindex)
196 SDL_VideoDevice *device;
198 /* Initialize all variables that we clean on shutdown */
199 device = SDL_calloc(1, sizeof(SDL_VideoDevice));
205 device->driverdata = SDL_calloc(1, sizeof(SDL_VideoDevice));
212 /* Set the function pointers */
213 device->VideoInit = NDS_VideoInit;
214 device->VideoQuit = NDS_VideoQuit;
215 device->SetDisplayMode = NDS_SetDisplayMode;
216 device->PumpEvents = NDS_PumpEvents;
217 device->CreateWindowFramebuffer = NDS_CreateWindowFramebuffer;
218 device->UpdateWindowFramebuffer = NDS_UpdateWindowFramebuffer;
219 device->DestroyWindowFramebuffer = NDS_DestroyWindowFramebuffer;
221 device->num_displays = 2; /* DS = dual screens */
223 device->free = NDS_DeleteDevice;
228 VideoBootStrap NDS_bootstrap = {
229 NDSVID_DRIVER_NAME, "SDL NDS video driver",
230 NDS_Available, NDS_CreateDevice
236 SDL_DisplayMode mode;
238 /* simple 256x192x16x60 for now */
241 mode.format = SDL_PIXELFORMAT_ABGR1555;
242 mode.refresh_rate = 60;
243 mode.driverdata = NULL;
245 if (SDL_AddBasicVideoDisplay(&mode) < 0) {
250 SDL_AddDisplayMode(&_this->displays[0], &mode);
252 powerOn(POWER_ALL_2D);
253 irqEnable(IRQ_VBLANK);
254 NDS_SetDisplayMode(_this, &_this->displays[0], &mode);
260 NDS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
262 /* right now this function is just hard-coded for 256x192 ABGR1555 */
263 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.) */
264 DISPLAY_SPR_ACTIVE | DISPLAY_SPR_EXT_PALETTE); /* display on main core
265 with lots of flags set for
266 flexibility/capacity to render */
268 /* hopefully these cover all the various things we might need to do */
269 vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
270 vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
271 vramSetBankC(VRAM_C_SUB_BG_0x06200000);
272 vramSetBankD(VRAM_D_MAIN_BG_0x06040000); /* not a typo. vram d can't sub */
273 vramSetBankE(VRAM_E_MAIN_SPRITE);
274 vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE);
275 vramSetBankG(VRAM_G_BG_EXT_PALETTE);
276 vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
277 vramSetBankI(VRAM_I_SUB_SPRITE);
279 videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); /* debug text on sub
280 TODO: this will change
282 introduced in render */
290 videoSetMode(DISPLAY_SCREEN_OFF);
291 videoSetModeSub(DISPLAY_SCREEN_OFF);
292 vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
293 vramSetBankE(VRAM_E_LCD);
294 vramSetBankF(VRAM_F_LCD);
295 vramSetBankG(VRAM_G_LCD);
296 vramSetBankH(VRAM_H_LCD);
297 vramSetBankI(VRAM_I_LCD);
300 /* vi: set ts=4 sw=4 expandtab: */