Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
More NDS video driver work.
Browse files Browse the repository at this point in the history
  • Loading branch information
Darren Alton committed Jul 13, 2008
1 parent 1d02a71 commit 9b99592
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 104 deletions.
189 changes: 102 additions & 87 deletions src/video/nds/SDL_ndsrender.c
Expand Up @@ -79,27 +79,33 @@ static void NDS_DestroyRenderer(SDL_Renderer * renderer);

SDL_RenderDriver NDS_RenderDriver = {
NDS_CreateRenderer,
{"nds", SDL_RENDERER_SINGLEBUFFER}
/*SDL_RENDERER_ values
SINGLEBUFFER Render directly to the window, if possible
PRESENTCOPY Present uses a copy from back buffer to the front buffer
PRESENTFLIP2 Present uses a flip, swapping back buffer and front buffer
PRESENTFLIP3 Present uses a flip, rotating two back buf.s and a front buf.
PRESENTDISCARD Present leaves the contents of the backbuffer undefined
PRESENTVSYNC Present is synchronized with the refresh rate
ACCELERATED The renderer uses hardware acceleration
*/
{ "nds", /* char* name */
(SDL_RENDERER_SINGLEBUFFER|SDL_RENDERER_ACCELERATED), /* u32 flags */
(SDL_TEXTUREMODULATE_NONE), /* u32 mod_modes */
(SDL_TEXTUREBLENDMODE_NONE), /* u32 blend_modes */
(SDL_TEXTURESCALEMODE_NONE), /* u32 scale_modes */
3, /* u32 num_texture_formats */
{
SDL_PIXELFORMAT_INDEX8,
SDL_PIXELFORMAT_RGB555,
SDL_PIXELFORMAT_RGB565
}, /* u32 texture_formats[20] */
(256), /* int max_texture_width */
(256), /* int max_texture_height */
}
};

typedef struct
{
int current_screen;
u16* fb;
bg_attribute *bg;
u8 bg_taken[4];
int sub;
} NDS_RenderData;

typedef struct
{
enum { NDSTX_BG, NDSTX_SPR } type;
int hw_index;
struct { int w, h, pitch, bpp; } dim;
u16 *vram;
} NDS_TextureData;
Expand All @@ -119,23 +125,6 @@ sdlds_rgb2bgr(u16 c)
return (c & GAmask) | r | b;
}

void
sdlds_surf2vram(SDL_Surface * s)
{
if (s->w == 256) {
u16 tmpbuf[0x20000];
int i;

dmaCopy((u8 *) (s->pixels) + 156 * sizeof(u16),
tmpbuf, 256 * 192 * sizeof(u16));
/* hack to fix the pixel format until I figure out why BGR doesn't work */
for (i = 0; i < 256 * 192; ++i) {
tmpbuf[i] = sdlds_rgb2bgr(tmpbuf[i]);
}
dmaCopy(tmpbuf, VRAM_A, 256 * 192 * sizeof(u16));
}
}

void
sdlds_print_pixfmt_info(SDL_PixelFormat * f)
{
Expand Down Expand Up @@ -200,32 +189,36 @@ NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.flags = 0;
renderer->window = window->id;
renderer->driverdata = data;
Setup_SoftwareRenderer(renderer); /* TODO: well, "TODON'T" is more like it */

if (flags & SDL_RENDERER_PRESENTFLIP2) {
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
n = 2;
} else if (flags & SDL_RENDERER_PRESENTFLIP3) {
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
n = 3;
} else {
renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
n = 1;
}
/*
for (i = 0; i < n; ++i) {
data->screens[i] =
SDL_CreateRGBSurface(0, 256, 192, bpp, Rmask, Gmask, Bmask,
Amask);
if (!data->screens[i]) {
NDS_DestroyRenderer(renderer);
return NULL;
}
SDL_SetSurfacePalette(data->screens[i], display->palette);
sdlds_print_surface_info(data->screens[i]);
}*/

data->fb = (u16*)0x06020000;
renderer->CreateTexture = NDS_CreateTexture;
renderer->QueryTexturePixels = NDS_QueryTexturePixels;
renderer->SetTexturePalette = NDS_SetTexturePalette;
renderer->GetTexturePalette = NDS_GetTexturePalette;
renderer->SetTextureColorMod = NDS_SetTextureColorMod;
renderer->SetTextureAlphaMod = NDS_SetTextureAlphaMod;
renderer->SetTextureBlendMode = NDS_SetTextureBlendMode;
renderer->SetTextureScaleMode = NDS_SetTextureScaleMode;
renderer->UpdateTexture = NDS_UpdateTexture;
renderer->LockTexture = NDS_LockTexture;
renderer->UnlockTexture = NDS_UnlockTexture;
renderer->DirtyTexture = NDS_DirtyTexture;
renderer->DestroyTexture = NDS_DestroyTexture;

renderer->info.mod_modes = NDS_RenderDriver.info.mod_modes;
renderer->info.blend_modes = NDS_RenderDriver.info.blend_modes;
renderer->info.scale_modes = NDS_RenderDriver.info.scale_modes;
renderer->info.num_texture_formats =
NDS_RenderDriver.info.num_texture_formats;
SDL_memcpy(renderer->info.texture_formats,
NDS_RenderDriver.info.texture_formats,
sizeof(renderer->info.texture_formats));;
renderer->info.max_texture_width = NDS_RenderDriver.info.max_texture_width;
renderer->info.max_texture_height =
NDS_RenderDriver.info.max_texture_height;

/*data->fb = (u16*)0x06020000;*/
data->bg = &BACKGROUND;
data->bg_taken[2] = data->bg_taken[3] = 0;
data->sub = 0;

return renderer;
}
Expand All @@ -250,7 +243,7 @@ static int
NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;

NDS_TextureData *txdat = NULL;
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
SDL_SetError("Unsupported texture format");
return -1;
Expand All @@ -263,9 +256,49 @@ NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_SetError("Unknown texture format");
return -1;
}
/* TODO: appropriate checks for ABGR1555 */
texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
/* TODO: conditional statements on w/h to place it as bg/sprite */
/* conditional statements on w/h to place it as bg/sprite */
/*if(texture->w <= 64 && texture->h <= 64) {
sprites not implemented yet. elegant, I know.
} else*/ if(texture->w <= 256 && texture->h <= 256) {
int whichbg = -1;
if(!data->bg_taken[2]) {
whichbg = 2;
data->bg->bg2_rotation.xdx = 0x100;
data->bg->bg2_rotation.xdy = 0;
data->bg->bg2_rotation.ydx = 0;
data->bg->bg2_rotation.ydy = 0x100;
data->bg->bg2_rotation.centerX = 0;
data->bg->bg2_rotation.centerY = 0;
} else if(!data->bg_taken[3]) {
whichbg = 3;
data->bg->bg3_rotation.xdx = 0x100;
data->bg->bg3_rotation.xdy = 0;
data->bg->bg3_rotation.ydx = 0;
data->bg->bg3_rotation.ydy = 0x100;
data->bg->bg3_rotation.centerX = 0;
data->bg->bg3_rotation.centerY = 0;
}
if(whichbg >= 0) {
data->bg->control[whichbg] = (bpp == 8) ?
BG_BMP8_256x256 : BG_BMP16_256x256;
data->bg->scroll[whichbg].x = 0;
data->bg->scroll[whichbg].y = 0;
texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
txdat = (NDS_TextureData*)texture->driverdata;
txdat->type = NDSTX_BG;
txdat->hw_index = whichbg;
txdat->dim.w = texture->w;
txdat->dim.h = texture->h;
txdat->dim.pitch = 256 * (bpp/8);
txdat->dim.bpp = bpp;
txdat->vram = (u16*)(data->sub ?
BG_BMP_RAM_SUB(whichbg) : BG_BMP_RAM(whichbg));
} else {
SDL_SetError("Out of NDS backgrounds.");
}
} else {
SDL_SetError("Texture too big for NDS hardware.");
}
}

if (!texture->driverdata) {
Expand Down Expand Up @@ -368,7 +401,7 @@ NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += surface->pitch;
dst += txdat->dim.pitch;
}
return 0;
}
Expand Down Expand Up @@ -415,13 +448,14 @@ NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
u16 color;
int i, j;

/* TODO: make a single-color sprite and stretch it.
color = RGB15(r>>3,g>>3,b>>3);
for (i = real_rect.x; i < real_rect.x+real_rect.w; ++i) {
for (j = real_rect.y; j < real_rect.y+real_rect.h; ++j) {
data->fb[(j + real_rect.y) * 256 + i + real_rect.x] =
0x8000 | color;
}
}
}*/
return 0;
}

Expand All @@ -448,26 +482,9 @@ NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
SDL_Surface *target = data->screens[data->current_screen];
SDL_Rect real_srcrect = *srcrect;
SDL_Rect real_dstrect = *dstrect;
/*sdlds_print_surface_info(surface);
sdlds_print_surface_info(target); */
sdlds_surf2vram(surface);
return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
}
#endif
/* copy it directly to vram */
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
sdlds_surf2vram(surface);
/*
int sx = srcrect->x, sy = srcrect->y, sw = srcrect->w, sh = srcrect->h;
int dx = dstrect->x, dy = dstrect->y, dw = dstrect->w, dh = dstrect->h;
int si, sj, di, dj;
for (sj = 0, dj = 0; sj < sh && dj < dh; ++sj, ++dj) {
for (si = 0, di = 0; si < sw && di < dw; ++si, ++di) {
data->fb[(dj + dy) * 256 + di + dx] = 0x8000 |
((u16 *) surface->pixels)[(sj + sy) * (surface->w) + si +
sx];
}
}*/
return 0;
}

Expand All @@ -479,10 +496,8 @@ NDS_RenderPresent(SDL_Renderer * renderer)
/* Send the data to the display TODO */

/* Update the flipping chain, if any */
if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
data->current_screen = (data->current_screen + 1) % 2;
} else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
data->current_screen = (data->current_screen + 1) % 3;
if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
swiWaitForVBlank();
}
}

Expand All @@ -492,9 +507,8 @@ NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
SDL_SetError("Unsupported texture format");
} else {
/* TODO: free anything allocated for texture */
/*SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
SDL_FreeSurface(surface);*/
/* free anything else allocated for texture */
SDL_free(texture->driverdata);
}
}

Expand All @@ -507,7 +521,8 @@ NDS_DestroyRenderer(SDL_Renderer * renderer)
int i;

if (data) {
for (i = 0; i < SDL_arraysize(data->texture); ++i) {
/* TODO: free anything relevant. */
/*for (i = 0; i < SDL_arraysize(data->texture); ++i) {
if (data->texture[i]) {
DestroyTexture(data->renderer, data->texture[i]);
}
Expand All @@ -520,7 +535,7 @@ NDS_DestroyRenderer(SDL_Renderer * renderer)
SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
data);
}
SDL_FreeDirtyRects(&data->dirty);
SDL_FreeDirtyRects(&data->dirty);*/
SDL_free(data);
}
SDL_free(renderer);
Expand Down
35 changes: 18 additions & 17 deletions src/video/nds/SDL_ndsvideo.c
Expand Up @@ -116,46 +116,44 @@ NDS_VideoInit(_THIS)
/* simple 256x192x15x60 for now */
mode.w = 256;
mode.h = 192;
mode.format = SDL_PIXELFORMAT_BGR555;
mode.format = SDL_PIXELFORMAT_ABGR1555;
mode.refresh_rate = 60;
mode.driverdata = NULL;

SDL_AddBasicVideoDisplay(&mode);
SDL_AddRenderDriver(0, &NDS_RenderDriver);
/*SDL_AddBasicVideoDisplay(&mode); two screens, same mode. uncomment later
SDL_AddRenderDriver(1, &NDS_RenderDriver);*/

SDL_zero(mode);
SDL_AddDisplayMode(0, &mode);

/* hackish stuff to get things up and running for now, and for a console */
powerON(POWER_ALL);
videoSetMode(MODE_FB0);
videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); /* debug text on sub */
vramSetBankA(VRAM_A_LCD);
vramSetBankC(VRAM_C_SUB_BG);
irqInit();
irqEnable(IRQ_VBLANK);
/* set up console for debug text 'n stuff */
SUB_BG0_CR = BG_MAP_BASE(31);
BG_PALETTE_SUB[255] = RGB15(31, 31, 31);
consoleInitDefault((u16 *) SCREEN_BASE_BLOCK_SUB(31),
(u16 *) CHAR_BASE_BLOCK_SUB(0), 16);

/*NDS_SetDisplayMode(_this, &mode); */
powerON(POWER_ALL); irqInit();
irqEnable(IRQ_VBLANK);
NDS_SetDisplayMode(_this, &mode);
return 0;
}

static int
NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
{
/* right now this function is just hard-coded for 256x192 ABGR1555 */
#if 0
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE); /* display on main core */
videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); /* debug text on sub */
vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_LCD,
VRAM_C_SUB_BG, VRAM_D_LCD);

/* set up console for debug text 'n stuff */
SUB_BG0_CR = BG_MAP_BASE(31);
BG_PALETTE_SUB[255] = RGB15(31, 31, 31);
consoleInitDefault((u16 *) SCREEN_BASE_BLOCK_SUB(31),
(u16 *) CHAR_BASE_BLOCK_SUB(0), 16);

#if 0
/* we should be using this as a texture for rendering, not as a framebuffer */
/* maps well to the 256x192 screen anyway. note: need VRAM_B for bigger */
BG3_CR = BG_BMP16_256x256;
BACKGROUND.control[3] = BG_BMP16_256x256;
/* affine transformation matrix. nothing too fancy here */
BG3_XDX = 0x100;
BG3_XDY = 0;
Expand All @@ -171,6 +169,9 @@ NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
void
NDS_VideoQuit(_THIS)
{
videoSetMode(DISPLAY_SCREEN_OFF);
videoSetModeSub(DISPLAY_SCREEN_OFF);
vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
}

/* vi: set ts=4 sw=4 expandtab: */
Expand Down

0 comments on commit 9b99592

Please sign in to comment.