comparison src/video/nds/SDL_ndsrender.c @ 3073:c5280d33c32a

NDS compiles again, but may not yet work. Sprite support has been removed for the time being while it is re-worked.
author Darren Alton <dalton@stevens.edu>
date Wed, 18 Feb 2009 00:33:31 +0000
parents 9dde605c7540
children 7f684f249ec9
comparison
equal deleted inserted replaced
3072:9da8f57ab92c 3073:c5280d33c32a
21 */ 21 */
22 22
23 #include <stdio.h> 23 #include <stdio.h>
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #include <nds.h> 25 #include <nds.h>
26 #include <nds/arm9/video.h> 26 //#include <nds/arm9/video.h>
27 #include <nds/arm9/sprite.h> 27 //#include <nds/arm9/sprite.h>
28 #include <nds/arm9/trig_lut.h> 28 //#include <nds/arm9/trig_lut.h>
29 29
30 #include "SDL_config.h" 30 #include "SDL_config.h"
31 31
32 #include "SDL_video.h" 32 #include "SDL_video.h"
33 #include "../SDL_sysvideo.h" 33 #include "../SDL_sysvideo.h"
34 #include "../SDL_yuv_sw_c.h" 34 #include "../SDL_yuv_sw_c.h"
35 #include "../SDL_renderer_sw.h" 35 #include "../SDL_renderer_sw.h"
36
37 /* NDS sprite-related functions */
38 #define SPRITE_DMA_CHANNEL 3
39 #define SPRITE_ANGLE_MASK 0x01FF
40
41 void
42 NDS_OAM_Update(tOAM * oam, int sub)
43 {
44 DC_FlushAll();
45 dmaCopyHalfWords(SPRITE_DMA_CHANNEL, oam->spriteBuffer,
46 sub ? OAM_SUB : OAM, SPRITE_COUNT * sizeof(SpriteEntry));
47 }
48
49 void
50 NDS_OAM_RotateSprite(SpriteRotation * spriteRotation, u16 angle)
51 {
52 s16 s = SIN[angle & SPRITE_ANGLE_MASK] >> 4;
53 s16 c = COS[angle & SPRITE_ANGLE_MASK] >> 4;
54
55 spriteRotation->hdx = c;
56 spriteRotation->hdy = s;
57 spriteRotation->vdx = -s;
58 spriteRotation->vdy = c;
59 }
60
61 void
62 NDS_OAM_Init(tOAM * oam, int sub)
63 {
64 int i;
65 for (i = 0; i < SPRITE_COUNT; i++) {
66 oam->spriteBuffer[i].attribute[0] = ATTR0_DISABLED;
67 oam->spriteBuffer[i].attribute[1] = 0;
68 oam->spriteBuffer[i].attribute[2] = 0;
69 }
70 for (i = 0; i < MATRIX_COUNT; i++) {
71 NDS_OAM_RotateSprite(&(oam->matrixBuffer[i]), 0);
72 }
73 swiWaitForVBlank();
74 NDS_OAM_Update(oam, sub);
75 }
76
77 void
78 NDS_OAM_HideSprite(SpriteEntry * spriteEntry)
79 {
80 spriteEntry->isRotoscale = 0;
81 spriteEntry->isHidden = 1;
82 }
83
84 void
85 NDS_OAM_ShowSprite(SpriteEntry * spriteEntry, int affine, int double_bound)
86 {
87 if (affine) {
88 spriteEntry->isRotoscale = 1;
89 spriteEntry->rsDouble = double_bound;
90 } else {
91 spriteEntry->isHidden = 0;
92 }
93 }
94
95 36
96 /* SDL NDS renderer implementation */ 37 /* SDL NDS renderer implementation */
97 38
98 static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags); 39 static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags);
99 static int NDS_ActivateRenderer(SDL_Renderer * renderer); 40 static int NDS_ActivateRenderer(SDL_Renderer * renderer);
145 3, /* u32 num_texture_formats */ 86 3, /* u32 num_texture_formats */
146 { 87 {
147 SDL_PIXELFORMAT_INDEX8, 88 SDL_PIXELFORMAT_INDEX8,
148 SDL_PIXELFORMAT_ABGR1555, 89 SDL_PIXELFORMAT_ABGR1555,
149 SDL_PIXELFORMAT_BGR555, 90 SDL_PIXELFORMAT_BGR555,
150 }, /* u32 texture_formats[20] */ 91 }, /* u32 texture_formats[20] */
151 (256), /* int max_texture_width */ 92 (256), /* int max_texture_width */
152 (256), /* int max_texture_height */ 93 (256), /* int max_texture_height */
153 } 94 }
154 }; 95 };
155 96
156 typedef struct 97 typedef struct
157 { 98 {
158 bg_attribute *bg; /* backgrounds */
159 tOAM oam_copy; /* sprites */
160 u8 bg_taken[4]; 99 u8 bg_taken[4];
100 OamState *oam;
161 int sub; 101 int sub;
162 } NDS_RenderData; 102 } NDS_RenderData;
163 103
164 typedef struct 104 typedef struct
165 { 105 {
166 enum 106 enum
167 { NDSTX_BG, NDSTX_SPR } type; /* represented in a bg or sprite. */ 107 { NDSTX_BG, NDSTX_SPR } type; /* represented in a bg or sprite. */
168 int hw_index; /* sprite: index in the OAM. / bg: 2 or 3. */ 108 int hw_index; /* index of sprite in OAM or bg from libnds */
169 struct 109 int pitch, bpp; /* useful information about the texture */
170 { 110 struct { int x,y; } scale; /* x/y stretch (24.8 fixed point) */
171 int hdx, hdy, vdx, vdy; /* affine transformation, used for scaling. */ 111 struct { int x,y; } scroll; /* x/y offset */
172 int pitch, bpp; /* some useful info */ 112 int rotate; /* -32768 to 32767, texture rotation */
173 } dim;
174 u16 *vram_pixels; /* where the pixel data is stored (a pointer into VRAM) */ 113 u16 *vram_pixels; /* where the pixel data is stored (a pointer into VRAM) */
175 u16 *vram_palette; /* where the palette data is stored if it's indexed. */ 114 u16 *vram_palette; /* where the palette data is stored if it's indexed. */
176 /*int size; */ 115 /*int size; */
177 } NDS_TextureData; 116 } NDS_TextureData;
178 117
256 renderer->info.max_texture_width = 195 renderer->info.max_texture_width =
257 NDS_RenderDriver.info.max_texture_width; 196 NDS_RenderDriver.info.max_texture_width;
258 renderer->info.max_texture_height = 197 renderer->info.max_texture_height =
259 NDS_RenderDriver.info.max_texture_height; 198 NDS_RenderDriver.info.max_texture_height;
260 199
261 data->sub = 0; /* TODO: this is hard-coded to the "main" screen. 200 data->sub = 0; /* TODO: this is hard-coded to the "main" screen.
262 figure out how to detect whether to set it to 201 figure out how to detect whether to set it to
263 "sub" screen. window->id, perhaps? */ 202 "sub" screen. window->id, perhaps? */
264 if (!data->sub) {
265 data->bg = &BACKGROUND;
266 } else {
267 data->bg = &BACKGROUND_SUB;
268 }
269 data->bg_taken[2] = data->bg_taken[3] = 0; 203 data->bg_taken[2] = data->bg_taken[3] = 0;
270
271 NDS_OAM_Init(&(data->oam_copy), data->sub); /* init sprites. */
272 204
273 return renderer; 205 return renderer;
274 } 206 }
275 207
276 static int 208 static int
306 238
307 /* conditional statements on w/h to place it as bg/sprite 239 /* conditional statements on w/h to place it as bg/sprite
308 depending on which one it fits. */ 240 depending on which one it fits. */
309 if (texture->w <= 64 && texture->h <= 64) { 241 if (texture->w <= 64 && texture->h <= 64) {
310 int whichspr = -1; 242 int whichspr = -1;
311 printf("Tried to make a sprite.\n"); 243 printf("NDS_CreateTexture: Tried to make a sprite.\n");
312 txdat->type = NDSTX_SPR; 244 txdat->type = NDSTX_SPR;
245 #if 0
313 for (i = 0; i < SPRITE_COUNT; ++i) { 246 for (i = 0; i < SPRITE_COUNT; ++i) {
314 if (data->oam_copy.spriteBuffer[i].attribute[0] & ATTR0_DISABLED) { 247 if (data->oam_copy.spriteBuffer[i].attribute[0] & ATTR0_DISABLED) {
315 whichspr = i; 248 whichspr = i;
316 break; 249 break;
317 } 250 }
375 txdat->dim.hdy = 0; 308 txdat->dim.hdy = 0;
376 txdat->dim.vdx = 0; 309 txdat->dim.vdx = 0;
377 txdat->dim.vdy = 0x100; 310 txdat->dim.vdy = 0x100;
378 txdat->dim.pitch = pitch; 311 txdat->dim.pitch = pitch;
379 txdat->dim.bpp = bpp; 312 txdat->dim.bpp = bpp;
380 txdat->vram_pixels = (u16 *) (data->sub ? SPRITE_GFX_SUB : SPRITE_GFX); /* FIXME: use tileIdx*boundary 313 txdat->vram_pixels = (u16 *) (data->sub ? SPRITE_GFX_SUB : SPRITE_GFX);
381 to point to proper location */ 314 /* FIXME: use tileIdx*boundary
315 to point to proper location */
382 } else { 316 } else {
383 SDL_SetError("Out of NDS sprites."); 317 SDL_SetError("Out of NDS sprites.");
384 } 318 }
319 #endif
385 } else if (texture->w <= 256 && texture->h <= 256) { 320 } else if (texture->w <= 256 && texture->h <= 256) {
386 int whichbg = -1, base = 0; 321 int whichbg = -1, base = 0;
387 if (!data->bg_taken[2]) { 322 if (!data->bg_taken[2]) {
388 whichbg = 2; 323 whichbg = 2;
389 } else if (!data->bg_taken[3]) { 324 } else if (!data->bg_taken[3]) {
396 if (!txdat) { 331 if (!txdat) {
397 SDL_OutOfMemory(); 332 SDL_OutOfMemory();
398 return -1; 333 return -1;
399 } 334 }
400 335
401 /* this is hard-coded to being 256x256 ABGR1555 for now. */ 336 // hard-coded for 256x256 for now...
402 data->bg->control[whichbg] = (bpp == 8) ? 337 // TODO: a series of if-elseif-else's to find the closest but larger size.
403 BG_BMP8_256x256 : BG_BMP16_256x256; 338 if(!data->sub) {
404 339 if(bpp==8) {
405 data->bg->control[whichbg] |= BG_BMP_BASE(base); 340 txdat->hw_index = bgInit(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
406 341 } else {
407 data->bg->scroll[whichbg].x = 0; 342 txdat->hw_index = bgInit(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
408 data->bg->scroll[whichbg].y = 0; 343 }
409 344 } else {
345 if(bpp==8) {
346 txdat->hw_index = bgInitSub(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
347 } else {
348 txdat->hw_index = bgInitSub(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
349 }
350 }
351
352 /* useful functions
353 bgGetGfxPtr(bg3);
354 bgSetCenter(bg3, rcX, rcY);
355 bgSetRotateScale(bg3, angle, scaleX, scaleY);
356 bgSetScroll(bg3, scrollX, scrollY);
357 bgUpdate(bg3);
358 */
410 txdat->type = NDSTX_BG; 359 txdat->type = NDSTX_BG;
411 txdat->hw_index = whichbg; 360 txdat->pitch = (texture->w)*(bpp/8);
412 txdat->dim.hdx = 0x100; 361 txdat->bpp = bpp;
413 txdat->dim.hdy = 0; 362 txdat->rotate = 0;
414 txdat->dim.vdx = 0; 363 txdat->scale.x = 0x100;
415 txdat->dim.vdy = 0x100; 364 txdat->scale.y = 0x100;
416 txdat->dim.pitch = 512; 365 txdat->scroll.x = 0;
417 txdat->dim.bpp = bpp; 366 txdat->scroll.y = 0;
418 txdat->vram_pixels = (u16 *) (data->sub ? 367 txdat->vram_pixels = (u16*)bgGetGfxPtr(txdat->hw_index);
419 BG_BMP_RAM_SUB(base) : 368
420 BG_BMP_RAM(base)); 369 bgSetCenter(txdat->hw_index, 0, 0);
421 370 bgSetRotateScale(txdat->hw_index, txdat->rotate, txdat->scale.x,
371 txdat->scale.y);
372 bgSetScroll(txdat->hw_index, txdat->scroll.x, txdat->scroll.y);
373 bgUpdate(txdat->hw_index);
374
375 data->bg_taken[whichbg] = 1;
422 /*txdat->size = txdat->dim.pitch * texture->h; */ 376 /*txdat->size = txdat->dim.pitch * texture->h; */
423 } else { 377 } else {
424 SDL_SetError("Out of NDS backgrounds."); 378 SDL_SetError("Out of NDS backgrounds.");
425 } 379 }
426 } else { 380 } else {
438 NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, 392 NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
439 void **pixels, int *pitch) 393 void **pixels, int *pitch)
440 { 394 {
441 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; 395 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
442 *pixels = txdat->vram_pixels; 396 *pixels = txdat->vram_pixels;
443 *pitch = txdat->dim.pitch; 397 *pitch = txdat->pitch;
444 return 0; 398 return 0;
445 } 399 }
446 400
447 static int 401 static int
448 NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 402 NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
455 409
456 txdat = (NDS_TextureData *) texture->driverdata; 410 txdat = (NDS_TextureData *) texture->driverdata;
457 411
458 src = (Uint8 *) pixels; 412 src = (Uint8 *) pixels;
459 dst = 413 dst =
460 (Uint8 *) txdat->vram_pixels + rect->y * txdat->dim.pitch + 414 (Uint8 *) txdat->vram_pixels + rect->y * txdat->pitch + rect->x *
461 rect->x * ((txdat->dim.bpp + 1) / 8); 415 ((txdat->bpp + 1) / 8);
462 length = rect->w * ((txdat->dim.bpp + 1) / 8); 416 length = rect->w * ((txdat->bpp + 1) / 8);
463 417
464 if (rect->w == texture->w) { 418 if (rect->w == texture->w) {
465 dmaCopy(src, dst, length * rect->h); 419 dmaCopy(src, dst, length * rect->h);
466 } else { 420 } else {
467 for (row = 0; row < rect->h; ++row) { 421 for (row = 0; row < rect->h; ++row) {
468 dmaCopy(src, dst, length); 422 dmaCopy(src, dst, length);
469 src += pitch; 423 src += pitch;
470 dst += txdat->dim.pitch; 424 dst += txdat->pitch;
471 } 425 }
472 } 426 }
473 427
474 return 0; 428 return 0;
475 } 429 }
479 const SDL_Rect * rect, int markDirty, void **pixels, 433 const SDL_Rect * rect, int markDirty, void **pixels,
480 int *pitch) 434 int *pitch)
481 { 435 {
482 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; 436 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
483 437
484 *pixels = (void *) ((u8 *) txdat->vram_pixels + rect->y 438 *pixels = (void *) ((u8 *) txdat->vram_pixels + rect->y * txdat->pitch +
485 * txdat->dim.pitch + 439 rect->x * ((txdat->bpp + 1) / 8));
486 rect->x * ((txdat->dim.bpp + 1) / 8)); 440 *pitch = txdat->pitch;
487 *pitch = txdat->dim.pitch;
488 441
489 return 0; 442 return 0;
490 } 443 }
491 444
492 static void 445 static void
502 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; 455 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
503 SDL_Rect real_rect = *rect; 456 SDL_Rect real_rect = *rect;
504 u16 color; 457 u16 color;
505 int i, j; 458 int i, j;
506 459
507 color = RGB8(r, g, b); /* <-- macro in libnds that makes an ARGB1555 pixel */ 460 printf("NDS_RenderFill: stub\n");
461 color = RGB8(r, g, b); /* macro in libnds that makes an ARGB1555 pixel */
508 /* TODO: make a single-color sprite and stretch it. 462 /* TODO: make a single-color sprite and stretch it.
509 calculate the "HDX" width modifier of the sprite by: 463 calculate the "HDX" width modifier of the sprite by:
510 let S be the actual sprite's width (like, 32 pixels for example) 464 let S be the actual sprite's width (like, 32 pixels for example)
511 let R be the rectangle's width (maybe 50 pixels) 465 let R be the rectangle's width (maybe 50 pixels)
512 HDX = (R<<8) / S; 466 HDX = (R<<8) / S;
523 { 477 {
524 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; 478 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
525 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; 479 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
526 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 480 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
527 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 481 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
528 int i; 482 int Bpp = SDL_BYTESPERPIXEL(texture->format);
529 int bpp = SDL_BYTESPERPIXEL(texture->format);
530 int pitch = txdat->dim.pitch;
531 483
532 if (txdat->type == NDSTX_BG) { 484 if (txdat->type == NDSTX_BG) {
533 bg_rotation *bgrot = (txdat->hw_index == 2) ? 485 txdat->scroll.x = dstrect->x;
534 &(data->bg->bg2_rotation) : &(data->bg->bg3_rotation); 486 txdat->scroll.y = dstrect->y;
535 bgrot->xdx = txdat->dim.hdx;
536 bgrot->xdy = txdat->dim.hdy;
537 bgrot->ydx = txdat->dim.vdx;
538 bgrot->ydy = txdat->dim.vdy;
539 bgrot->centerX = 0;
540 bgrot->centerY = 0;
541
542 data->bg->scroll[txdat->hw_index].x = dstrect->x;
543 data->bg->scroll[txdat->hw_index].y = dstrect->y;
544 } else { 487 } else {
545 /* sprites not fully implemented yet */ 488 /* sprites not fully implemented yet */
546 SpriteEntry *spr = &(data->oam_copy.spriteBuffer[txdat->hw_index]); 489 printf("NDS_RenderCopy: used sprite!\n");
547 spr->posX = dstrect->x; 490 // SpriteEntry *spr = &(data->oam_copy.spriteBuffer[txdat->hw_index]);
548 spr->posY = dstrect->y; 491 // spr->posX = dstrect->x;
549 if (txdat->hw_index < MATRIX_COUNT && spr->isRotoscale) { 492 // spr->posY = dstrect->y;
550 SpriteRotation *sprot = 493 // if (txdat->hw_index < MATRIX_COUNT && spr->isRotoscale) {
551 &(data->oam_copy.matrixBuffer[txdat->hw_index]); 494 // }
552 sprot->hdx = txdat->dim.hdx;
553 sprot->hdy = txdat->dim.hdy;
554 sprot->vdx = txdat->dim.vdx;
555 sprot->vdy = txdat->dim.vdy;
556 }
557 } 495 }
558 496
559 return 0; 497 return 0;
560 } 498 }
561 499
566 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; 504 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
567 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 505 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
568 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 506 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
569 507
570 /* update sprites */ 508 /* update sprites */
571 NDS_OAM_Update(&(data->oam_copy), data->sub); 509 // NDS_OAM_Update(&(data->oam_copy), data->sub);
572 /* vsync for NDS */ 510 /* vsync for NDS */
573 if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) { 511 if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
574 swiWaitForVBlank(); 512 swiWaitForVBlank();
575 } 513 }
576 } 514 }