# HG changeset patch # User Darren Alton # Date 1216489039 0 # Node ID 4135aa9c56455db505f63927bc7d499fae1f5c42 # Parent bc3e3e889f6d5fa753b22602a2fa5fd0e07216ec More work on the accelerated 2D video driver, beginnings of sprite-based rendering support. Also some initial work on an audio driver. diff -r bc3e3e889f6d -r 4135aa9c5645 Makefile.ds --- a/Makefile.ds Sun Jul 13 04:28:54 2008 +0000 +++ b/Makefile.ds Sat Jul 19 17:37:19 2008 +0000 @@ -31,6 +31,7 @@ src/SDL_fatal.c \ src/audio/disk/SDL_diskaudio.c \ src/audio/dummy/SDL_dummyaudio.c \ +src/audio/nds/SDL_ndsaudio.c \ src/audio/SDL_audio.c \ src/audio/SDL_audiocvt.c \ src/audio/SDL_audiodev.c \ diff -r bc3e3e889f6d -r 4135aa9c5645 include/SDL_config_nintendods.h --- a/include/SDL_config_nintendods.h Sun Jul 13 04:28:54 2008 +0000 +++ b/include/SDL_config_nintendods.h Sat Jul 19 17:37:19 2008 +0000 @@ -92,14 +92,15 @@ #define LACKS_SYS_MMAN_H 1 /* Enable various audio drivers */ -#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_NDS 1 +/*#define SDL_AUDIO_DRIVER_DUMMY 1 TODO: uncomment this later*/ /* DS doesn't have optical media */ #define SDL_CDROM_DISABLED 1 /* Enable various input drivers */ #define SDL_JOYSTICK_NDS 1 -/*#define SDL_JOYSTICK_DUMMY 1*/ +/*#define SDL_JOYSTICK_DUMMY 1 TODO: uncomment this later*/ /* DS has no dynamic linking afaik */ #define SDL_LOADSO_DISABLED 1 @@ -113,6 +114,6 @@ /* Enable various video drivers */ #define SDL_VIDEO_DRIVER_NDS 1 -#define SDL_VIDEO_DRIVER_DUMMY 1 +/*#define SDL_VIDEO_DRIVER_DUMMY 1 TODO: uncomment this later*/ #endif /* _SDL_config_nintendods_h */ diff -r bc3e3e889f6d -r 4135aa9c5645 src/audio/SDL_audio.c --- a/src/audio/SDL_audio.c Sun Jul 13 04:28:54 2008 +0000 +++ b/src/audio/SDL_audio.c Sat Jul 19 17:37:19 2008 +0000 @@ -70,6 +70,7 @@ extern AudioBootStrap DCAUD_bootstrap; extern AudioBootStrap MMEAUDIO_bootstrap; extern AudioBootStrap DART_bootstrap; +extern AudioBootStrap NDSAUD_bootstrap; /* Available audio drivers */ @@ -145,6 +146,9 @@ #if SDL_AUDIO_DRIVER_DART &DART_bootstrap, #endif +#if SDL_AUDIO_DRIVER_NDS + &NDSAUD_bootstrap, +#endif NULL }; diff -r bc3e3e889f6d -r 4135aa9c5645 src/audio/nds/SDL_ndsaudio.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audio/nds/SDL_ndsaudio.c Sat Jul 19 17:37:19 2008 +0000 @@ -0,0 +1,92 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org + + This file written by Ryan C. Gordon (icculus@icculus.org) +*/ +#include "SDL_config.h" + +/* Output audio to NDS */ + +#include + +#include "SDL_audio.h" +#include "../SDL_audio_c.h" +#include "SDL_ndsaudio.h" + +static int +NDSAUD_OpenDevice(_THIS, const char *devname, int iscapture) +{ + return 1; /* always succeeds. */ +} + +static void +NDSAUD_PlayDevice(_THIS) +{ + TransferSoundData* sound = SDL_malloc(sizeof(TransferSoundData)); + if(!sound) { + SDL_OutOfMemory(); + } + sound->data = NULL; /* pointer to raw audio data */ + sound->len = 0; /* size of raw data pointed to above */ + sound->rate = 22050; /* sample rate = 22050Hz */ + sound->vol = 127; /* volume [0..127] for [min..max] */ + sound->pan = 64; /* balance [0..127] for [left..right] */ + sound->format = 0; /* 0 for 16-bit, 1 for 8-bit */ + /* stub */ +} + + +static Uint8 * +NDSAUD_GetDeviceBuf(_THIS) +{ + /* stub */ +} + +static void +NDSAUD_WaitDevice(_THIS) +{ + /* stub */ +} + +static void +NDSAUD_CloseDevice(_THIS) +{ + /* stub */ +} + +static int +NDSAUD_Init(SDL_AudioDriverImpl * impl) +{ + /* Set the function pointers */ + impl->OpenDevice = NDSAUD_OpenDevice; + impl->PlayDevice = NDSAUD_PlayDevice; + impl->WaitDevice = NDSAUD_WaitDevice; + impl->GetDeviceBuf = NDSAUD_GetDeviceBuf; + impl->CloseDevice = NDSAUD_CloseDevice; + impl->OnlyHasDefaultOutputDevice = 1; + return 1; +} + +AudioBootStrap NDSAUD_bootstrap = { + "nds", "SDL NDS audio driver", NDSAUD_Init, 1 +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff -r bc3e3e889f6d -r 4135aa9c5645 src/audio/nds/SDL_ndsaudio.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audio/nds/SDL_ndsaudio.h Sat Jul 19 17:37:19 2008 +0000 @@ -0,0 +1,42 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_ndsaudio_h +#define _SDL_ndsaudio_h + +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData +{ + /* The file descriptor for the audio device */ + Uint8 *mixbuf; + Uint32 mixlen; + Uint32 write_delay; + Uint32 initial_calls; +}; + +#endif /* _SDL_ndsaudio_h */ +/* vi: set ts=4 sw=4 expandtab: */ diff -r bc3e3e889f6d -r 4135aa9c5645 src/video/nds/SDL_ndsrender.c --- a/src/video/nds/SDL_ndsrender.c Sun Jul 13 04:28:54 2008 +0000 +++ b/src/video/nds/SDL_ndsrender.c Sat Jul 19 17:37:19 2008 +0000 @@ -159,6 +159,7 @@ /* Uint32 Rmask = 0x7C00, Gmask = 0x03E0, Bmask = 0x001F, Amask = 0x8000; Uint32 Rmask = 0x001F, Gmask = 0x03E0, Bmask = 0x7C00, Amask = 0x8000; */ +printf("+NDS_CreateRenderer\n"); /* hard coded this to BGR555 for now */ if (!SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_BGR555, &bpp, @@ -220,6 +221,7 @@ data->bg_taken[2] = data->bg_taken[3] = 0; data->sub = 0; +printf("-NDS_CreateRenderer\n"); return renderer; } @@ -228,6 +230,7 @@ { NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; /* stub. TODO: figure out what needs to be done, if anything. */ +printf("!NDS_ActivateRenderer\n"); return 0; } @@ -236,6 +239,7 @@ { NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; /* stub. TODO: figure out what needs to be done */ +printf("!NDS_DisplayModeChanged\n"); return 0; } @@ -244,6 +248,7 @@ { NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; NDS_TextureData *txdat = NULL; +printf("+NDS_CreateTexture\n"); if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("Unsupported texture format"); return -1; @@ -301,6 +306,7 @@ } } +printf("-NDS_CreateTexture\n"); if (!texture->driverdata) { return -1; } @@ -311,6 +317,7 @@ NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, void **pixels, int *pitch) { +printf("+NDS_QueryTexturePixels\n"); if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("Unsupported texture format"); return -1; @@ -319,6 +326,7 @@ *pixels = txdat->vram; *pitch = txdat->dim.pitch; +printf("-NDS_QueryTexturePixels\n"); return 0; } } @@ -327,12 +335,14 @@ NDS_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Color * colors, int firstcolor, int ncolors) { +printf("+NDS_SetTexturePalette\n"); if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("YUV textures don't have a palette"); return -1; } else { NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; /* TODO: mess with 8-bit modes and/or 16-color palette modes */ +printf("-NDS_SetTexturePalette\n"); return 0; } } @@ -341,11 +351,13 @@ NDS_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Color * colors, int firstcolor, int ncolors) { +printf("+NDS_GetTexturePalette\n"); if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("YUV textures don't have a palette"); return -1; } else { NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; +printf("-NDS_GetTexturePalette\n"); /* TODO: mess with 8-bit modes and/or 16-color palette modes */ return 0; } @@ -354,6 +366,7 @@ static int NDS_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) { +printf("!NDS_SetTextureColorMod\n"); /* stub. TODO: figure out what needs to be done, if anything */ return 0; } @@ -361,6 +374,7 @@ static int NDS_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) { +printf("!NDS_SetTextureAlphaMod\n"); /* stub. TODO: figure out what needs to be done, if anything */ return 0; } @@ -368,6 +382,7 @@ static int NDS_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) { +printf("!NDS_SetTextureBlendMode\n"); /* stub. TODO: figure out what needs to be done, if anything */ return 0; } @@ -375,6 +390,7 @@ static int NDS_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) { +printf("!NDS_SetTextureScaleMode\n"); /* stub. TODO: figure out what needs to be done. (NDS hardware scaling is nearest neighbor.) */ return 0; @@ -384,6 +400,7 @@ NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { +printf("+NDS_UpdateTexture\n"); if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("Unsupported texture format"); return -1; @@ -403,6 +420,7 @@ src += pitch; dst += txdat->dim.pitch; } +printf("-NDS_UpdateTexture\n"); return 0; } } @@ -412,6 +430,7 @@ const SDL_Rect * rect, int markDirty, void **pixels, int *pitch) { +printf("+NDS_LockTexture\n"); if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("Unsupported texture format"); return -1; @@ -421,6 +440,7 @@ *pixels = (void *) ((u8 *)txdat->vram + rect->y * txdat->dim.pitch + rect->x * (txdat->dim.bpp/8)); *pitch = txdat->dim.pitch; +printf("-NDS_LockTexture\n"); return 0; } } @@ -431,12 +451,14 @@ if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("Unsupported texture format"); } +printf("!NDS_UnlockTexture\n"); } static void NDS_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects) { /* stub */ +printf("!NDS_DirtyTexture\n"); } static int @@ -448,6 +470,7 @@ u16 color; int i, j; +printf("+NDS_RenderFill\n"); /* TODO: make a single-color sprite and stretch it. color = RGB15(r>>3,g>>3,b>>3); for (i = real_rect.x; i < real_rect.x+real_rect.w; ++i) { @@ -456,6 +479,7 @@ 0x8000 | color; } }*/ +printf("-NDS_RenderFill\n"); return 0; } @@ -467,6 +491,7 @@ SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); +printf("+NDS_RenderCopy\n"); #if 0 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_Surface *target = data->screens[data->current_screen]; @@ -485,6 +510,7 @@ return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect); } #endif +printf("-NDS_RenderCopy\n"); return 0; } @@ -495,21 +521,25 @@ NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; /* Send the data to the display TODO */ +printf("+NDS_RenderPresent\n"); /* Update the flipping chain, if any */ if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) { swiWaitForVBlank(); } +printf("-NDS_RenderPresent\n"); } static void NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { +printf("+NDS_DestroyTexture\n"); if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { SDL_SetError("Unsupported texture format"); } else { /* free anything else allocated for texture */ SDL_free(texture->driverdata); } +printf("-NDS_DestroyTexture\n"); } static void @@ -520,6 +550,7 @@ SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);*/ int i; +printf("+NDS_DestroyRenderer\n"); if (data) { /* TODO: free anything relevant. */ /*for (i = 0; i < SDL_arraysize(data->texture); ++i) { @@ -539,6 +570,7 @@ SDL_free(data); } SDL_free(renderer); +printf("-NDS_DestroyRenderer\n"); } /* vi: set ts=4 sw=4 expandtab: */ diff -r bc3e3e889f6d -r 4135aa9c5645 src/video/nds/SDL_ndsvideo.c --- a/src/video/nds/SDL_ndsvideo.c Sun Jul 13 04:28:54 2008 +0000 +++ b/src/video/nds/SDL_ndsvideo.c Sat Jul 19 17:37:19 2008 +0000 @@ -21,16 +21,8 @@ */ #include "SDL_config.h" -/* Dummy SDL video driver implementation; this is just enough to make an - * SDL-based application THINK it's got a working video driver, for - * applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it, - * and also for use as a collection of stubs when porting SDL to a new - * platform for which you haven't yet written a valid video driver. - * - * This is also a great way to determine bottlenecks: if you think that SDL - * is a performance problem for a given platform, enable this driver, and - * then see if your application runs faster without video overhead. - * +/* SDL Nintendo DS video driver implementation + * based on dummy driver: * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion * of this was cut-and-pasted from Stephane Peter's work in the AAlib * SDL video driver. Renamed to "DUMMY" by Sam Lantinga. @@ -39,6 +31,9 @@ #include #include #include +#include +#include +#include #include "SDL_video.h" #include "SDL_mouse.h" @@ -57,12 +52,71 @@ static int NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode); static void NDS_VideoQuit(_THIS); -/* DUMMY driver bootstrap functions */ +/* NDS sprite-related functions */ + +#define SPRITE_DMA_CHANNEL 3 +#define SPRITE_ANGLE_MASK 0x01FF + +void +NDS_OAM_Update(tOAM *oam) +{ + DC_FlushAll(); + dmaCopyHalfWords(SPRITE_DMA_CHANNEL, oam->spriteBuffer, OAM, + SPRITE_COUNT * sizeof(SpriteEntry)); +} + +void +NDS_OAM_RotateSprite(SpriteRotation *spriteRotation, u16 angle) +{ + s16 s = SIN[angle & SPRITE_ANGLE_MASK] >> 4; + s16 c = COS[angle & SPRITE_ANGLE_MASK] >> 4; + + spriteRotation->hdx = c; + spriteRotation->hdy = s; + spriteRotation->vdx = -s; + spriteRotation->vdy = c; +} +void +NDS_OAM_Init(tOAM *oam) +{ + int i; + for(i = 0; i < SPRITE_COUNT; i++) { + oam->spriteBuffer[i].attribute[0] = ATTR0_DISABLED; + oam->spriteBuffer[i].attribute[1] = 0; + oam->spriteBuffer[i].attribute[2] = 0; + } + for(i = 0; i < MATRIX_COUNT; i++) { + NDS_OAM_RotateSprite(&(oam->matrixBuffer[i]), 0); + } + swiWaitForVBlank(); + NDS_OAM_Update(oam); +} + +void +NDS_OAM_HideSprite(SpriteEntry *spriteEntry) +{ + spriteEntry->isRotoscale = 0; + spriteEntry->isHidden = 1; +} + +void +NDS_OAM_ShowSprite(SpriteEntry *spriteEntry, int affine, int double_bound) +{ + if (affine) { + spriteEntry->isRotoscale = 1; + spriteEntry->rsDouble = double_bound; + } else { + spriteEntry->isHidden = 0; + } +} + + +/* SDL NDS driver bootstrap functions */ static int NDS_Available(void) { - const char *envr = SDL_getenv("SDL_VIDEODRIVER"); + /*const char *envr = SDL_getenv("SDL_VIDEODRIVER");*/ /*printf("NDS_Available()\n"); */ return (1); } @@ -79,6 +133,7 @@ SDL_VideoDevice *device; /*printf("NDS_CreateDevice(%d)\n", devindex); */ +printf("+NDS_CreateDevice\n"); /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { @@ -99,6 +154,7 @@ device->free = NDS_DeleteDevice; +printf("-NDS_CreateDevice\n"); return device; } @@ -113,7 +169,8 @@ SDL_DisplayMode mode; int i; - /* simple 256x192x15x60 for now */ +printf("+NDS_VideoInit\n"); + /* simple 256x192x16x60 for now */ mode.w = 256; mode.h = 192; mode.format = SDL_PIXELFORMAT_ABGR1555; @@ -129,49 +186,41 @@ SDL_AddDisplayMode(0, &mode); /* hackish stuff to get things up and running for now, and for a console */ - powerON(POWER_ALL); irqInit(); + powerON(POWER_ALL_2D); irqInit(); irqEnable(IRQ_VBLANK); NDS_SetDisplayMode(_this, &mode); +printf("-NDS_VideoInit\n"); return 0; } static int NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode) { +printf("+NDS_SetDisplayMode\n"); /* right now this function is just hard-coded for 256x192 ABGR1555 */ videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE); /* display on main core */ videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); /* debug text on sub */ - vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_LCD, - VRAM_C_SUB_BG, VRAM_D_LCD); - + vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_MAIN_BG_0x06020000, + VRAM_C_SUB_BG_0x06200000, VRAM_C_SUB_BG_0x06220000); + vramSetBankE(VRAM_E_MAIN_SPRITE); /* set up console for debug text 'n stuff */ SUB_BG0_CR = BG_MAP_BASE(31); BG_PALETTE_SUB[255] = RGB15(31, 31, 31); + /* debugging purposes, uncomment this later. then remove it & add 2screen. consoleInitDefault((u16 *) SCREEN_BASE_BLOCK_SUB(31), - (u16 *) CHAR_BASE_BLOCK_SUB(0), 16); - -#if 0 -/* we should be using this as a texture for rendering, not as a framebuffer */ - /* maps well to the 256x192 screen anyway. note: need VRAM_B for bigger */ - BACKGROUND.control[3] = BG_BMP16_256x256; - /* affine transformation matrix. nothing too fancy here */ - BG3_XDX = 0x100; - BG3_XDY = 0; - BG3_YDX = 0; - BG3_YDY = 0x100; - /* x/y position */ - BG3_CX = 0; - BG3_CY = 0; -#endif + (u16 *) CHAR_BASE_BLOCK_SUB(0), 16);*/ +printf("-NDS_SetDisplayMode\n"); return 0; } void NDS_VideoQuit(_THIS) { +printf("+NDS_VideoQuit\n"); videoSetMode(DISPLAY_SCREEN_OFF); videoSetModeSub(DISPLAY_SCREEN_OFF); vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD); +printf("-NDS_VideoQuit\n"); } /* vi: set ts=4 sw=4 expandtab: */