comparison src/video/nds/SDL_ndsrender.c @ 2679:bc3e3e889f6d gsoc2008_nds

More NDS video driver work.
author Darren Alton <dalton@stevens.edu>
date Sun, 13 Jul 2008 04:28:54 +0000
parents 3895761db26a
children 4135aa9c5645
comparison
equal deleted inserted replaced
2678:3895761db26a 2679:bc3e3e889f6d
77 static void NDS_DestroyRenderer(SDL_Renderer * renderer); 77 static void NDS_DestroyRenderer(SDL_Renderer * renderer);
78 78
79 79
80 SDL_RenderDriver NDS_RenderDriver = { 80 SDL_RenderDriver NDS_RenderDriver = {
81 NDS_CreateRenderer, 81 NDS_CreateRenderer,
82 {"nds", SDL_RENDERER_SINGLEBUFFER} 82 { "nds", /* char* name */
83 /*SDL_RENDERER_ values 83 (SDL_RENDERER_SINGLEBUFFER|SDL_RENDERER_ACCELERATED), /* u32 flags */
84 SINGLEBUFFER Render directly to the window, if possible 84 (SDL_TEXTUREMODULATE_NONE), /* u32 mod_modes */
85 PRESENTCOPY Present uses a copy from back buffer to the front buffer 85 (SDL_TEXTUREBLENDMODE_NONE), /* u32 blend_modes */
86 PRESENTFLIP2 Present uses a flip, swapping back buffer and front buffer 86 (SDL_TEXTURESCALEMODE_NONE), /* u32 scale_modes */
87 PRESENTFLIP3 Present uses a flip, rotating two back buf.s and a front buf. 87 3, /* u32 num_texture_formats */
88 PRESENTDISCARD Present leaves the contents of the backbuffer undefined 88 {
89 PRESENTVSYNC Present is synchronized with the refresh rate 89 SDL_PIXELFORMAT_INDEX8,
90 ACCELERATED The renderer uses hardware acceleration 90 SDL_PIXELFORMAT_RGB555,
91 */ 91 SDL_PIXELFORMAT_RGB565
92 }, /* u32 texture_formats[20] */
93 (256), /* int max_texture_width */
94 (256), /* int max_texture_height */
95 }
92 }; 96 };
93 97
94 typedef struct 98 typedef struct
95 { 99 {
96 int current_screen; 100 bg_attribute *bg;
97 u16* fb; 101 u8 bg_taken[4];
102 int sub;
98 } NDS_RenderData; 103 } NDS_RenderData;
99 104
100 typedef struct 105 typedef struct
101 { 106 {
102 enum { NDSTX_BG, NDSTX_SPR } type; 107 enum { NDSTX_BG, NDSTX_SPR } type;
108 int hw_index;
103 struct { int w, h, pitch, bpp; } dim; 109 struct { int w, h, pitch, bpp; } dim;
104 u16 *vram; 110 u16 *vram;
105 } NDS_TextureData; 111 } NDS_TextureData;
106 112
107 113
115 /* hack to get the proper colors until I actually get BGR555 to work right */ 121 /* hack to get the proper colors until I actually get BGR555 to work right */
116 u16 Rmask = 0x7C00, Bmask = 0x001F, GAmask = 0x83E0, r, b; 122 u16 Rmask = 0x7C00, Bmask = 0x001F, GAmask = 0x83E0, r, b;
117 r = (c & Rmask) >> 10; 123 r = (c & Rmask) >> 10;
118 b = (c & Bmask) << 10; 124 b = (c & Bmask) << 10;
119 return (c & GAmask) | r | b; 125 return (c & GAmask) | r | b;
120 }
121
122 void
123 sdlds_surf2vram(SDL_Surface * s)
124 {
125 if (s->w == 256) {
126 u16 tmpbuf[0x20000];
127 int i;
128
129 dmaCopy((u8 *) (s->pixels) + 156 * sizeof(u16),
130 tmpbuf, 256 * 192 * sizeof(u16));
131 /* hack to fix the pixel format until I figure out why BGR doesn't work */
132 for (i = 0; i < 256 * 192; ++i) {
133 tmpbuf[i] = sdlds_rgb2bgr(tmpbuf[i]);
134 }
135 dmaCopy(tmpbuf, VRAM_A, 256 * 192 * sizeof(u16));
136 }
137 } 126 }
138 127
139 void 128 void
140 sdlds_print_pixfmt_info(SDL_PixelFormat * f) 129 sdlds_print_pixfmt_info(SDL_PixelFormat * f)
141 { 130 {
198 renderer->DestroyRenderer = NDS_DestroyRenderer; 187 renderer->DestroyRenderer = NDS_DestroyRenderer;
199 renderer->info.name = NDS_RenderDriver.info.name; 188 renderer->info.name = NDS_RenderDriver.info.name;
200 renderer->info.flags = 0; 189 renderer->info.flags = 0;
201 renderer->window = window->id; 190 renderer->window = window->id;
202 renderer->driverdata = data; 191 renderer->driverdata = data;
203 Setup_SoftwareRenderer(renderer); /* TODO: well, "TODON'T" is more like it */ 192 renderer->CreateTexture = NDS_CreateTexture;
204 193 renderer->QueryTexturePixels = NDS_QueryTexturePixels;
205 if (flags & SDL_RENDERER_PRESENTFLIP2) { 194 renderer->SetTexturePalette = NDS_SetTexturePalette;
206 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; 195 renderer->GetTexturePalette = NDS_GetTexturePalette;
207 n = 2; 196 renderer->SetTextureColorMod = NDS_SetTextureColorMod;
208 } else if (flags & SDL_RENDERER_PRESENTFLIP3) { 197 renderer->SetTextureAlphaMod = NDS_SetTextureAlphaMod;
209 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; 198 renderer->SetTextureBlendMode = NDS_SetTextureBlendMode;
210 n = 3; 199 renderer->SetTextureScaleMode = NDS_SetTextureScaleMode;
211 } else { 200 renderer->UpdateTexture = NDS_UpdateTexture;
212 renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; 201 renderer->LockTexture = NDS_LockTexture;
213 n = 1; 202 renderer->UnlockTexture = NDS_UnlockTexture;
214 } 203 renderer->DirtyTexture = NDS_DirtyTexture;
215 /* 204 renderer->DestroyTexture = NDS_DestroyTexture;
216 for (i = 0; i < n; ++i) { 205
217 data->screens[i] = 206 renderer->info.mod_modes = NDS_RenderDriver.info.mod_modes;
218 SDL_CreateRGBSurface(0, 256, 192, bpp, Rmask, Gmask, Bmask, 207 renderer->info.blend_modes = NDS_RenderDriver.info.blend_modes;
219 Amask); 208 renderer->info.scale_modes = NDS_RenderDriver.info.scale_modes;
220 if (!data->screens[i]) { 209 renderer->info.num_texture_formats =
221 NDS_DestroyRenderer(renderer); 210 NDS_RenderDriver.info.num_texture_formats;
222 return NULL; 211 SDL_memcpy(renderer->info.texture_formats,
223 } 212 NDS_RenderDriver.info.texture_formats,
224 SDL_SetSurfacePalette(data->screens[i], display->palette); 213 sizeof(renderer->info.texture_formats));;
225 sdlds_print_surface_info(data->screens[i]); 214 renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width;
226 }*/ 215 renderer->info.max_texture_height =
227 216 NDS_RenderDriver.info.max_texture_height;
228 data->fb = (u16*)0x06020000; 217
218 /*data->fb = (u16*)0x06020000;*/
219 data->bg = &BACKGROUND;
220 data->bg_taken[2] = data->bg_taken[3] = 0;
221 data->sub = 0;
229 222
230 return renderer; 223 return renderer;
231 } 224 }
232 225
233 static int 226 static int
248 241
249 static int 242 static int
250 NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 243 NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
251 { 244 {
252 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; 245 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
253 246 NDS_TextureData *txdat = NULL;
254 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 247 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
255 SDL_SetError("Unsupported texture format"); 248 SDL_SetError("Unsupported texture format");
256 return -1; 249 return -1;
257 } else { 250 } else {
258 int bpp; 251 int bpp;
261 if (!SDL_PixelFormatEnumToMasks 254 if (!SDL_PixelFormatEnumToMasks
262 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { 255 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
263 SDL_SetError("Unknown texture format"); 256 SDL_SetError("Unknown texture format");
264 return -1; 257 return -1;
265 } 258 }
266 /* TODO: appropriate checks for ABGR1555 */ 259 /* conditional statements on w/h to place it as bg/sprite */
267 texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData)); 260 /*if(texture->w <= 64 && texture->h <= 64) {
268 /* TODO: conditional statements on w/h to place it as bg/sprite */ 261 sprites not implemented yet. elegant, I know.
262 } else*/ if(texture->w <= 256 && texture->h <= 256) {
263 int whichbg = -1;
264 if(!data->bg_taken[2]) {
265 whichbg = 2;
266 data->bg->bg2_rotation.xdx = 0x100;
267 data->bg->bg2_rotation.xdy = 0;
268 data->bg->bg2_rotation.ydx = 0;
269 data->bg->bg2_rotation.ydy = 0x100;
270 data->bg->bg2_rotation.centerX = 0;
271 data->bg->bg2_rotation.centerY = 0;
272 } else if(!data->bg_taken[3]) {
273 whichbg = 3;
274 data->bg->bg3_rotation.xdx = 0x100;
275 data->bg->bg3_rotation.xdy = 0;
276 data->bg->bg3_rotation.ydx = 0;
277 data->bg->bg3_rotation.ydy = 0x100;
278 data->bg->bg3_rotation.centerX = 0;
279 data->bg->bg3_rotation.centerY = 0;
280 }
281 if(whichbg >= 0) {
282 data->bg->control[whichbg] = (bpp == 8) ?
283 BG_BMP8_256x256 : BG_BMP16_256x256;
284 data->bg->scroll[whichbg].x = 0;
285 data->bg->scroll[whichbg].y = 0;
286 texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
287 txdat = (NDS_TextureData*)texture->driverdata;
288 txdat->type = NDSTX_BG;
289 txdat->hw_index = whichbg;
290 txdat->dim.w = texture->w;
291 txdat->dim.h = texture->h;
292 txdat->dim.pitch = 256 * (bpp/8);
293 txdat->dim.bpp = bpp;
294 txdat->vram = (u16*)(data->sub ?
295 BG_BMP_RAM_SUB(whichbg) : BG_BMP_RAM(whichbg));
296 } else {
297 SDL_SetError("Out of NDS backgrounds.");
298 }
299 } else {
300 SDL_SetError("Texture too big for NDS hardware.");
301 }
269 } 302 }
270 303
271 if (!texture->driverdata) { 304 if (!texture->driverdata) {
272 return -1; 305 return -1;
273 } 306 }
366 rect->x * (txdat->dim.bpp/8); 399 rect->x * (txdat->dim.bpp/8);
367 length = rect->w * (txdat->dim.bpp/8); 400 length = rect->w * (txdat->dim.bpp/8);
368 for (row = 0; row < rect->h; ++row) { 401 for (row = 0; row < rect->h; ++row) {
369 SDL_memcpy(dst, src, length); 402 SDL_memcpy(dst, src, length);
370 src += pitch; 403 src += pitch;
371 dst += surface->pitch; 404 dst += txdat->dim.pitch;
372 } 405 }
373 return 0; 406 return 0;
374 } 407 }
375 } 408 }
376 409
413 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; 446 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
414 SDL_Rect real_rect = *rect; 447 SDL_Rect real_rect = *rect;
415 u16 color; 448 u16 color;
416 int i, j; 449 int i, j;
417 450
451 /* TODO: make a single-color sprite and stretch it.
418 color = RGB15(r>>3,g>>3,b>>3); 452 color = RGB15(r>>3,g>>3,b>>3);
419 for (i = real_rect.x; i < real_rect.x+real_rect.w; ++i) { 453 for (i = real_rect.x; i < real_rect.x+real_rect.w; ++i) {
420 for (j = real_rect.y; j < real_rect.y+real_rect.h; ++j) { 454 for (j = real_rect.y; j < real_rect.y+real_rect.h; ++j) {
421 data->fb[(j + real_rect.y) * 256 + i + real_rect.x] = 455 data->fb[(j + real_rect.y) * 256 + i + real_rect.x] =
422 0x8000 | color; 456 0x8000 | color;
423 } 457 }
424 } 458 }*/
425 return 0; 459 return 0;
426 } 460 }
427 461
428 static int 462 static int
429 NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 463 NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
446 } else { 480 } else {
447 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; 481 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
448 SDL_Surface *target = data->screens[data->current_screen]; 482 SDL_Surface *target = data->screens[data->current_screen];
449 SDL_Rect real_srcrect = *srcrect; 483 SDL_Rect real_srcrect = *srcrect;
450 SDL_Rect real_dstrect = *dstrect; 484 SDL_Rect real_dstrect = *dstrect;
451 /*sdlds_print_surface_info(surface);
452 sdlds_print_surface_info(target); */
453 sdlds_surf2vram(surface);
454 return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect); 485 return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
455 } 486 }
456 #endif 487 #endif
457 /* copy it directly to vram */
458 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
459 sdlds_surf2vram(surface);
460 /*
461 int sx = srcrect->x, sy = srcrect->y, sw = srcrect->w, sh = srcrect->h;
462 int dx = dstrect->x, dy = dstrect->y, dw = dstrect->w, dh = dstrect->h;
463 int si, sj, di, dj;
464 for (sj = 0, dj = 0; sj < sh && dj < dh; ++sj, ++dj) {
465 for (si = 0, di = 0; si < sw && di < dw; ++si, ++di) {
466 data->fb[(dj + dy) * 256 + di + dx] = 0x8000 |
467 ((u16 *) surface->pixels)[(sj + sy) * (surface->w) + si +
468 sx];
469 }
470 }*/
471 return 0; 488 return 0;
472 } 489 }
473 490
474 491
475 static void 492 static void
477 { 494 {
478 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; 495 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
479 /* Send the data to the display TODO */ 496 /* Send the data to the display TODO */
480 497
481 /* Update the flipping chain, if any */ 498 /* Update the flipping chain, if any */
482 if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { 499 if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
483 data->current_screen = (data->current_screen + 1) % 2; 500 swiWaitForVBlank();
484 } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
485 data->current_screen = (data->current_screen + 1) % 3;
486 } 501 }
487 } 502 }
488 503
489 static void 504 static void
490 NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) 505 NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
491 { 506 {
492 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 507 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
493 SDL_SetError("Unsupported texture format"); 508 SDL_SetError("Unsupported texture format");
494 } else { 509 } else {
495 /* TODO: free anything allocated for texture */ 510 /* free anything else allocated for texture */
496 /*SDL_Surface *surface = (SDL_Surface *) texture->driverdata; 511 SDL_free(texture->driverdata);
497 SDL_FreeSurface(surface);*/
498 } 512 }
499 } 513 }
500 514
501 static void 515 static void
502 NDS_DestroyRenderer(SDL_Renderer * renderer) 516 NDS_DestroyRenderer(SDL_Renderer * renderer)
505 /*SDL_Window *window = SDL_GetWindowFromID(renderer->window); 519 /*SDL_Window *window = SDL_GetWindowFromID(renderer->window);
506 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);*/ 520 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);*/
507 int i; 521 int i;
508 522
509 if (data) { 523 if (data) {
510 for (i = 0; i < SDL_arraysize(data->texture); ++i) { 524 /* TODO: free anything relevant. */
525 /*for (i = 0; i < SDL_arraysize(data->texture); ++i) {
511 if (data->texture[i]) { 526 if (data->texture[i]) {
512 DestroyTexture(data->renderer, data->texture[i]); 527 DestroyTexture(data->renderer, data->texture[i]);
513 } 528 }
514 } 529 }
515 if (data->surface.format) { 530 if (data->surface.format) {
518 } 533 }
519 if (display->palette) { 534 if (display->palette) {
520 SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, 535 SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
521 data); 536 data);
522 } 537 }
523 SDL_FreeDirtyRects(&data->dirty); 538 SDL_FreeDirtyRects(&data->dirty);*/
524 SDL_free(data); 539 SDL_free(data);
525 } 540 }
526 SDL_free(renderer); 541 SDL_free(renderer);
527 } 542 }
528 543