More NDS video driver work. gsoc2008_nds
authorDarren Alton <dalton@stevens.edu>
Sun, 13 Jul 2008 04:28:54 +0000
branchgsoc2008_nds
changeset 2679 bc3e3e889f6d
parent 2678 3895761db26a
child 2680 4135aa9c5645
More NDS video driver work.
src/video/nds/SDL_ndsrender.c
src/video/nds/SDL_ndsvideo.c
--- a/src/video/nds/SDL_ndsrender.c	Thu Jul 10 23:35:01 2008 +0000
+++ b/src/video/nds/SDL_ndsrender.c	Sun Jul 13 04:28:54 2008 +0000
@@ -79,27 +79,33 @@
 
 SDL_RenderDriver NDS_RenderDriver = {
     NDS_CreateRenderer,
-    {"nds", SDL_RENDERER_SINGLEBUFFER}
-/*SDL_RENDERER_ values
-SINGLEBUFFER   Render directly to the window, if possible
-PRESENTCOPY    Present uses a copy from back buffer to the front buffer
-PRESENTFLIP2   Present uses a flip, swapping back buffer and front buffer
-PRESENTFLIP3   Present uses a flip, rotating two back buf.s and a front buf.
-PRESENTDISCARD Present leaves the contents of the backbuffer undefined
-PRESENTVSYNC   Present is synchronized with the refresh rate
-ACCELERATED    The renderer uses hardware acceleration
-*/
+    {   "nds", /* char* name */
+        (SDL_RENDERER_SINGLEBUFFER|SDL_RENDERER_ACCELERATED), /* u32 flags */
+        (SDL_TEXTUREMODULATE_NONE), /* u32 mod_modes */
+        (SDL_TEXTUREBLENDMODE_NONE), /* u32 blend_modes */
+        (SDL_TEXTURESCALEMODE_NONE), /* u32 scale_modes */
+        3, /* u32 num_texture_formats */
+        {
+            SDL_PIXELFORMAT_INDEX8,
+            SDL_PIXELFORMAT_RGB555,
+            SDL_PIXELFORMAT_RGB565
+        }, /* u32 texture_formats[20] */
+        (256), /* int max_texture_width */
+        (256), /* int max_texture_height */
+    }
 };
 
 typedef struct
 {
-    int current_screen;
-    u16* fb;
+    bg_attribute *bg;
+    u8 bg_taken[4];
+    int sub;
 } NDS_RenderData;
 
 typedef struct
 {
     enum { NDSTX_BG, NDSTX_SPR } type;
+    int hw_index;
     struct { int w, h, pitch, bpp; } dim;
     u16 *vram;
 } NDS_TextureData;
@@ -120,23 +126,6 @@
 }
 
 void
-sdlds_surf2vram(SDL_Surface * s)
-{
-    if (s->w == 256) {
-        u16 tmpbuf[0x20000];
-        int i;
-
-        dmaCopy((u8 *) (s->pixels) + 156 * sizeof(u16),
-                tmpbuf, 256 * 192 * sizeof(u16));
-    /* hack to fix the pixel format until I figure out why BGR doesn't work */
-        for (i = 0; i < 256 * 192; ++i) {
-            tmpbuf[i] = sdlds_rgb2bgr(tmpbuf[i]);
-        }
-        dmaCopy(tmpbuf, VRAM_A, 256 * 192 * sizeof(u16));
-    }
-}
-
-void
 sdlds_print_pixfmt_info(SDL_PixelFormat * f)
 {
     if (!f)
@@ -200,32 +189,36 @@
     renderer->info.flags = 0;
     renderer->window = window->id;
     renderer->driverdata = data;
-    Setup_SoftwareRenderer(renderer); /* TODO: well, "TODON'T" is more like it */
+    renderer->CreateTexture = NDS_CreateTexture;
+    renderer->QueryTexturePixels = NDS_QueryTexturePixels;
+    renderer->SetTexturePalette = NDS_SetTexturePalette;
+    renderer->GetTexturePalette = NDS_GetTexturePalette;
+    renderer->SetTextureColorMod = NDS_SetTextureColorMod;
+    renderer->SetTextureAlphaMod = NDS_SetTextureAlphaMod;
+    renderer->SetTextureBlendMode = NDS_SetTextureBlendMode;
+    renderer->SetTextureScaleMode = NDS_SetTextureScaleMode;
+    renderer->UpdateTexture = NDS_UpdateTexture;
+    renderer->LockTexture = NDS_LockTexture;
+    renderer->UnlockTexture = NDS_UnlockTexture;
+    renderer->DirtyTexture = NDS_DirtyTexture;
+    renderer->DestroyTexture = NDS_DestroyTexture;
 
-    if (flags & SDL_RENDERER_PRESENTFLIP2) {
-        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
-        n = 2;
-    } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
-        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
-        n = 3;
-    } else {
-        renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
-        n = 1;
-    }
-    /*
-    for (i = 0; i < n; ++i) {
-        data->screens[i] =
-            SDL_CreateRGBSurface(0, 256, 192, bpp, Rmask, Gmask, Bmask,
-                                 Amask);
-        if (!data->screens[i]) {
-            NDS_DestroyRenderer(renderer);
-            return NULL;
-        }
-        SDL_SetSurfacePalette(data->screens[i], display->palette);
-        sdlds_print_surface_info(data->screens[i]);
-    }*/
+    renderer->info.mod_modes = NDS_RenderDriver.info.mod_modes;
+    renderer->info.blend_modes = NDS_RenderDriver.info.blend_modes;
+    renderer->info.scale_modes = NDS_RenderDriver.info.scale_modes;
+    renderer->info.num_texture_formats =
+        NDS_RenderDriver.info.num_texture_formats;
+    SDL_memcpy(renderer->info.texture_formats,
+               NDS_RenderDriver.info.texture_formats,
+               sizeof(renderer->info.texture_formats));;
+    renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width;
+    renderer->info.max_texture_height =
+        NDS_RenderDriver.info.max_texture_height;
 
-    data->fb = (u16*)0x06020000;
+    /*data->fb = (u16*)0x06020000;*/
+    data->bg = &BACKGROUND;
+    data->bg_taken[2] = data->bg_taken[3] = 0;
+    data->sub = 0;
 
     return renderer;
 }
@@ -250,7 +243,7 @@
 NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
     NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
-
+    NDS_TextureData *txdat = NULL;
     if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
         SDL_SetError("Unsupported texture format");
         return -1;
@@ -263,9 +256,49 @@
             SDL_SetError("Unknown texture format");
             return -1;
         }
-        /* TODO: appropriate checks for ABGR1555 */
-        texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
-        /* TODO: conditional statements on w/h to place it as bg/sprite */
+        /* conditional statements on w/h to place it as bg/sprite */
+        /*if(texture->w <= 64 && texture->h <= 64) {
+            sprites not implemented yet.  elegant, I know.
+        } else*/ if(texture->w <= 256 && texture->h <= 256) {
+            int whichbg = -1;
+            if(!data->bg_taken[2]) {
+                whichbg = 2;
+                data->bg->bg2_rotation.xdx = 0x100;
+                data->bg->bg2_rotation.xdy = 0;
+                data->bg->bg2_rotation.ydx = 0;
+                data->bg->bg2_rotation.ydy = 0x100;
+                data->bg->bg2_rotation.centerX = 0;
+                data->bg->bg2_rotation.centerY = 0;
+            } else if(!data->bg_taken[3]) {
+                whichbg = 3;
+                data->bg->bg3_rotation.xdx = 0x100;
+                data->bg->bg3_rotation.xdy = 0;
+                data->bg->bg3_rotation.ydx = 0;
+                data->bg->bg3_rotation.ydy = 0x100;
+                data->bg->bg3_rotation.centerX = 0;
+                data->bg->bg3_rotation.centerY = 0;
+            }
+            if(whichbg >= 0) {
+                data->bg->control[whichbg] = (bpp == 8) ?
+                    BG_BMP8_256x256 : BG_BMP16_256x256;
+                data->bg->scroll[whichbg].x = 0;
+                data->bg->scroll[whichbg].y = 0;
+                texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
+                txdat = (NDS_TextureData*)texture->driverdata;
+                txdat->type = NDSTX_BG;
+                txdat->hw_index = whichbg;
+                txdat->dim.w = texture->w;
+                txdat->dim.h = texture->h;
+                txdat->dim.pitch = 256 * (bpp/8);
+                txdat->dim.bpp = bpp;
+                txdat->vram = (u16*)(data->sub ?
+                    BG_BMP_RAM_SUB(whichbg) : BG_BMP_RAM(whichbg));
+            } else {
+                SDL_SetError("Out of NDS backgrounds.");
+            }
+        } else {
+            SDL_SetError("Texture too big for NDS hardware.");
+        }
     }
 
     if (!texture->driverdata) {
@@ -368,7 +401,7 @@
         for (row = 0; row < rect->h; ++row) {
             SDL_memcpy(dst, src, length);
             src += pitch;
-            dst += surface->pitch;
+            dst += txdat->dim.pitch;
         }
         return 0;
     }
@@ -415,13 +448,14 @@
     u16 color;
     int i, j;
 
+    /* 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) {
         for (j = real_rect.y; j < real_rect.y+real_rect.h; ++j) {
             data->fb[(j + real_rect.y) * 256 + i + real_rect.x] = 
                 0x8000 | color;
         }
-    }
+    }*/
     return 0;
 }
 
@@ -448,26 +482,9 @@
         SDL_Surface *target = data->screens[data->current_screen];
         SDL_Rect real_srcrect = *srcrect;
         SDL_Rect real_dstrect = *dstrect;
-        /*sdlds_print_surface_info(surface);
-           sdlds_print_surface_info(target); */
-        sdlds_surf2vram(surface);
         return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
     }
 #endif
-    /* copy it directly to vram */
-    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-    sdlds_surf2vram(surface);
-    /*
-    int sx = srcrect->x, sy = srcrect->y, sw = srcrect->w, sh = srcrect->h;
-    int dx = dstrect->x, dy = dstrect->y, dw = dstrect->w, dh = dstrect->h;
-    int si, sj, di, dj;
-    for (sj = 0, dj = 0; sj < sh && dj < dh; ++sj, ++dj) {
-        for (si = 0, di = 0; si < sw && di < dw; ++si, ++di) {
-            data->fb[(dj + dy) * 256 + di + dx] = 0x8000 |
-                ((u16 *) surface->pixels)[(sj + sy) * (surface->w) + si +
-                                             sx];
-        }
-    }*/
     return 0;
 }
 
@@ -479,10 +496,8 @@
     /* Send the data to the display TODO */
 
     /* Update the flipping chain, if any */
-    if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
-        data->current_screen = (data->current_screen + 1) % 2;
-    } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
-        data->current_screen = (data->current_screen + 1) % 3;
+    if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
+        swiWaitForVBlank();
     }
 }
 
@@ -492,9 +507,8 @@
     if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
         SDL_SetError("Unsupported texture format");
     } else {
-        /* TODO: free anything allocated for texture */
-        /*SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
-        SDL_FreeSurface(surface);*/
+        /* free anything else allocated for texture */
+        SDL_free(texture->driverdata);
     }
 }
 
@@ -507,7 +521,8 @@
     int i;
 
     if (data) {
-        for (i = 0; i < SDL_arraysize(data->texture); ++i) {
+        /* TODO: free anything relevant. */
+        /*for (i = 0; i < SDL_arraysize(data->texture); ++i) {
             if (data->texture[i]) {
                 DestroyTexture(data->renderer, data->texture[i]);
             }
@@ -520,7 +535,7 @@
             SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
                                 data);
         }
-        SDL_FreeDirtyRects(&data->dirty);
+        SDL_FreeDirtyRects(&data->dirty);*/
         SDL_free(data);
     }
     SDL_free(renderer);
--- a/src/video/nds/SDL_ndsvideo.c	Thu Jul 10 23:35:01 2008 +0000
+++ b/src/video/nds/SDL_ndsvideo.c	Sun Jul 13 04:28:54 2008 +0000
@@ -116,31 +116,22 @@
     /* simple 256x192x15x60 for now */
     mode.w = 256;
     mode.h = 192;
-    mode.format = SDL_PIXELFORMAT_BGR555;
+    mode.format = SDL_PIXELFORMAT_ABGR1555;
     mode.refresh_rate = 60;
     mode.driverdata = NULL;
 
     SDL_AddBasicVideoDisplay(&mode);
     SDL_AddRenderDriver(0, &NDS_RenderDriver);
+    /*SDL_AddBasicVideoDisplay(&mode); two screens, same mode. uncomment later
+    SDL_AddRenderDriver(1, &NDS_RenderDriver);*/
 
     SDL_zero(mode);
     SDL_AddDisplayMode(0, &mode);
 
     /* hackish stuff to get things up and running for now, and for a console */
-    powerON(POWER_ALL);
-    videoSetMode(MODE_FB0);
-    videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);    /* debug text on sub */
-    
    vramSetBankA(VRAM_A_LCD);
-    vramSetBankC(VRAM_C_SUB_BG);
-    
    irqInit();
-    irqEnable(IRQ_VBLANK);
-    /* set up console for debug text 'n stuff */
-    SUB_BG0_CR = BG_MAP_BASE(31);
-    BG_PALETTE_SUB[255] = RGB15(31, 31, 31);
-    consoleInitDefault((u16 *) SCREEN_BASE_BLOCK_SUB(31),
-                       (u16 *) CHAR_BASE_BLOCK_SUB(0), 16);
-
-    /*NDS_SetDisplayMode(_this, &mode); */
+    powerON(POWER_ALL);
    irqInit();
+    irqEnable(IRQ_VBLANK);
+    NDS_SetDisplayMode(_this, &mode);
     return 0;
 }
 
@@ -148,14 +139,21 @@
 NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
 {
     /* right now this function is just hard-coded for 256x192 ABGR1555 */
-#if 0
     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);
 
+    /* set up console for debug text 'n stuff */
+    SUB_BG0_CR = BG_MAP_BASE(31);
+    BG_PALETTE_SUB[255] = RGB15(31, 31, 31);
+    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 */
-    BG3_CR = BG_BMP16_256x256;
+    BACKGROUND.control[3] = BG_BMP16_256x256;
     /* affine transformation matrix.  nothing too fancy here */
     BG3_XDX = 0x100;
     BG3_XDY = 0;
@@ -171,6 +169,9 @@
 void
 NDS_VideoQuit(_THIS)
 {
+    videoSetMode(DISPLAY_SCREEN_OFF);
+    videoSetModeSub(DISPLAY_SCREEN_OFF);
+    vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
 }
 
 /* vi: set ts=4 sw=4 expandtab: */