More NDS video driver work. gsoc2008_nds
authorDarren Alton <dalton@stevens.edu>
Sun, 13 Jul 2008 04:28:54 +0000
branchgsoc2008_nds
changeset 2679bc3e3e889f6d
parent 2678 3895761db26a
child 2680 4135aa9c5645
More NDS video driver work.
src/video/nds/SDL_ndsrender.c
src/video/nds/SDL_ndsvideo.c
     1.1 --- a/src/video/nds/SDL_ndsrender.c	Thu Jul 10 23:35:01 2008 +0000
     1.2 +++ b/src/video/nds/SDL_ndsrender.c	Sun Jul 13 04:28:54 2008 +0000
     1.3 @@ -79,27 +79,33 @@
     1.4  
     1.5  SDL_RenderDriver NDS_RenderDriver = {
     1.6      NDS_CreateRenderer,
     1.7 -    {"nds", SDL_RENDERER_SINGLEBUFFER}
     1.8 -/*SDL_RENDERER_ values
     1.9 -SINGLEBUFFER   Render directly to the window, if possible
    1.10 -PRESENTCOPY    Present uses a copy from back buffer to the front buffer
    1.11 -PRESENTFLIP2   Present uses a flip, swapping back buffer and front buffer
    1.12 -PRESENTFLIP3   Present uses a flip, rotating two back buf.s and a front buf.
    1.13 -PRESENTDISCARD Present leaves the contents of the backbuffer undefined
    1.14 -PRESENTVSYNC   Present is synchronized with the refresh rate
    1.15 -ACCELERATED    The renderer uses hardware acceleration
    1.16 -*/
    1.17 +    {   "nds", /* char* name */
    1.18 +        (SDL_RENDERER_SINGLEBUFFER|SDL_RENDERER_ACCELERATED), /* u32 flags */
    1.19 +        (SDL_TEXTUREMODULATE_NONE), /* u32 mod_modes */
    1.20 +        (SDL_TEXTUREBLENDMODE_NONE), /* u32 blend_modes */
    1.21 +        (SDL_TEXTURESCALEMODE_NONE), /* u32 scale_modes */
    1.22 +        3, /* u32 num_texture_formats */
    1.23 +        {
    1.24 +            SDL_PIXELFORMAT_INDEX8,
    1.25 +            SDL_PIXELFORMAT_RGB555,
    1.26 +            SDL_PIXELFORMAT_RGB565
    1.27 +        }, /* u32 texture_formats[20] */
    1.28 +        (256), /* int max_texture_width */
    1.29 +        (256), /* int max_texture_height */
    1.30 +    }
    1.31  };
    1.32  
    1.33  typedef struct
    1.34  {
    1.35 -    int current_screen;
    1.36 -    u16* fb;
    1.37 +    bg_attribute *bg;
    1.38 +    u8 bg_taken[4];
    1.39 +    int sub;
    1.40  } NDS_RenderData;
    1.41  
    1.42  typedef struct
    1.43  {
    1.44      enum { NDSTX_BG, NDSTX_SPR } type;
    1.45 +    int hw_index;
    1.46      struct { int w, h, pitch, bpp; } dim;
    1.47      u16 *vram;
    1.48  } NDS_TextureData;
    1.49 @@ -120,23 +126,6 @@
    1.50  }
    1.51  
    1.52  void
    1.53 -sdlds_surf2vram(SDL_Surface * s)
    1.54 -{
    1.55 -    if (s->w == 256) {
    1.56 -        u16 tmpbuf[0x20000];
    1.57 -        int i;
    1.58 -
    1.59 -        dmaCopy((u8 *) (s->pixels) + 156 * sizeof(u16),
    1.60 -                tmpbuf, 256 * 192 * sizeof(u16));
    1.61 -    /* hack to fix the pixel format until I figure out why BGR doesn't work */
    1.62 -        for (i = 0; i < 256 * 192; ++i) {
    1.63 -            tmpbuf[i] = sdlds_rgb2bgr(tmpbuf[i]);
    1.64 -        }
    1.65 -        dmaCopy(tmpbuf, VRAM_A, 256 * 192 * sizeof(u16));
    1.66 -    }
    1.67 -}
    1.68 -
    1.69 -void
    1.70  sdlds_print_pixfmt_info(SDL_PixelFormat * f)
    1.71  {
    1.72      if (!f)
    1.73 @@ -200,32 +189,36 @@
    1.74      renderer->info.flags = 0;
    1.75      renderer->window = window->id;
    1.76      renderer->driverdata = data;
    1.77 -    Setup_SoftwareRenderer(renderer); /* TODO: well, "TODON'T" is more like it */
    1.78 +    renderer->CreateTexture = NDS_CreateTexture;
    1.79 +    renderer->QueryTexturePixels = NDS_QueryTexturePixels;
    1.80 +    renderer->SetTexturePalette = NDS_SetTexturePalette;
    1.81 +    renderer->GetTexturePalette = NDS_GetTexturePalette;
    1.82 +    renderer->SetTextureColorMod = NDS_SetTextureColorMod;
    1.83 +    renderer->SetTextureAlphaMod = NDS_SetTextureAlphaMod;
    1.84 +    renderer->SetTextureBlendMode = NDS_SetTextureBlendMode;
    1.85 +    renderer->SetTextureScaleMode = NDS_SetTextureScaleMode;
    1.86 +    renderer->UpdateTexture = NDS_UpdateTexture;
    1.87 +    renderer->LockTexture = NDS_LockTexture;
    1.88 +    renderer->UnlockTexture = NDS_UnlockTexture;
    1.89 +    renderer->DirtyTexture = NDS_DirtyTexture;
    1.90 +    renderer->DestroyTexture = NDS_DestroyTexture;
    1.91  
    1.92 -    if (flags & SDL_RENDERER_PRESENTFLIP2) {
    1.93 -        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
    1.94 -        n = 2;
    1.95 -    } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
    1.96 -        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
    1.97 -        n = 3;
    1.98 -    } else {
    1.99 -        renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
   1.100 -        n = 1;
   1.101 -    }
   1.102 -    /*
   1.103 -    for (i = 0; i < n; ++i) {
   1.104 -        data->screens[i] =
   1.105 -            SDL_CreateRGBSurface(0, 256, 192, bpp, Rmask, Gmask, Bmask,
   1.106 -                                 Amask);
   1.107 -        if (!data->screens[i]) {
   1.108 -            NDS_DestroyRenderer(renderer);
   1.109 -            return NULL;
   1.110 -        }
   1.111 -        SDL_SetSurfacePalette(data->screens[i], display->palette);
   1.112 -        sdlds_print_surface_info(data->screens[i]);
   1.113 -    }*/
   1.114 +    renderer->info.mod_modes = NDS_RenderDriver.info.mod_modes;
   1.115 +    renderer->info.blend_modes = NDS_RenderDriver.info.blend_modes;
   1.116 +    renderer->info.scale_modes = NDS_RenderDriver.info.scale_modes;
   1.117 +    renderer->info.num_texture_formats =
   1.118 +        NDS_RenderDriver.info.num_texture_formats;
   1.119 +    SDL_memcpy(renderer->info.texture_formats,
   1.120 +               NDS_RenderDriver.info.texture_formats,
   1.121 +               sizeof(renderer->info.texture_formats));;
   1.122 +    renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width;
   1.123 +    renderer->info.max_texture_height =
   1.124 +        NDS_RenderDriver.info.max_texture_height;
   1.125  
   1.126 -    data->fb = (u16*)0x06020000;
   1.127 +    /*data->fb = (u16*)0x06020000;*/
   1.128 +    data->bg = &BACKGROUND;
   1.129 +    data->bg_taken[2] = data->bg_taken[3] = 0;
   1.130 +    data->sub = 0;
   1.131  
   1.132      return renderer;
   1.133  }
   1.134 @@ -250,7 +243,7 @@
   1.135  NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   1.136  {
   1.137      NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
   1.138 -
   1.139 +    NDS_TextureData *txdat = NULL;
   1.140      if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   1.141          SDL_SetError("Unsupported texture format");
   1.142          return -1;
   1.143 @@ -263,9 +256,49 @@
   1.144              SDL_SetError("Unknown texture format");
   1.145              return -1;
   1.146          }
   1.147 -        /* TODO: appropriate checks for ABGR1555 */
   1.148 -        texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
   1.149 -        /* TODO: conditional statements on w/h to place it as bg/sprite */
   1.150 +        /* conditional statements on w/h to place it as bg/sprite */
   1.151 +        /*if(texture->w <= 64 && texture->h <= 64) {
   1.152 +            sprites not implemented yet.  elegant, I know.
   1.153 +        } else*/ if(texture->w <= 256 && texture->h <= 256) {
   1.154 +            int whichbg = -1;
   1.155 +            if(!data->bg_taken[2]) {
   1.156 +                whichbg = 2;
   1.157 +                data->bg->bg2_rotation.xdx = 0x100;
   1.158 +                data->bg->bg2_rotation.xdy = 0;
   1.159 +                data->bg->bg2_rotation.ydx = 0;
   1.160 +                data->bg->bg2_rotation.ydy = 0x100;
   1.161 +                data->bg->bg2_rotation.centerX = 0;
   1.162 +                data->bg->bg2_rotation.centerY = 0;
   1.163 +            } else if(!data->bg_taken[3]) {
   1.164 +                whichbg = 3;
   1.165 +                data->bg->bg3_rotation.xdx = 0x100;
   1.166 +                data->bg->bg3_rotation.xdy = 0;
   1.167 +                data->bg->bg3_rotation.ydx = 0;
   1.168 +                data->bg->bg3_rotation.ydy = 0x100;
   1.169 +                data->bg->bg3_rotation.centerX = 0;
   1.170 +                data->bg->bg3_rotation.centerY = 0;
   1.171 +            }
   1.172 +            if(whichbg >= 0) {
   1.173 +                data->bg->control[whichbg] = (bpp == 8) ?
   1.174 +                    BG_BMP8_256x256 : BG_BMP16_256x256;
   1.175 +                data->bg->scroll[whichbg].x = 0;
   1.176 +                data->bg->scroll[whichbg].y = 0;
   1.177 +                texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
   1.178 +                txdat = (NDS_TextureData*)texture->driverdata;
   1.179 +                txdat->type = NDSTX_BG;
   1.180 +                txdat->hw_index = whichbg;
   1.181 +                txdat->dim.w = texture->w;
   1.182 +                txdat->dim.h = texture->h;
   1.183 +                txdat->dim.pitch = 256 * (bpp/8);
   1.184 +                txdat->dim.bpp = bpp;
   1.185 +                txdat->vram = (u16*)(data->sub ?
   1.186 +                    BG_BMP_RAM_SUB(whichbg) : BG_BMP_RAM(whichbg));
   1.187 +            } else {
   1.188 +                SDL_SetError("Out of NDS backgrounds.");
   1.189 +            }
   1.190 +        } else {
   1.191 +            SDL_SetError("Texture too big for NDS hardware.");
   1.192 +        }
   1.193      }
   1.194  
   1.195      if (!texture->driverdata) {
   1.196 @@ -368,7 +401,7 @@
   1.197          for (row = 0; row < rect->h; ++row) {
   1.198              SDL_memcpy(dst, src, length);
   1.199              src += pitch;
   1.200 -            dst += surface->pitch;
   1.201 +            dst += txdat->dim.pitch;
   1.202          }
   1.203          return 0;
   1.204      }
   1.205 @@ -415,13 +448,14 @@
   1.206      u16 color;
   1.207      int i, j;
   1.208  
   1.209 +    /* TODO: make a single-color sprite and stretch it.
   1.210      color = RGB15(r>>3,g>>3,b>>3);
   1.211      for (i = real_rect.x; i < real_rect.x+real_rect.w; ++i) {
   1.212          for (j = real_rect.y; j < real_rect.y+real_rect.h; ++j) {
   1.213              data->fb[(j + real_rect.y) * 256 + i + real_rect.x] = 
   1.214                  0x8000 | color;
   1.215          }
   1.216 -    }
   1.217 +    }*/
   1.218      return 0;
   1.219  }
   1.220  
   1.221 @@ -448,26 +482,9 @@
   1.222          SDL_Surface *target = data->screens[data->current_screen];
   1.223          SDL_Rect real_srcrect = *srcrect;
   1.224          SDL_Rect real_dstrect = *dstrect;
   1.225 -        /*sdlds_print_surface_info(surface);
   1.226 -           sdlds_print_surface_info(target); */
   1.227 -        sdlds_surf2vram(surface);
   1.228          return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
   1.229      }
   1.230  #endif
   1.231 -    /* copy it directly to vram */
   1.232 -    SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   1.233 -    sdlds_surf2vram(surface);
   1.234 -    /*
   1.235 -    int sx = srcrect->x, sy = srcrect->y, sw = srcrect->w, sh = srcrect->h;
   1.236 -    int dx = dstrect->x, dy = dstrect->y, dw = dstrect->w, dh = dstrect->h;
   1.237 -    int si, sj, di, dj;
   1.238 -    for (sj = 0, dj = 0; sj < sh && dj < dh; ++sj, ++dj) {
   1.239 -        for (si = 0, di = 0; si < sw && di < dw; ++si, ++di) {
   1.240 -            data->fb[(dj + dy) * 256 + di + dx] = 0x8000 |
   1.241 -                ((u16 *) surface->pixels)[(sj + sy) * (surface->w) + si +
   1.242 -                                             sx];
   1.243 -        }
   1.244 -    }*/
   1.245      return 0;
   1.246  }
   1.247  
   1.248 @@ -479,10 +496,8 @@
   1.249      /* Send the data to the display TODO */
   1.250  
   1.251      /* Update the flipping chain, if any */
   1.252 -    if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
   1.253 -        data->current_screen = (data->current_screen + 1) % 2;
   1.254 -    } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
   1.255 -        data->current_screen = (data->current_screen + 1) % 3;
   1.256 +    if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
   1.257 +        swiWaitForVBlank();
   1.258      }
   1.259  }
   1.260  
   1.261 @@ -492,9 +507,8 @@
   1.262      if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   1.263          SDL_SetError("Unsupported texture format");
   1.264      } else {
   1.265 -        /* TODO: free anything allocated for texture */
   1.266 -        /*SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   1.267 -        SDL_FreeSurface(surface);*/
   1.268 +        /* free anything else allocated for texture */
   1.269 +        SDL_free(texture->driverdata);
   1.270      }
   1.271  }
   1.272  
   1.273 @@ -507,7 +521,8 @@
   1.274      int i;
   1.275  
   1.276      if (data) {
   1.277 -        for (i = 0; i < SDL_arraysize(data->texture); ++i) {
   1.278 +        /* TODO: free anything relevant. */
   1.279 +        /*for (i = 0; i < SDL_arraysize(data->texture); ++i) {
   1.280              if (data->texture[i]) {
   1.281                  DestroyTexture(data->renderer, data->texture[i]);
   1.282              }
   1.283 @@ -520,7 +535,7 @@
   1.284              SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
   1.285                                  data);
   1.286          }
   1.287 -        SDL_FreeDirtyRects(&data->dirty);
   1.288 +        SDL_FreeDirtyRects(&data->dirty);*/
   1.289          SDL_free(data);
   1.290      }
   1.291      SDL_free(renderer);
     2.1 --- a/src/video/nds/SDL_ndsvideo.c	Thu Jul 10 23:35:01 2008 +0000
     2.2 +++ b/src/video/nds/SDL_ndsvideo.c	Sun Jul 13 04:28:54 2008 +0000
     2.3 @@ -116,31 +116,22 @@
     2.4      /* simple 256x192x15x60 for now */
     2.5      mode.w = 256;
     2.6      mode.h = 192;
     2.7 -    mode.format = SDL_PIXELFORMAT_BGR555;
     2.8 +    mode.format = SDL_PIXELFORMAT_ABGR1555;
     2.9      mode.refresh_rate = 60;
    2.10      mode.driverdata = NULL;
    2.11  
    2.12      SDL_AddBasicVideoDisplay(&mode);
    2.13      SDL_AddRenderDriver(0, &NDS_RenderDriver);
    2.14 +    /*SDL_AddBasicVideoDisplay(&mode); two screens, same mode. uncomment later
    2.15 +    SDL_AddRenderDriver(1, &NDS_RenderDriver);*/
    2.16  
    2.17      SDL_zero(mode);
    2.18      SDL_AddDisplayMode(0, &mode);
    2.19  
    2.20      /* hackish stuff to get things up and running for now, and for a console */
    2.21 -    powerON(POWER_ALL);
    2.22 -    videoSetMode(MODE_FB0);
    2.23 -    videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);    /* debug text on sub */
    2.24 -    
    2.25     vramSetBankA(VRAM_A_LCD);
    2.26 -    vramSetBankC(VRAM_C_SUB_BG);
    2.27 -    
    2.28     irqInit();
    2.29 -    irqEnable(IRQ_VBLANK);
    2.30 -    /* set up console for debug text 'n stuff */
    2.31 -    SUB_BG0_CR = BG_MAP_BASE(31);
    2.32 -    BG_PALETTE_SUB[255] = RGB15(31, 31, 31);
    2.33 -    consoleInitDefault((u16 *) SCREEN_BASE_BLOCK_SUB(31),
    2.34 -                       (u16 *) CHAR_BASE_BLOCK_SUB(0), 16);
    2.35 -
    2.36 -    /*NDS_SetDisplayMode(_this, &mode); */
    2.37 +    powerON(POWER_ALL);
    2.38     irqInit();
    2.39 +    irqEnable(IRQ_VBLANK);
    2.40 +    NDS_SetDisplayMode(_this, &mode);
    2.41      return 0;
    2.42  }
    2.43  
    2.44 @@ -148,14 +139,21 @@
    2.45  NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
    2.46  {
    2.47      /* right now this function is just hard-coded for 256x192 ABGR1555 */
    2.48 -#if 0
    2.49      videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);       /* display on main core */
    2.50      videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);    /* debug text on sub */
    2.51      vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_LCD,
    2.52                       VRAM_C_SUB_BG, VRAM_D_LCD);
    2.53  
    2.54 +    /* set up console for debug text 'n stuff */
    2.55 +    SUB_BG0_CR = BG_MAP_BASE(31);
    2.56 +    BG_PALETTE_SUB[255] = RGB15(31, 31, 31);
    2.57 +    consoleInitDefault((u16 *) SCREEN_BASE_BLOCK_SUB(31),
    2.58 +                       (u16 *) CHAR_BASE_BLOCK_SUB(0), 16);
    2.59 +
    2.60 +#if 0
    2.61 +/* we should be using this as a texture for rendering, not as a framebuffer */
    2.62      /* maps well to the 256x192 screen anyway.  note: need VRAM_B for bigger */
    2.63 -    BG3_CR = BG_BMP16_256x256;
    2.64 +    BACKGROUND.control[3] = BG_BMP16_256x256;
    2.65      /* affine transformation matrix.  nothing too fancy here */
    2.66      BG3_XDX = 0x100;
    2.67      BG3_XDY = 0;
    2.68 @@ -171,6 +169,9 @@
    2.69  void
    2.70  NDS_VideoQuit(_THIS)
    2.71  {
    2.72 +    videoSetMode(DISPLAY_SCREEN_OFF);
    2.73 +    videoSetModeSub(DISPLAY_SCREEN_OFF);
    2.74 +    vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
    2.75  }
    2.76  
    2.77  /* vi: set ts=4 sw=4 expandtab: */