Mercurial > sdl-ios-xcode
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 } |