renderer: Added a separate copy of texture pixels in system RAM, copied into VRAM during RenderPresent. Still trying to fix rendering.
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
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.
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.
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
27 #include "SDL_config.h"
29 #include "SDL_video.h"
30 #include "../SDL_sysvideo.h"
31 #include "../SDL_yuv_sw_c.h"
32 #include "../SDL_renderer_sw.h"
35 /* SDL NDS renderer implementation */
37 static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags);
38 static int NDS_ActivateRenderer(SDL_Renderer * renderer);
39 static int NDS_DisplayModeChanged(SDL_Renderer * renderer);
40 static int NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
41 static int NDS_QueryTexturePixels(SDL_Renderer * renderer,
42 SDL_Texture * texture, void **pixels,
44 static int NDS_SetTexturePalette(SDL_Renderer * renderer,
45 SDL_Texture * texture,
46 const SDL_Color * colors, int firstcolor,
48 static int NDS_GetTexturePalette(SDL_Renderer * renderer,
49 SDL_Texture * texture, SDL_Color * colors,
50 int firstcolor, int ncolors);
51 static int NDS_SetTextureColorMod(SDL_Renderer * renderer,
52 SDL_Texture * texture);
53 static int NDS_SetTextureAlphaMod(SDL_Renderer * renderer,
54 SDL_Texture * texture);
55 static int NDS_SetTextureBlendMode(SDL_Renderer * renderer,
56 SDL_Texture * texture);
57 static int NDS_SetTextureScaleMode(SDL_Renderer * renderer,
58 SDL_Texture * texture);
59 static int NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
60 const SDL_Rect * rect, const void *pixels,
62 static int NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
63 const SDL_Rect * rect, int markDirty, void **pixels,
65 static void NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
66 static void NDS_DirtyTexture(SDL_Renderer * renderer,
67 SDL_Texture * texture, int numrects,
68 const SDL_Rect * rects);
69 static int NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g,
70 Uint8 b, Uint8 a, const SDL_Rect * rect);
71 static int NDS_RenderCopy(SDL_Renderer * renderer,
72 SDL_Texture * texture,
73 const SDL_Rect * srcrect,
74 const SDL_Rect * dstrect);
75 static void NDS_RenderPresent(SDL_Renderer * renderer);
76 static void NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
77 static void NDS_DestroyRenderer(SDL_Renderer * renderer);
80 SDL_RenderDriver NDS_RenderDriver = {
82 { "nds", /* char* name */
83 (SDL_RENDERER_SINGLEBUFFER|SDL_RENDERER_ACCELERATED), /* u32 flags */
84 (SDL_TEXTUREMODULATE_NONE), /* u32 mod_modes */
85 (SDL_TEXTUREBLENDMODE_NONE), /* u32 blend_modes */
86 (SDL_TEXTURESCALEMODE_NONE), /* u32 scale_modes */
87 3, /* u32 num_texture_formats */
89 SDL_PIXELFORMAT_INDEX8,
90 SDL_PIXELFORMAT_ABGR1555,
91 SDL_PIXELFORMAT_BGR555,
92 }, /* u32 texture_formats[20] */
93 (256), /* int max_texture_width */
94 (256), /* int max_texture_height */
102 /* todo for sprites: pSpriteRotation and pSpriteEntry. pointers to OAM */
108 enum { NDSTX_BG, NDSTX_SPR } type;
110 struct { int hdx, hdy, vdx, vdy, pitch, bpp; } dim;
112 u16 *system_ram_copy;
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
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;
131 /* again the above shouldn't make it into the stable version */
134 NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
136 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
137 SDL_DisplayMode *displayMode = &display->current_mode;
138 SDL_Renderer *renderer;
139 NDS_RenderData *data;
142 Uint32 Rmask, Gmask, Bmask, Amask;
143 /* Uint32 Rmask = 0x7C00, Gmask = 0x03E0, Bmask = 0x001F, Amask = 0x8000;
144 Uint32 Rmask = 0x001F, Gmask = 0x03E0, Bmask = 0x7C00, Amask = 0x8000;
146 printf("+NDS_CreateRenderer\n");
148 /* hard coded this to BGR555 for now */
149 if (!SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_BGR555, &bpp,
150 &Rmask, &Gmask, &Bmask, &Amask)) {
151 SDL_SetError("Unknown display format");
155 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
161 data = (NDS_RenderData *) SDL_malloc(sizeof(*data));
163 NDS_DestroyRenderer(renderer);
169 renderer->RenderFill = NDS_RenderFill;
170 renderer->RenderCopy = NDS_RenderCopy;
171 renderer->RenderPresent = NDS_RenderPresent;
172 renderer->DestroyRenderer = NDS_DestroyRenderer;
173 renderer->info.name = NDS_RenderDriver.info.name;
174 renderer->info.flags = 0;
175 renderer->window = window->id;
176 renderer->driverdata = data;
177 renderer->CreateTexture = NDS_CreateTexture;
178 renderer->QueryTexturePixels = NDS_QueryTexturePixels;
179 renderer->SetTexturePalette = NDS_SetTexturePalette;
180 renderer->GetTexturePalette = NDS_GetTexturePalette;
181 renderer->SetTextureColorMod = NDS_SetTextureColorMod;
182 renderer->SetTextureAlphaMod = NDS_SetTextureAlphaMod;
183 renderer->SetTextureBlendMode = NDS_SetTextureBlendMode;
184 renderer->SetTextureScaleMode = NDS_SetTextureScaleMode;
185 renderer->UpdateTexture = NDS_UpdateTexture;
186 renderer->LockTexture = NDS_LockTexture;
187 renderer->UnlockTexture = NDS_UnlockTexture;
188 renderer->DirtyTexture = NDS_DirtyTexture;
189 renderer->DestroyTexture = NDS_DestroyTexture;
191 renderer->info.mod_modes = NDS_RenderDriver.info.mod_modes;
192 renderer->info.blend_modes = NDS_RenderDriver.info.blend_modes;
193 renderer->info.scale_modes = NDS_RenderDriver.info.scale_modes;
194 renderer->info.num_texture_formats =
195 NDS_RenderDriver.info.num_texture_formats;
196 SDL_memcpy(renderer->info.texture_formats,
197 NDS_RenderDriver.info.texture_formats,
198 sizeof(renderer->info.texture_formats));;
199 renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width;
200 renderer->info.max_texture_height =
201 NDS_RenderDriver.info.max_texture_height;
203 /*data->fb = (u16*)0x06020000;*/
204 data->bg = &BACKGROUND;
205 data->bg_taken[2] = data->bg_taken[3] = 0;
208 printf("-NDS_CreateRenderer\n");
213 NDS_ActivateRenderer(SDL_Renderer * renderer)
215 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
216 /* stub. TODO: figure out what needs to be done, if anything. */
217 printf("!NDS_ActivateRenderer\n");
222 NDS_DisplayModeChanged(SDL_Renderer * renderer)
224 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
225 /* stub. TODO: figure out what needs to be done */
226 printf("!NDS_DisplayModeChanged\n");
231 NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
233 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
234 NDS_TextureData *txdat = NULL;
236 printf("+NDS_CreateTexture\n");
237 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
238 SDL_SetError("Unsupported texture format");
242 Uint32 Rmask, Gmask, Bmask, Amask;
244 if (!SDL_PixelFormatEnumToMasks
245 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
246 SDL_SetError("Unknown texture format");
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) {
254 if(!data->bg_taken[2]) {
256 } else if(!data->bg_taken[3]) {
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);
277 SDL_SetError("Out of NDS backgrounds.");
278 printf("ran out.\n");
281 SDL_SetError("Texture too big for NDS hardware.");
285 printf("-NDS_CreateTexture\n");
286 if (!texture->driverdata) {
293 NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
294 void **pixels, int *pitch)
296 printf("+NDS_QueryTexturePixels\n");
297 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
298 SDL_SetError("Unsupported texture format");
301 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
303 *pixels = txdat->vram;
304 *pitch = txdat->dim.pitch;
305 printf("-NDS_QueryTexturePixels\n");
311 NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
312 const SDL_Rect * rect, const void *pixels, int pitch)
314 printf("+NDS_UpdateTexture\n");
315 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
316 SDL_SetError("Unsupported texture format");
319 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
323 /* IMPORTANT! copy the new pixels into the sprite or bg. */
324 src = (Uint8 *) pixels;
326 (Uint8 *) txdat->system_ram_copy + rect->y * txdat->dim.pitch +
327 rect->x * (txdat->dim.bpp/8);
328 length = rect->w * (txdat->dim.bpp/8);
329 for (row = 0; row < rect->h; ++row) {
330 SDL_memcpy(dst, src, length);
332 dst += txdat->dim.pitch;
334 printf("-NDS_UpdateTexture\n");
340 NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
341 const SDL_Rect * rect, int markDirty, void **pixels,
344 printf("+NDS_LockTexture\n");
345 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
346 SDL_SetError("Unsupported texture format");
349 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
352 printf("wanted to mark dirty\n");
353 /*SDL_AddDirtyRect(&txdat->dirty, rect);*/
356 *pixels = (void *) ((u8 *)txdat->system_ram_copy + rect->y
357 * txdat->dim.pitch + rect->x * (txdat->dim.bpp/8));
358 *pitch = txdat->dim.pitch;
359 printf(" pixels = %08x\n", (u32)*pixels);
360 printf("-NDS_LockTexture\n");
366 NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
368 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
369 SDL_SetError("Unsupported texture format");
371 printf("+NDS_UnlockTexture\n-NDS_UnlockTexture\n");
375 NDS_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
376 int numrects, const SDL_Rect * rects)
378 printf("!NDS_DirtyTexture\n");
382 NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
383 Uint8 a, const SDL_Rect * rect)
385 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
386 SDL_Rect real_rect = *rect;
390 printf("+NDS_RenderFill\n");
391 /* TODO: make a single-color sprite and stretch it.
392 color = RGB15(r>>3,g>>3,b>>3);
393 for (i = real_rect.x; i < real_rect.x+real_rect.w; ++i) {
394 for (j = real_rect.y; j < real_rect.y+real_rect.h; ++j) {
395 data->fb[(j + real_rect.y) * 256 + i + real_rect.x] =
399 printf("-NDS_RenderFill\n");
404 NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
405 const SDL_Rect * srcrect, const SDL_Rect * dstrect)
407 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
408 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
409 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
410 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
412 int bpp = SDL_BYTESPERPIXEL(texture->format);
413 int pitch = txdat->dim.pitch;
414 printf("+NDS_RenderCopy\n");
415 if(txdat->type == NDSTX_BG) {
416 bg_rotation *tmpbg = (txdat->hw_index == 2) ?
417 &(data->bg->bg2_rotation) : &(data->bg->bg3_rotation);
418 tmpbg->xdx = txdat->dim.hdx;
419 tmpbg->xdy = txdat->dim.hdy;
420 tmpbg->ydx = txdat->dim.vdx;
421 tmpbg->ydy = txdat->dim.vdy;
425 /* sprites not implemented yet */
427 printf(" txdat->hw_index = %d\n", txdat->hw_index);
428 printf("-NDS_RenderCopy\n");
434 NDS_RenderPresent(SDL_Renderer * renderer)
436 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
437 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
438 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
440 /* Send the data to the display TODO :
441 shouldn't it already be there at this point?
442 I guess set the BG's and sprites "visible" flags here. */
443 printf("+NDS_RenderPresent\n");
445 for(i = 0; i < 64; ++i) {
446 SDL_Texture * tx = display->textures[i];
447 NDS_TextureData * txdat = (NDS_TextureData*)tx->driverdata;
448 SDL_memcpy(txdat->vram, txdat->system_ram_copy, txdat->size);
452 if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
455 printf("-NDS_RenderPresent\n");
459 NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
461 printf("+NDS_DestroyTexture\n");
462 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
463 SDL_SetError("Unsupported texture format");
465 /* free anything else allocated for texture */
466 NDS_TextureData *txdat = texture->driverdata;
467 /*SDL_FreeDirtyRects(&txdat->dirty);*/
468 SDL_free(txdat->system_ram_copy);
471 printf("-NDS_DestroyTexture\n");
475 NDS_DestroyRenderer(SDL_Renderer * renderer)
477 NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
478 /*SDL_Window *window = SDL_GetWindowFromID(renderer->window);
479 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);*/
482 printf("+NDS_DestroyRenderer\n");
484 /* TODO: free anything relevant. */
485 /*for (i = 0; i < SDL_arraysize(data->texture); ++i) {
486 if (data->texture[i]) {
487 DestroyTexture(data->renderer, data->texture[i]);
490 if (data->surface.format) {
491 SDL_SetSurfacePalette(&data->surface, NULL);
492 SDL_FreeFormat(data->surface.format);
494 if (display->palette) {
495 SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
498 SDL_FreeDirtyRects(&data->dirty);*/
502 printf("-NDS_DestroyRenderer\n");
506 NDS_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
507 const SDL_Color * colors, int firstcolor, int ncolors)
509 printf("+NDS_SetTexturePalette\n");
510 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
511 SDL_SetError("YUV textures don't have a palette");
514 NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
515 /* TODO: mess with 8-bit modes and/or 16-color palette modes */
516 printf("-NDS_SetTexturePalette\n");
522 NDS_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
523 SDL_Color * colors, int firstcolor, int ncolors)
525 printf("+NDS_GetTexturePalette\n");
526 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
527 SDL_SetError("YUV textures don't have a palette");
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 */
538 NDS_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
540 printf("!NDS_SetTextureColorMod\n");
541 /* stub. TODO: figure out what needs to be done, if anything */
546 NDS_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
548 printf("!NDS_SetTextureAlphaMod\n");
549 /* stub. TODO: figure out what needs to be done, if anything */
554 NDS_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
556 printf("!NDS_SetTextureBlendMode\n");
557 /* stub. TODO: figure out what needs to be done, if anything */
562 NDS_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
564 printf("!NDS_SetTextureScaleMode\n");
565 /* stub. TODO: figure out what needs to be done.
566 (NDS hardware scaling is nearest neighbor.) */
570 /* vi: set ts=4 sw=4 expandtab: */