src/video/nds/SDL_ndsrender.c
author Darren Alton <dalton@stevens.edu>
Tue, 10 Jun 2008 06:57:57 +0000
branchgsoc2008_nds
changeset 2670 6e4669f4db49
child 2671 c3e7c0698cbb
permissions -rw-r--r--
Fix for the previous commit: actually 'svn add'ed some files.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     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.
     9 
    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.
    14 
    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
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #include <stdio.h>
    24 #include <stdlib.h>
    25 #include <nds.h>
    26 
    27 #include "SDL_config.h"
    28 
    29 #include "SDL_video.h"
    30 #include "../SDL_sysvideo.h"
    31 #include "../SDL_yuv_sw_c.h"
    32 #include "../SDL_renderer_sw.h"
    33 
    34 
    35 /* SDL surface based renderer implementation */
    36 
    37 static SDL_Renderer *SDL_NDS_CreateRenderer(SDL_Window * window,
    38                                               Uint32 flags);
    39 static int SDL_NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g,
    40                                 Uint8 b, Uint8 a, const SDL_Rect * rect);
    41 static int SDL_NDS_RenderCopy(SDL_Renderer * renderer,
    42                                 SDL_Texture * texture,
    43                                 const SDL_Rect * srcrect,
    44                                 const SDL_Rect * dstrect);
    45 static void SDL_NDS_RenderPresent(SDL_Renderer * renderer);
    46 static void SDL_NDS_DestroyRenderer(SDL_Renderer * renderer);
    47 
    48 
    49 SDL_RenderDriver SDL_NDS_RenderDriver = {
    50     SDL_NDS_CreateRenderer,
    51     { "nds",  SDL_RENDERER_PRESENTCOPY }
    52 /*   (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
    53       SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
    54       SDL_RENDERER_PRESENTDISCARD),*/
    55 };
    56 
    57 typedef struct
    58 {
    59     int current_screen;
    60     SDL_Surface *screens[3];
    61     int ultimate_answer;
    62 } SDL_NDS_RenderData;
    63 
    64 SDL_Renderer *
    65 SDL_NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
    66 {
    67     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
    68     SDL_DisplayMode *displayMode = &display->current_mode;
    69     SDL_Renderer *renderer;
    70     SDL_NDS_RenderData *data;
    71     int i, n;
    72     int bpp = 16;
    73     Uint32 Rmask = 0x7C00, Gmask = 0x03E0, Bmask = 0x001F, Amask = 0x8000;
    74 
    75     printf("SDL_NDS_CreateRenderer(window, 0x%x)\n", flags);
    76     printf(" window: (%d,%d), %dx%d\n", window->x, window->y, window->w, window->h);
    77 
    78     /* hard coded this to ARGB1555 for now
    79     if (!SDL_PixelFormatEnumToMasks
    80         (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
    81         SDL_SetError("Unknown display format");
    82         return NULL;
    83     }*/
    84 
    85     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
    86     if (!renderer) {
    87         SDL_OutOfMemory();
    88         return NULL;
    89     }
    90 
    91     data = (SDL_NDS_RenderData *) SDL_malloc(sizeof(*data));
    92     if (!data) {
    93         SDL_NDS_DestroyRenderer(renderer);
    94         SDL_OutOfMemory();
    95         return NULL;
    96     }
    97     SDL_zerop(data);
    98 
    99     renderer->RenderFill = SDL_NDS_RenderFill;
   100     renderer->RenderCopy = SDL_NDS_RenderCopy;
   101     renderer->RenderPresent = SDL_NDS_RenderPresent;
   102     renderer->DestroyRenderer = SDL_NDS_DestroyRenderer;
   103     renderer->info.name = SDL_NDS_RenderDriver.info.name;
   104     renderer->info.flags = 0;
   105     renderer->window = window->id;
   106     renderer->driverdata = data;
   107     Setup_SoftwareRenderer(renderer);
   108 
   109     if (flags & SDL_RENDERER_PRESENTFLIP2) {
   110         renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
   111         n = 2;
   112     } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
   113         renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
   114         n = 3;
   115     } else {
   116         renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
   117         n = 1;
   118     }
   119     for (i = 0; i < n; ++i) {
   120         data->screens[i] =
   121             SDL_CreateRGBSurface(0, 256, 192, bpp, Rmask, Gmask, Bmask, Amask);
   122         if (!data->screens[i]) {
   123             SDL_NDS_DestroyRenderer(renderer);
   124             return NULL;
   125         }
   126         SDL_SetSurfacePalette(data->screens[i], display->palette);
   127     }
   128 
   129     data->current_screen = 0;
   130     data->ultimate_answer = 42;
   131 #if 0
   132 #define blarg (data->screens[0])
   133     printf("hello?\n");
   134     if(!data || !(data->screens) || !blarg) {
   135         printf("they're null.\n");
   136     } else {
   137         printf("not null.\n");
   138         printf("%d\n%d\n%d\n%d\n%x\n%x\n%x\n%x\n",
   139         blarg->w, blarg->h, blarg->pitch,
   140         blarg->format->BitsPerPixel,
   141         blarg->format->Rmask,
   142         blarg->format->Gmask,
   143         blarg->format->Bmask,
   144         (u32)(blarg->pixels)); /* ARGH WHY DOESN'T THIS PRINT AT ALL? */
   145         printf("hurr\n");
   146     }
   147 #undef blarg
   148 #endif
   149     return renderer;
   150 }
   151 
   152 static int
   153 SDL_NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
   154                      Uint8 a, const SDL_Rect * rect)
   155 {
   156     SDL_NDS_RenderData *data = (SDL_NDS_RenderData *) renderer->driverdata;
   157     SDL_Surface *target = data->screens[data->current_screen];
   158     Uint32 color;
   159     SDL_Rect real_rect = *rect;
   160 
   161     color = SDL_MapRGBA(target->format, r, g, b, a);
   162 
   163     return SDL_FillRect(target, &real_rect, color);
   164 }
   165 
   166 /* this is mainly for testing stuff to put a surface where I can see it */
   167 void sdlds_surf2vram(SDL_Surface *s) {
   168     int i;
   169     for(i = 0; i < 256*192; ++i) {
   170         ((u16*)VRAM_A)[i] = ((u16*)(s->pixels))[i];
   171     }
   172 }
   173 
   174 static int
   175 SDL_NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   176                      const SDL_Rect * srcrect, const SDL_Rect * dstrect)
   177 {
   178     SDL_NDS_RenderData *data =
   179         (SDL_NDS_RenderData *) renderer->driverdata;
   180     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   181     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   182     printf("SDL_NDS_RenderCopy(renderer, texture, srcrect, dstrect)\n");
   183     printf(" renderer: %s\n", renderer->info.name);
   184     printf(" texture: %dx%d\n", texture->w, texture->h);
   185     printf(" srcrect: (%d,%d), %dx%d\n", srcrect->x, srcrect->y, srcrect->w, srcrect->h);
   186     printf(" dstrect: (%d,%d), %dx%d\n", dstrect->x, dstrect->y, dstrect->w, dstrect->h);
   187 
   188     if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
   189         SDL_Surface *target = data->screens[data->current_screen];
   190         void *pixels =
   191             (Uint8 *) target->pixels + dstrect->y * target->pitch +
   192             dstrect->x * target->format->BytesPerPixel;
   193         return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
   194                                    srcrect, display->current_mode.format,
   195                                    dstrect->w, dstrect->h, pixels,
   196                                    target->pitch);
   197     } else {
   198         SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   199         SDL_Surface *target = data->screens[data->current_screen];
   200         SDL_Rect real_srcrect = *srcrect;
   201         SDL_Rect real_dstrect = *dstrect;
   202         printf("Rmask %x Gmask %x Bmask %x Amask %x\n"
   203                "width %d, height %d, pitch %d\nbpp %d, pixels %x\n",
   204             surface->format->Rmask, surface->format->Gmask,
   205             surface->format->Bmask, surface->format->Amask,
   206             surface->w, surface->h, surface->pitch,
   207             surface->format->BitsPerPixel, (u32)(surface->pixels));
   208         sdlds_surf2vram(surface);
   209         return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
   210     }
   211 #if 0
   212 /* previous attempt to copy it directly to vram */
   213         SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
   214         int sx = srcrect->x, sy = srcrect->y, sw = srcrect->w, sh = srcrect->h;
   215         int dx = dstrect->x, dy = dstrect->y, dw = dstrect->w, dh = dstrect->h;
   216         int si,sj, di,dj;
   217         /*printf("DEBUG: still alive!\n");*/
   218         for(sj=0, dj=0; sj<sh && dj<dh; ++sj, ++dj) {
   219             for(si=0, di=0; si<sw && di<dw; ++si, ++di) {
   220                 ((uint16*)VRAM_A)[(dj+dy)*256 + di+dx]
   221                  = ((Uint16*)surface->pixels)[(sj+sy)*(surface->w) + si+sx];
   222             }
   223         }
   224         /*printf("DEBUG: still alive!\n");*/
   225     }
   226     return 0;
   227 #endif
   228 }
   229 
   230 static void
   231 SDL_NDS_RenderPresent(SDL_Renderer * renderer)
   232 {
   233     SDL_NDS_RenderData *data =
   234         (SDL_NDS_RenderData *) renderer->driverdata;
   235 
   236     printf("SDL_NDS_RenderPresent(renderer)\n");
   237     printf(" renderer: %s\n", renderer->info.name);
   238     /* Send the data to the display */
   239 
   240 #if 0
   241 /*testing to see if rectangles drawn get copied right*/
   242     {
   243     SDL_Rect ra;
   244   	ra.x=0; ra.y=0; ra.w=256; ra.h=192;
   245 	SDL_FillRect(data->screens[data->current_screen], &ra, 0x250);
   246 	ra.x=32; ra.y=32; ra.w=192; ra.h=128;
   247 	SDL_FillRect(data->screens[data->current_screen], &ra,
   248 	    SDL_MapRGBA(data->screens[data->current_screen]->format,
   249 	    255,255,255,255));
   250 	}
   251 /*okay so this works but why not when I do it in the main()?
   252   for some reason the screen I get from screen=SDL_SetVideoMode(...)
   253   doesn't get copied to renderer->driverdata? */
   254     for(i = 0; i < 30; ++i) swiWaitForVBlank(); /* delay for debug purpose */
   255 #endif
   256     sdlds_surf2vram(data->screens[data->current_screen]);
   257 
   258     /* Update the flipping chain, if any */
   259     if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
   260         data->current_screen = (data->current_screen + 1) % 2;
   261     } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
   262         data->current_screen = (data->current_screen + 1) % 3;
   263     }
   264 }
   265 
   266 static void
   267 SDL_NDS_DestroyRenderer(SDL_Renderer * renderer)
   268 {
   269     SDL_NDS_RenderData *data = (SDL_NDS_RenderData *) renderer->driverdata;
   270     int i;
   271 
   272     printf("SDL_NDS_DestroyRenderer(renderer)\n");
   273     printf(" renderer: %s\n", renderer->info.name);
   274     if (data) {
   275         for (i = 0; i < SDL_arraysize(data->screens); ++i) {
   276             if (data->screens[i]) {
   277                 SDL_FreeSurface(data->screens[i]);
   278             }
   279         }
   280         SDL_free(data);
   281     }
   282     SDL_free(renderer);
   283 }
   284 
   285 /* vi: set ts=4 sw=4 expandtab: */