Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

NDS compiles again, but may not yet work. Sprite support has been rem…

…oved for the time being while it is re-worked.
  • Loading branch information
Darren Alton committed Feb 18, 2009
1 parent 8de4855 commit e4fea42d3cb3a7ab93672d9c9f70162c50fb2aae
Showing with 80 additions and 140 deletions.
  1. +3 −1 Makefile.ds
  2. +77 −139 src/video/nds/SDL_ndsrender.c
@@ -87,7 +87,9 @@ src/video/SDL_blit_copy.c \
src/video/SDL_blit_N.c \
src/video/SDL_blit_slow.c \
src/video/SDL_bmp.c \
src/video/SDL_fill.c \
src/video/SDL_drawline.c \
src/video/SDL_drawpoint.c \
src/video/SDL_fillrect.c \
src/video/SDL_gamma.c \
src/video/SDL_pixels.c \
src/video/SDL_rect.c \
@@ -23,9 +23,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <nds.h>
#include <nds/arm9/video.h>
#include <nds/arm9/sprite.h>
#include <nds/arm9/trig_lut.h>
//#include <nds/arm9/video.h>
//#include <nds/arm9/sprite.h>
//#include <nds/arm9/trig_lut.h>

#include "SDL_config.h"

@@ -34,65 +34,6 @@
#include "../SDL_yuv_sw_c.h"
#include "../SDL_renderer_sw.h"

/* NDS sprite-related functions */
#define SPRITE_DMA_CHANNEL 3
#define SPRITE_ANGLE_MASK 0x01FF

void
NDS_OAM_Update(tOAM * oam, int sub)
{
DC_FlushAll();
dmaCopyHalfWords(SPRITE_DMA_CHANNEL, oam->spriteBuffer,
sub ? OAM_SUB : OAM, SPRITE_COUNT * sizeof(SpriteEntry));
}

void
NDS_OAM_RotateSprite(SpriteRotation * spriteRotation, u16 angle)
{
s16 s = SIN[angle & SPRITE_ANGLE_MASK] >> 4;
s16 c = COS[angle & SPRITE_ANGLE_MASK] >> 4;

spriteRotation->hdx = c;
spriteRotation->hdy = s;
spriteRotation->vdx = -s;
spriteRotation->vdy = c;
}

void
NDS_OAM_Init(tOAM * oam, int sub)
{
int i;
for (i = 0; i < SPRITE_COUNT; i++) {
oam->spriteBuffer[i].attribute[0] = ATTR0_DISABLED;
oam->spriteBuffer[i].attribute[1] = 0;
oam->spriteBuffer[i].attribute[2] = 0;
}
for (i = 0; i < MATRIX_COUNT; i++) {
NDS_OAM_RotateSprite(&(oam->matrixBuffer[i]), 0);
}
swiWaitForVBlank();
NDS_OAM_Update(oam, sub);
}

void
NDS_OAM_HideSprite(SpriteEntry * spriteEntry)
{
spriteEntry->isRotoscale = 0;
spriteEntry->isHidden = 1;
}

void
NDS_OAM_ShowSprite(SpriteEntry * spriteEntry, int affine, int double_bound)
{
if (affine) {
spriteEntry->isRotoscale = 1;
spriteEntry->rsDouble = double_bound;
} else {
spriteEntry->isHidden = 0;
}
}


/* SDL NDS renderer implementation */

static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags);
@@ -147,30 +88,28 @@ SDL_RenderDriver NDS_RenderDriver = {
SDL_PIXELFORMAT_INDEX8,
SDL_PIXELFORMAT_ABGR1555,
SDL_PIXELFORMAT_BGR555,
}, /* u32 texture_formats[20] */
}, /* u32 texture_formats[20] */
(256), /* int max_texture_width */
(256), /* int max_texture_height */
}
};

typedef struct
{
bg_attribute *bg; /* backgrounds */
tOAM oam_copy; /* sprites */
u8 bg_taken[4];
OamState *oam;
int sub;
} NDS_RenderData;

typedef struct
{
enum
{ NDSTX_BG, NDSTX_SPR } type; /* represented in a bg or sprite. */
int hw_index; /* sprite: index in the OAM. / bg: 2 or 3. */
struct
{
int hdx, hdy, vdx, vdy; /* affine transformation, used for scaling. */
int pitch, bpp; /* some useful info */
} dim;
int hw_index; /* index of sprite in OAM or bg from libnds */
int pitch, bpp; /* useful information about the texture */
struct { int x,y; } scale; /* x/y stretch (24.8 fixed point) */
struct { int x,y; } scroll; /* x/y offset */
int rotate; /* -32768 to 32767, texture rotation */
u16 *vram_pixels; /* where the pixel data is stored (a pointer into VRAM) */
u16 *vram_palette; /* where the palette data is stored if it's indexed. */
/*int size; */
@@ -258,18 +197,11 @@ NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.max_texture_height =
NDS_RenderDriver.info.max_texture_height;

data->sub = 0; /* TODO: this is hard-coded to the "main" screen.
figure out how to detect whether to set it to
"sub" screen. window->id, perhaps? */
if (!data->sub) {
data->bg = &BACKGROUND;
} else {
data->bg = &BACKGROUND_SUB;
}
data->sub = 0; /* TODO: this is hard-coded to the "main" screen.
figure out how to detect whether to set it to
"sub" screen. window->id, perhaps? */
data->bg_taken[2] = data->bg_taken[3] = 0;

NDS_OAM_Init(&(data->oam_copy), data->sub); /* init sprites. */

return renderer;
}

@@ -308,8 +240,9 @@ NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
depending on which one it fits. */
if (texture->w <= 64 && texture->h <= 64) {
int whichspr = -1;
printf("Tried to make a sprite.\n");
printf("NDS_CreateTexture: Tried to make a sprite.\n");
txdat->type = NDSTX_SPR;
#if 0
for (i = 0; i < SPRITE_COUNT; ++i) {
if (data->oam_copy.spriteBuffer[i].attribute[0] & ATTR0_DISABLED) {
whichspr = i;
@@ -377,11 +310,13 @@ NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
txdat->dim.vdy = 0x100;
txdat->dim.pitch = pitch;
txdat->dim.bpp = bpp;
txdat->vram_pixels = (u16 *) (data->sub ? SPRITE_GFX_SUB : SPRITE_GFX); /* FIXME: use tileIdx*boundary
to point to proper location */
txdat->vram_pixels = (u16 *) (data->sub ? SPRITE_GFX_SUB : SPRITE_GFX);
/* FIXME: use tileIdx*boundary
to point to proper location */
} else {
SDL_SetError("Out of NDS sprites.");
}
#endif
} else if (texture->w <= 256 && texture->h <= 256) {
int whichbg = -1, base = 0;
if (!data->bg_taken[2]) {
@@ -398,27 +333,46 @@ NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return -1;
}

/* this is hard-coded to being 256x256 ABGR1555 for now. */
data->bg->control[whichbg] = (bpp == 8) ?
BG_BMP8_256x256 : BG_BMP16_256x256;

data->bg->control[whichbg] |= BG_BMP_BASE(base);

data->bg->scroll[whichbg].x = 0;
data->bg->scroll[whichbg].y = 0;
// hard-coded for 256x256 for now...
// TODO: a series of if-elseif-else's to find the closest but larger size.
if(!data->sub) {
if(bpp==8) {
txdat->hw_index = bgInit(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
} else {
txdat->hw_index = bgInit(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
}
} else {
if(bpp==8) {
txdat->hw_index = bgInitSub(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
} else {
txdat->hw_index = bgInitSub(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
}
}

/* useful functions
bgGetGfxPtr(bg3);
bgSetCenter(bg3, rcX, rcY);
bgSetRotateScale(bg3, angle, scaleX, scaleY);
bgSetScroll(bg3, scrollX, scrollY);
bgUpdate(bg3);
*/
txdat->type = NDSTX_BG;
txdat->hw_index = whichbg;
txdat->dim.hdx = 0x100;
txdat->dim.hdy = 0;
txdat->dim.vdx = 0;
txdat->dim.vdy = 0x100;
txdat->dim.pitch = 512;
txdat->dim.bpp = bpp;
txdat->vram_pixels = (u16 *) (data->sub ?
BG_BMP_RAM_SUB(base) :
BG_BMP_RAM(base));

txdat->pitch = (texture->w)*(bpp/8);
txdat->bpp = bpp;
txdat->rotate = 0;
txdat->scale.x = 0x100;
txdat->scale.y = 0x100;
txdat->scroll.x = 0;
txdat->scroll.y = 0;
txdat->vram_pixels = (u16*)bgGetGfxPtr(txdat->hw_index);

bgSetCenter(txdat->hw_index, 0, 0);
bgSetRotateScale(txdat->hw_index, txdat->rotate, txdat->scale.x,
txdat->scale.y);
bgSetScroll(txdat->hw_index, txdat->scroll.x, txdat->scroll.y);
bgUpdate(txdat->hw_index);

data->bg_taken[whichbg] = 1;
/*txdat->size = txdat->dim.pitch * texture->h; */
} else {
SDL_SetError("Out of NDS backgrounds.");
@@ -440,7 +394,7 @@ NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
{
NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
*pixels = txdat->vram_pixels;
*pitch = txdat->dim.pitch;
*pitch = txdat->pitch;
return 0;
}

@@ -457,17 +411,17 @@ NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,

src = (Uint8 *) pixels;
dst =
(Uint8 *) txdat->vram_pixels + rect->y * txdat->dim.pitch +
rect->x * ((txdat->dim.bpp + 1) / 8);
length = rect->w * ((txdat->dim.bpp + 1) / 8);
(Uint8 *) txdat->vram_pixels + rect->y * txdat->pitch + rect->x *
((txdat->bpp + 1) / 8);
length = rect->w * ((txdat->bpp + 1) / 8);

if (rect->w == texture->w) {
dmaCopy(src, dst, length * rect->h);
} else {
for (row = 0; row < rect->h; ++row) {
dmaCopy(src, dst, length);
src += pitch;
dst += txdat->dim.pitch;
dst += txdat->pitch;
}
}

@@ -481,10 +435,9 @@ NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
{
NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;

*pixels = (void *) ((u8 *) txdat->vram_pixels + rect->y
* txdat->dim.pitch +
rect->x * ((txdat->dim.bpp + 1) / 8));
*pitch = txdat->dim.pitch;
*pixels = (void *) ((u8 *) txdat->vram_pixels + rect->y * txdat->pitch +
rect->x * ((txdat->bpp + 1) / 8));
*pitch = txdat->pitch;

return 0;
}
@@ -504,7 +457,8 @@ NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
u16 color;
int i, j;

color = RGB8(r, g, b); /* <-- macro in libnds that makes an ARGB1555 pixel */
printf("NDS_RenderFill: stub\n");
color = RGB8(r, g, b); /* macro in libnds that makes an ARGB1555 pixel */
/* TODO: make a single-color sprite and stretch it.
calculate the "HDX" width modifier of the sprite by:
let S be the actual sprite's width (like, 32 pixels for example)
@@ -525,35 +479,19 @@ NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
int i;
int bpp = SDL_BYTESPERPIXEL(texture->format);
int pitch = txdat->dim.pitch;
int Bpp = SDL_BYTESPERPIXEL(texture->format);

if (txdat->type == NDSTX_BG) {
bg_rotation *bgrot = (txdat->hw_index == 2) ?
&(data->bg->bg2_rotation) : &(data->bg->bg3_rotation);
bgrot->xdx = txdat->dim.hdx;
bgrot->xdy = txdat->dim.hdy;
bgrot->ydx = txdat->dim.vdx;
bgrot->ydy = txdat->dim.vdy;
bgrot->centerX = 0;
bgrot->centerY = 0;

data->bg->scroll[txdat->hw_index].x = dstrect->x;
data->bg->scroll[txdat->hw_index].y = dstrect->y;
txdat->scroll.x = dstrect->x;
txdat->scroll.y = dstrect->y;
} else {
/* sprites not fully implemented yet */
SpriteEntry *spr = &(data->oam_copy.spriteBuffer[txdat->hw_index]);
spr->posX = dstrect->x;
spr->posY = dstrect->y;
if (txdat->hw_index < MATRIX_COUNT && spr->isRotoscale) {
SpriteRotation *sprot =
&(data->oam_copy.matrixBuffer[txdat->hw_index]);
sprot->hdx = txdat->dim.hdx;
sprot->hdy = txdat->dim.hdy;
sprot->vdx = txdat->dim.vdx;
sprot->vdy = txdat->dim.vdy;
}
printf("NDS_RenderCopy: used sprite!\n");
// SpriteEntry *spr = &(data->oam_copy.spriteBuffer[txdat->hw_index]);
// spr->posX = dstrect->x;
// spr->posY = dstrect->y;
// if (txdat->hw_index < MATRIX_COUNT && spr->isRotoscale) {
// }
}

return 0;
@@ -568,7 +506,7 @@ NDS_RenderPresent(SDL_Renderer * renderer)
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);

/* update sprites */
NDS_OAM_Update(&(data->oam_copy), data->sub);
// NDS_OAM_Update(&(data->oam_copy), data->sub);
/* vsync for NDS */
if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
swiWaitForVBlank();

0 comments on commit e4fea42

Please sign in to comment.