Mercurial > sdl-ios-xcode
comparison src/video/nds/SDL_ndsrender.c @ 2688:71c56e900f8b gsoc2008_nds
Cleaning up the renderer code to hopefully squish any problems. Starting to incorporate sprites, as well
author | Darren Alton <dalton@stevens.edu> |
---|---|
date | Fri, 15 Aug 2008 10:17:07 +0000 |
parents | 5166b19b6808 |
children | ca01c20274c0 |
comparison
equal
deleted
inserted
replaced
2687:5166b19b6808 | 2688:71c56e900f8b |
---|---|
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> | |
27 #include <nds/arm9/sprite.h> | |
28 #include <nds/arm9/trig_lut.h> | |
26 | 29 |
27 #include "SDL_config.h" | 30 #include "SDL_config.h" |
28 | 31 |
29 #include "SDL_video.h" | 32 #include "SDL_video.h" |
30 #include "../SDL_sysvideo.h" | 33 #include "../SDL_sysvideo.h" |
31 #include "../SDL_yuv_sw_c.h" | 34 #include "../SDL_yuv_sw_c.h" |
32 #include "../SDL_renderer_sw.h" | 35 #include "../SDL_renderer_sw.h" |
36 | |
37 | |
38 | |
39 /* NDS sprite-related functions */ | |
40 #define SPRITE_DMA_CHANNEL 3 | |
41 #define SPRITE_ANGLE_MASK 0x01FF | |
42 | |
43 void | |
44 NDS_OAM_Update(tOAM *oam) | |
45 { | |
46 DC_FlushAll(); | |
47 dmaCopyHalfWords(SPRITE_DMA_CHANNEL, oam->spriteBuffer, OAM, | |
48 SPRITE_COUNT * sizeof(SpriteEntry)); | |
49 } | |
50 | |
51 void | |
52 NDS_OAM_RotateSprite(SpriteRotation *spriteRotation, u16 angle) | |
53 { | |
54 s16 s = SIN[angle & SPRITE_ANGLE_MASK] >> 4; | |
55 s16 c = COS[angle & SPRITE_ANGLE_MASK] >> 4; | |
56 | |
57 spriteRotation->hdx = c; | |
58 spriteRotation->hdy = s; | |
59 spriteRotation->vdx = -s; | |
60 spriteRotation->vdy = c; | |
61 } | |
62 | |
63 void | |
64 NDS_OAM_Init(tOAM *oam) | |
65 { | |
66 int i; | |
67 for(i = 0; i < SPRITE_COUNT; i++) { | |
68 oam->spriteBuffer[i].attribute[0] = ATTR0_DISABLED; | |
69 oam->spriteBuffer[i].attribute[1] = 0; | |
70 oam->spriteBuffer[i].attribute[2] = 0; | |
71 } | |
72 for(i = 0; i < MATRIX_COUNT; i++) { | |
73 NDS_OAM_RotateSprite(&(oam->matrixBuffer[i]), 0); | |
74 } | |
75 swiWaitForVBlank(); | |
76 NDS_OAM_Update(oam); | |
77 } | |
78 | |
79 void | |
80 NDS_OAM_HideSprite(SpriteEntry *spriteEntry) | |
81 { | |
82 spriteEntry->isRotoscale = 0; | |
83 spriteEntry->isHidden = 1; | |
84 } | |
85 | |
86 void | |
87 NDS_OAM_ShowSprite(SpriteEntry *spriteEntry, int affine, int double_bound) | |
88 { | |
89 if (affine) { | |
90 spriteEntry->isRotoscale = 1; | |
91 spriteEntry->rsDouble = double_bound; | |
92 } else { | |
93 spriteEntry->isHidden = 0; | |
94 } | |
95 } | |
33 | 96 |
34 | 97 |
35 /* SDL NDS renderer implementation */ | 98 /* SDL NDS renderer implementation */ |
36 | 99 |
37 static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags); | 100 static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags); |
95 } | 158 } |
96 }; | 159 }; |
97 | 160 |
98 typedef struct | 161 typedef struct |
99 { | 162 { |
100 bg_attribute *bg; | 163 bg_attribute *bg; /* backgrounds */ |
164 tOAM oam_copy; /* sprites */ | |
101 u8 bg_taken[4]; | 165 u8 bg_taken[4]; |
102 /* todo for sprites: pSpriteRotation and pSpriteEntry. pointers to OAM */ | |
103 int sub; | 166 int sub; |
104 } NDS_RenderData; | 167 } NDS_RenderData; |
105 | 168 |
106 typedef struct | 169 typedef struct |
107 { | 170 { |
112 u16 *system_ram_copy; | 175 u16 *system_ram_copy; |
113 int size; | 176 int size; |
114 } NDS_TextureData; | 177 } NDS_TextureData; |
115 | 178 |
116 | 179 |
117 /* this is mainly hackish testing/debugging stuff to get cleaned up soon | |
118 anything named sdlds_blah shouldn't make it into the stable version | |
119 */ | |
120 | |
121 u16 | |
122 sdlds_rgb2bgr(u16 c) | |
123 { | |
124 /* hack to get the proper colors until I actually get BGR555 to work right */ | |
125 u16 Rmask = 0x7C00, Bmask = 0x001F, GAmask = 0x83E0, r, b; | |
126 r = (c & Rmask) >> 10; | |
127 b = (c & Bmask) << 10; | |
128 return (c & GAmask) | r | b; | |
129 } | |
130 | |
131 /* again the above shouldn't make it into the stable version */ | |
132 | 180 |
133 SDL_Renderer * | 181 SDL_Renderer * |
134 NDS_CreateRenderer(SDL_Window * window, Uint32 flags) | 182 NDS_CreateRenderer(SDL_Window * window, Uint32 flags) |
135 { | 183 { |
136 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | 184 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); |
137 SDL_DisplayMode *displayMode = &display->current_mode; | 185 SDL_DisplayMode *displayMode = &display->current_mode; |
138 SDL_Renderer *renderer; | 186 SDL_Renderer *renderer; |
139 NDS_RenderData *data; | 187 NDS_RenderData *data; |
140 int i, n; | 188 int i, n; |
141 int bpp = 15; | 189 int bpp; |
142 Uint32 Rmask, Gmask, Bmask, Amask; | 190 Uint32 Rmask, Gmask, Bmask, Amask; |
143 /* Uint32 Rmask = 0x7C00, Gmask = 0x03E0, Bmask = 0x001F, Amask = 0x8000; | 191 |
144 Uint32 Rmask = 0x001F, Gmask = 0x03E0, Bmask = 0x7C00, Amask = 0x8000; | |
145 */ | |
146 printf("+NDS_CreateRenderer\n"); | 192 printf("+NDS_CreateRenderer\n"); |
147 | 193 if (!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp, |
148 /* hard coded this to BGR555 for now */ | |
149 if (!SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_BGR555, &bpp, | |
150 &Rmask, &Gmask, &Bmask, &Amask)) { | 194 &Rmask, &Gmask, &Bmask, &Amask)) { |
151 SDL_SetError("Unknown display format"); | 195 SDL_SetError("Unknown display format"); |
152 return NULL; | 196 return NULL; |
197 } | |
198 switch(displayMode->format) { | |
199 case SDL_PIXELFORMAT_INDEX8: | |
200 case SDL_PIXELFORMAT_ABGR1555: | |
201 case SDL_PIXELFORMAT_BGR555: | |
202 /* okay */ | |
203 break; | |
204 default: | |
205 printf("DEBUG: wrong display format!\n"); | |
206 break; | |
153 } | 207 } |
154 | 208 |
155 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); | 209 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); |
156 if (!renderer) { | 210 if (!renderer) { |
157 SDL_OutOfMemory(); | 211 SDL_OutOfMemory(); |
198 sizeof(renderer->info.texture_formats));; | 252 sizeof(renderer->info.texture_formats));; |
199 renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width; | 253 renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width; |
200 renderer->info.max_texture_height = | 254 renderer->info.max_texture_height = |
201 NDS_RenderDriver.info.max_texture_height; | 255 NDS_RenderDriver.info.max_texture_height; |
202 | 256 |
203 /*data->fb = (u16*)0x06020000;*/ | 257 data->bg = &BACKGROUND; /* BACKGROUND_SUB for second screen. */ |
204 data->bg = &BACKGROUND; | |
205 data->bg_taken[2] = data->bg_taken[3] = 0; | 258 data->bg_taken[2] = data->bg_taken[3] = 0; |
206 data->sub = 0; | 259 NDS_OAM_Init(&(data->oam_copy)); /* init sprites. */ |
260 | |
261 data->sub = 0; /* TODO: this is hard-coded to the "main" screen. | |
262 figure out how to detect whether to set it to | |
263 "sub" screen. window->id, perhaps? */ | |
207 | 264 |
208 printf("-NDS_CreateRenderer\n"); | 265 printf("-NDS_CreateRenderer\n"); |
209 return renderer; | 266 return renderer; |
210 } | 267 } |
211 | 268 |
212 static int | 269 static int |
213 NDS_ActivateRenderer(SDL_Renderer * renderer) | 270 NDS_ActivateRenderer(SDL_Renderer * renderer) |
214 { | 271 { |
215 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; | 272 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; |
216 /* stub. TODO: figure out what needs to be done, if anything. */ | 273 printf("!NDS_ActivateRenderer\n"); |
217 printf("!NDS_ActivateRenderer\n"); | |
218 return 0; | 274 return 0; |
219 } | 275 } |
220 | 276 |
221 static int | 277 static int |
222 NDS_DisplayModeChanged(SDL_Renderer * renderer) | 278 NDS_DisplayModeChanged(SDL_Renderer * renderer) |
223 { | 279 { |
224 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; | 280 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; |
225 /* stub. TODO: figure out what needs to be done */ | 281 printf("!NDS_DisplayModeChanged\n"); |
226 printf("!NDS_DisplayModeChanged\n"); | |
227 return 0; | 282 return 0; |
228 } | 283 } |
229 | 284 |
230 static int | 285 static int |
231 NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 286 NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
232 { | 287 { |
233 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; | 288 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; |
234 NDS_TextureData *txdat = NULL; | 289 NDS_TextureData *txdat = NULL; |
235 int i; | 290 int i; |
236 printf("+NDS_CreateTexture\n"); | 291 int bpp; |
237 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 292 Uint32 Rmask, Gmask, Bmask, Amask; |
238 SDL_SetError("Unsupported texture format"); | 293 |
294 printf("+NDS_CreateTexture\n"); | |
295 if (!SDL_PixelFormatEnumToMasks | |
296 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
297 SDL_SetError("Unknown texture format"); | |
239 return -1; | 298 return -1; |
299 } | |
300 | |
301 /* conditional statements on w/h to place it as bg/sprite | |
302 depending on which one it fits. */ | |
303 if(texture->w <= 64 && texture->h <= 64) { | |
304 /* TODO: implement sprites similar to how BG's are. | |
305 they have a similar affine transformation matrix | |
306 (hdx,hdy,vdx,vdy) as the backgrounds, so it should | |
307 be similar enough to handle with the same driverdata. */ | |
308 printf("Tried to make a sprite.\n"); | |
309 } else if(texture->w <= 256 && texture->h <= 256) { | |
310 int whichbg = -1; | |
311 if(!data->bg_taken[2]) { | |
312 whichbg = 2; | |
313 } else if(!data->bg_taken[3]) { | |
314 whichbg = 3; | |
315 } | |
316 if(whichbg >= 0) { | |
317 /* TODO: maybe this should be in RenderPresent or RenderCopy | |
318 instead, copying from a malloc'd system RAM pixel buffer. */ | |
319 data->bg->control[whichbg] = (bpp == 8) ? | |
320 BG_BMP8_256x256 : BG_BMP16_256x256; | |
321 data->bg->scroll[whichbg].x = 0; | |
322 data->bg->scroll[whichbg].y = 0; | |
323 texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData)); | |
324 txdat = (NDS_TextureData*)texture->driverdata; | |
325 txdat->type = NDSTX_BG; | |
326 txdat->hw_index = whichbg; | |
327 txdat->dim.hdx = 0x100; txdat->dim.hdy = 0; | |
328 txdat->dim.vdx = 0; txdat->dim.vdy = 0x100; | |
329 txdat->dim.pitch = 256 * (bpp/8); | |
330 txdat->dim.bpp = bpp; | |
331 txdat->vram = (u16*)(data->sub ? | |
332 BG_BMP_RAM_SUB(whichbg) : BG_BMP_RAM(whichbg)); | |
333 txdat->size = txdat->dim.pitch * texture->h; | |
334 } else { | |
335 SDL_SetError("Out of NDS backgrounds."); | |
336 printf("ran out.\n"); | |
337 } | |
240 } else { | 338 } else { |
241 int bpp; | 339 SDL_SetError("Texture too big for NDS hardware."); |
242 Uint32 Rmask, Gmask, Bmask, Amask; | 340 } |
243 | 341 |
244 if (!SDL_PixelFormatEnumToMasks | 342 printf("-NDS_CreateTexture\n"); |
245 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
246 SDL_SetError("Unknown texture format"); | |
247 return -1; | |
248 } | |
249 /* conditional statements on w/h to place it as bg/sprite */ | |
250 /*if(texture->w <= 64 && texture->h <= 64) { | |
251 sprites not implemented yet. elegant, I know. | |
252 } else*/ if(texture->w <= 256 && texture->h <= 256) { | |
253 int whichbg = -1; | |
254 if(!data->bg_taken[2]) { | |
255 whichbg = 2; | |
256 } else if(!data->bg_taken[3]) { | |
257 whichbg = 3; | |
258 } | |
259 if(whichbg >= 0) { | |
260 data->bg->control[whichbg] = (bpp == 8) ? | |
261 BG_BMP8_256x256 : BG_BMP16_256x256; | |
262 data->bg->scroll[whichbg].x = 0; | |
263 data->bg->scroll[whichbg].y = 0; | |
264 texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData)); | |
265 txdat = (NDS_TextureData*)texture->driverdata; | |
266 txdat->type = NDSTX_BG; | |
267 txdat->hw_index = whichbg; | |
268 txdat->dim.hdx = 0x100; txdat->dim.hdy = 0; | |
269 txdat->dim.vdx = 0; txdat->dim.vdy = 0x100; | |
270 txdat->dim.pitch = 256 * (bpp/8); | |
271 txdat->dim.bpp = bpp; | |
272 txdat->vram = (u16*)(data->sub ? | |
273 BG_BMP_RAM_SUB(whichbg) : BG_BMP_RAM(whichbg)); | |
274 txdat->size = txdat->dim.pitch * texture->h; | |
275 txdat->system_ram_copy = SDL_malloc(txdat->size); | |
276 } else { | |
277 SDL_SetError("Out of NDS backgrounds."); | |
278 printf("ran out.\n"); | |
279 } | |
280 } else { | |
281 SDL_SetError("Texture too big for NDS hardware."); | |
282 } | |
283 } | |
284 | |
285 printf("-NDS_CreateTexture\n"); | |
286 if (!texture->driverdata) { | 343 if (!texture->driverdata) { |
344 SDL_SetError("Couldn't create NDS render driver data."); | |
287 return -1; | 345 return -1; |
288 } | 346 } |
347 | |
289 return 0; | 348 return 0; |
290 } | 349 } |
291 | 350 |
292 static int | 351 static int |
293 NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, | 352 NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, |
294 void **pixels, int *pitch) | 353 void **pixels, int *pitch) |
295 { | 354 { |
296 printf("+NDS_QueryTexturePixels\n"); | 355 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; |
297 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 356 printf("+NDS_QueryTexturePixels\n"); |
298 SDL_SetError("Unsupported texture format"); | 357 *pixels = txdat->vram; |
299 return -1; | 358 *pitch = txdat->dim.pitch; |
300 } else { | 359 printf("-NDS_QueryTexturePixels\n"); |
301 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; | 360 return 0; |
302 | |
303 *pixels = txdat->vram; | |
304 *pitch = txdat->dim.pitch; | |
305 printf("-NDS_QueryTexturePixels\n"); | |
306 return 0; | |
307 } | |
308 } | 361 } |
309 | 362 |
310 static int | 363 static int |
311 NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 364 NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
312 const SDL_Rect * rect, const void *pixels, int pitch) | 365 const SDL_Rect * rect, const void *pixels, int pitch) |
313 { | 366 { |
314 printf("+NDS_UpdateTexture\n"); | 367 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; |
315 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 368 Uint8 *src, *dst; |
316 SDL_SetError("Unsupported texture format"); | 369 int row; size_t length; |
317 return -1; | 370 printf("+NDS_UpdateTexture\n"); |
318 } else { | 371 |
319 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; | 372 src = (Uint8 *) pixels; |
320 Uint8 *src, *dst; | 373 dst = |
321 int row; | 374 (Uint8 *) txdat->system_ram_copy + rect->y * txdat->dim.pitch + |
322 size_t length; | 375 rect->x * (txdat->dim.bpp/8); |
323 /* IMPORTANT! copy the new pixels into the sprite or bg. */ | 376 length = rect->w * (txdat->dim.bpp/8); |
324 src = (Uint8 *) pixels; | 377 for (row = 0; row < rect->h; ++row) { |
325 dst = | 378 SDL_memcpy(dst, src, length); |
326 (Uint8 *) txdat->system_ram_copy + rect->y * txdat->dim.pitch + | 379 src += pitch; |
327 rect->x * (txdat->dim.bpp/8); | 380 dst += txdat->dim.pitch; |
328 length = rect->w * (txdat->dim.bpp/8); | 381 } |
329 for (row = 0; row < rect->h; ++row) { | 382 |
330 SDL_memcpy(dst, src, length); | 383 printf("-NDS_UpdateTexture\n"); |
331 src += pitch; | 384 return 0; |
332 dst += txdat->dim.pitch; | |
333 } | |
334 printf("-NDS_UpdateTexture\n"); | |
335 return 0; | |
336 } | |
337 } | 385 } |
338 | 386 |
339 static int | 387 static int |
340 NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 388 NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
341 const SDL_Rect * rect, int markDirty, void **pixels, | 389 const SDL_Rect * rect, int markDirty, void **pixels, |
342 int *pitch) | 390 int *pitch) |
343 { | 391 { |
344 printf("+NDS_LockTexture\n"); | 392 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; |
345 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 393 int i; |
346 SDL_SetError("Unsupported texture format"); | 394 printf("+NDS_LockTexture\n"); |
347 return -1; | 395 if (markDirty) { |
348 } else { | 396 printf("wanted to mark dirty\n"); |
349 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; | 397 /* TODO: figure out how to handle this! */ |
350 | 398 /*SDL_AddDirtyRect(&txdat->dirty, rect);*/ |
351 if (markDirty) { | 399 } |
352 printf("wanted to mark dirty\n"); | 400 |
353 /*SDL_AddDirtyRect(&txdat->dirty, rect);*/ | 401 *pixels = (void *) ((u8 *)txdat->vram + rect->y |
354 } | 402 * txdat->dim.pitch + rect->x * (txdat->dim.bpp/8)); |
355 | 403 *pitch = txdat->dim.pitch; |
356 *pixels = (void *) ((u8 *)txdat->system_ram_copy + rect->y | 404 printf(" pixels = %08x\n", (u32)*pixels); |
357 * txdat->dim.pitch + rect->x * (txdat->dim.bpp/8)); | 405 printf(" vram = %08x\n", (u32)(txdat->vram)); |
358 *pitch = txdat->dim.pitch; | 406 printf("-NDS_LockTexture\n"); |
359 printf(" pixels = %08x\n", (u32)*pixels); | 407 return 0; |
360 printf("-NDS_LockTexture\n"); | |
361 return 0; | |
362 } | |
363 } | 408 } |
364 | 409 |
365 static void | 410 static void |
366 NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 411 NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
367 { | 412 { |
368 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 413 printf("+NDS_UnlockTexture\n"); |
369 SDL_SetError("Unsupported texture format"); | 414 /* TODO: should I be doing something here, somehow, now that the pixels |
370 } | 415 should have been "written" between LockTexture and this? */ |
371 printf("+NDS_UnlockTexture\n-NDS_UnlockTexture\n"); | 416 printf("-NDS_UnlockTexture\n"); |
372 } | 417 } |
373 | 418 |
374 static void | 419 static void |
375 NDS_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 420 NDS_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
376 int numrects, const SDL_Rect * rects) | 421 int numrects, const SDL_Rect * rects) |
377 { /* stub */ | 422 { |
378 printf("!NDS_DirtyTexture\n"); | 423 /* stub */ |
424 printf("!NDS_DirtyTexture\n"); | |
379 } | 425 } |
380 | 426 |
381 static int | 427 static int |
382 NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, | 428 NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, |
383 Uint8 a, const SDL_Rect * rect) | 429 Uint8 a, const SDL_Rect * rect) |
385 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; | 431 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; |
386 SDL_Rect real_rect = *rect; | 432 SDL_Rect real_rect = *rect; |
387 u16 color; | 433 u16 color; |
388 int i, j; | 434 int i, j; |
389 | 435 |
390 printf("+NDS_RenderFill\n"); | 436 printf("+NDS_RenderFill\n"); |
437 color = RGB8(r,g,b); /* <-- macro in libnds that makes an ARGB1555 pixel */ | |
391 /* TODO: make a single-color sprite and stretch it. | 438 /* TODO: make a single-color sprite and stretch it. |
392 color = RGB15(r>>3,g>>3,b>>3); | 439 calculate the "HDX" width modifier of the sprite by: |
393 for (i = real_rect.x; i < real_rect.x+real_rect.w; ++i) { | 440 let S be the actual sprite's width (like, 32 pixels for example) |
394 for (j = real_rect.y; j < real_rect.y+real_rect.h; ++j) { | 441 let R be the rectangle's width (maybe 50 pixels) |
395 data->fb[(j + real_rect.y) * 256 + i + real_rect.x] = | 442 HDX = (R<<8) / S; |
396 0x8000 | color; | 443 (it's fixed point, hence the bit shift. same goes for vertical. |
397 } | 444 be sure to use 32-bit int's for the bit shift before the division!) |
398 }*/ | 445 */ |
399 printf("-NDS_RenderFill\n"); | 446 |
447 printf("-NDS_RenderFill\n"); | |
400 return 0; | 448 return 0; |
401 } | 449 } |
402 | 450 |
403 static int | 451 static int |
404 NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | 452 NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, |
409 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | 457 SDL_Window *window = SDL_GetWindowFromID(renderer->window); |
410 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | 458 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); |
411 int i; | 459 int i; |
412 int bpp = SDL_BYTESPERPIXEL(texture->format); | 460 int bpp = SDL_BYTESPERPIXEL(texture->format); |
413 int pitch = txdat->dim.pitch; | 461 int pitch = txdat->dim.pitch; |
414 printf("+NDS_RenderCopy\n"); | 462 printf("+NDS_RenderCopy\n"); |
415 if(txdat->type == NDSTX_BG) { | 463 if(txdat->type == NDSTX_BG) { |
416 bg_rotation *tmpbg = (txdat->hw_index == 2) ? | 464 bg_rotation *tmpbg = (txdat->hw_index == 2) ? |
417 &(data->bg->bg2_rotation) : &(data->bg->bg3_rotation); | 465 &(data->bg->bg2_rotation) : &(data->bg->bg3_rotation); |
418 tmpbg->xdx = txdat->dim.hdx; | 466 tmpbg->xdx = txdat->dim.hdx; |
419 tmpbg->xdy = txdat->dim.hdy; | 467 tmpbg->xdy = txdat->dim.hdy; |
423 tmpbg->centerY = 0; | 471 tmpbg->centerY = 0; |
424 } else { | 472 } else { |
425 /* sprites not implemented yet */ | 473 /* sprites not implemented yet */ |
426 } | 474 } |
427 printf(" txdat->hw_index = %d\n", txdat->hw_index); | 475 printf(" txdat->hw_index = %d\n", txdat->hw_index); |
428 printf("-NDS_RenderCopy\n"); | 476 printf("-NDS_RenderCopy\n"); |
429 return 0; | 477 return 0; |
430 } | 478 } |
431 | 479 |
432 | 480 |
433 static void | 481 static void |
435 { | 483 { |
436 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; | 484 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; |
437 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | 485 SDL_Window *window = SDL_GetWindowFromID(renderer->window); |
438 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | 486 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); |
439 int i; | 487 int i; |
440 /* Send the data to the display TODO : | 488 printf("+NDS_RenderPresent\n"); |
441 shouldn't it already be there at this point? | 489 |
442 I guess set the BG's and sprites "visible" flags here. */ | 490 { |
443 printf("+NDS_RenderPresent\n"); | |
444 | |
445 for(i = 0; i < 64; ++i) { | |
446 SDL_Texture * tx = display->textures[i]; | 491 SDL_Texture * tx = display->textures[i]; |
447 NDS_TextureData * txdat = (NDS_TextureData*)tx->driverdata; | 492 NDS_TextureData * txdat = (NDS_TextureData*)tx->driverdata; |
448 SDL_memcpy(txdat->vram, txdat->system_ram_copy, txdat->size); | 493 /* Send the data to the display TODO : |
494 shouldn't it already be there at this point? from lock/unlock | |
495 giving it the direct address in VRAM of the bg's. | |
496 I guess set the BG's and sprites "visible" flags here, | |
497 if applicable. */ | |
449 } | 498 } |
450 | 499 |
451 /* vsync for NDS */ | 500 /* vsync for NDS */ |
452 if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) { | 501 if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) { |
453 swiWaitForVBlank(); | 502 swiWaitForVBlank(); |
454 } | 503 } |
455 printf("-NDS_RenderPresent\n"); | 504 printf("-NDS_RenderPresent\n"); |
456 } | 505 } |
457 | 506 |
458 static void | 507 static void |
459 NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 508 NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
460 { | 509 { |
461 printf("+NDS_DestroyTexture\n"); | 510 printf("+NDS_DestroyTexture\n"); |
462 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 511 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
463 SDL_SetError("Unsupported texture format"); | 512 SDL_SetError("Unsupported texture format"); |
464 } else { | 513 } else { |
465 /* free anything else allocated for texture */ | 514 /* free anything else allocated for texture */ |
466 NDS_TextureData *txdat = texture->driverdata; | 515 NDS_TextureData *txdat = texture->driverdata; |
467 /*SDL_FreeDirtyRects(&txdat->dirty);*/ | 516 /*SDL_FreeDirtyRects(&txdat->dirty);*/ |
468 SDL_free(txdat->system_ram_copy); | 517 SDL_free(txdat->system_ram_copy); |
469 SDL_free(txdat); | 518 SDL_free(txdat); |
470 } | 519 } |
471 printf("-NDS_DestroyTexture\n"); | 520 printf("-NDS_DestroyTexture\n"); |
472 } | 521 } |
473 | 522 |
474 static void | 523 static void |
475 NDS_DestroyRenderer(SDL_Renderer * renderer) | 524 NDS_DestroyRenderer(SDL_Renderer * renderer) |
476 { | 525 { |
477 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; | 526 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata; |
478 /*SDL_Window *window = SDL_GetWindowFromID(renderer->window); | 527 /*SDL_Window *window = SDL_GetWindowFromID(renderer->window); |
479 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);*/ | 528 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);*/ |
480 int i; | 529 int i; |
481 | 530 |
482 printf("+NDS_DestroyRenderer\n"); | 531 printf("+NDS_DestroyRenderer\n"); |
483 if (data) { | 532 if (data) { |
484 /* TODO: free anything relevant. */ | 533 /* TODO: free anything else relevant. */ |
485 /*for (i = 0; i < SDL_arraysize(data->texture); ++i) { | 534 /*for (i = 0; i < SDL_arraysize(data->texture); ++i) { |
486 if (data->texture[i]) { | 535 if (data->texture[i]) { |
487 DestroyTexture(data->renderer, data->texture[i]); | 536 DestroyTexture(data->renderer, data->texture[i]); |
488 } | 537 } |
489 } | 538 } |
497 } | 546 } |
498 SDL_FreeDirtyRects(&data->dirty);*/ | 547 SDL_FreeDirtyRects(&data->dirty);*/ |
499 SDL_free(data); | 548 SDL_free(data); |
500 } | 549 } |
501 SDL_free(renderer); | 550 SDL_free(renderer); |
502 printf("-NDS_DestroyRenderer\n"); | 551 printf("-NDS_DestroyRenderer\n"); |
503 } | 552 } |
504 | 553 |
505 static int | 554 static int |
506 NDS_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, | 555 NDS_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, |
507 const SDL_Color * colors, int firstcolor, int ncolors) | 556 const SDL_Color * colors, int firstcolor, int ncolors) |
508 { | 557 { |
509 printf("+NDS_SetTexturePalette\n"); | 558 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; |
510 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 559 printf("+NDS_SetTexturePalette\n"); |
511 SDL_SetError("YUV textures don't have a palette"); | 560 /* set 8-bit modes in the background control registers |
512 return -1; | 561 for backgrounds, BGn_CR |= BG_256_COLOR */ |
513 } else { | 562 printf("-NDS_SetTexturePalette\n"); |
514 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; | 563 return 0; |
515 /* TODO: mess with 8-bit modes and/or 16-color palette modes */ | |
516 printf("-NDS_SetTexturePalette\n"); | |
517 return 0; | |
518 } | |
519 } | 564 } |
520 | 565 |
521 static int | 566 static int |
522 NDS_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, | 567 NDS_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, |
523 SDL_Color * colors, int firstcolor, int ncolors) | 568 SDL_Color * colors, int firstcolor, int ncolors) |
524 { | 569 { |
525 printf("+NDS_GetTexturePalette\n"); | 570 printf("+NDS_GetTexturePalette\n"); |
526 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 571 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; |
527 SDL_SetError("YUV textures don't have a palette"); | 572 printf("-NDS_GetTexturePalette\n"); |
528 return -1; | 573 return 0; |
529 } else { | |
530 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata; | |
531 printf("-NDS_GetTexturePalette\n"); | |
532 /* TODO: mess with 8-bit modes and/or 16-color palette modes */ | |
533 return 0; | |
534 } | |
535 } | 574 } |
536 | 575 |
537 static int | 576 static int |
538 NDS_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) | 577 NDS_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) |
539 { | 578 { |
540 printf("!NDS_SetTextureColorMod\n"); | 579 printf("!NDS_SetTextureColorMod\n"); |
541 /* stub. TODO: figure out what needs to be done, if anything */ | 580 /* stub! */ |
542 return 0; | 581 return 0; |
543 } | 582 } |
544 | 583 |
545 static int | 584 static int |
546 NDS_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) | 585 NDS_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) |
547 { | 586 { |
548 printf("!NDS_SetTextureAlphaMod\n"); | 587 printf("!NDS_SetTextureAlphaMod\n"); |
549 /* stub. TODO: figure out what needs to be done, if anything */ | 588 /* stub! */ |
550 return 0; | 589 return 0; |
551 } | 590 } |
552 | 591 |
553 static int | 592 static int |
554 NDS_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) | 593 NDS_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) |
555 { | 594 { |
556 printf("!NDS_SetTextureBlendMode\n"); | 595 printf("!NDS_SetTextureBlendMode\n"); |
557 /* stub. TODO: figure out what needs to be done, if anything */ | 596 /* stub! */ |
558 return 0; | 597 return 0; |
559 } | 598 } |
560 | 599 |
561 static int | 600 static int |
562 NDS_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) | 601 NDS_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) |
563 { | 602 { |
564 printf("!NDS_SetTextureScaleMode\n"); | 603 printf("!NDS_SetTextureScaleMode\n"); |
565 /* stub. TODO: figure out what needs to be done. | 604 /* stub! (note: NDS hardware scaling is nearest neighbor.) */ |
566 (NDS hardware scaling is nearest neighbor.) */ | |
567 return 0; | 605 return 0; |
568 } | 606 } |
569 | 607 |
570 /* vi: set ts=4 sw=4 expandtab: */ | 608 /* vi: set ts=4 sw=4 expandtab: */ |