gpu-remove endian swapping struct balderdash from sprite rendering

This commit is contained in:
zeromus 2012-06-13 19:41:54 +00:00
parent 811b94de9b
commit 130623e6ab
3 changed files with 94 additions and 118 deletions

View File

@ -219,14 +219,14 @@ void GPU_Reset(GPU *g, u8 l)
if(g->core == GPU_SUB)
{
g->oam = (OAM *)(MMU.ARM9_OAM + ADDRESS_STEP_1KB);
g->oam = (MMU.ARM9_OAM + ADDRESS_STEP_1KB);
g->sprMem = MMU_BOBJ;
// GPU core B
g->dispx_st = (REG_DISPx*)(&MMU.ARM9_REG[REG_DISPB]);
}
else
{
g->oam = (OAM *)(MMU.ARM9_OAM);
g->oam = (MMU.ARM9_OAM);
g->sprMem = MMU_AOBJ;
// GPU core A
g->dispx_st = (REG_DISPx*)(&MMU.ARM9_REG[0]);
@ -822,6 +822,45 @@ finish:
}
}
//unpacks an _OAM_ structure from the provided oam buffer (should point at OAM 0) and provided OAM index.
//is endian-safe
void SlurpOAM(_OAM_* oam_output, void* oam_buffer, int oam_index)
{
u16* u16_oam_buffer = (u16*)oam_buffer;
int u16_offset = oam_index<<2;
u16 attr[4];
for(int i=0;i<4;i++)
attr[i] = LE_TO_LOCAL_16(u16_oam_buffer[u16_offset + i]);
oam_output->Y = (attr[0]>>0) & 0xFF;
oam_output->RotScale = (attr[0]>>8)&3;
oam_output->Mode = (attr[0]>>10)&3;
oam_output->Mosaic = (attr[0]>>12)&1;
oam_output->Depth = (attr[0]>>13)&1;
oam_output->Shape = (attr[0]>>14)&3;
oam_output->X = (s16)((attr[1]>>0)&0x1FF);
oam_output->RotScalIndex = (attr[1]>>9)&7;
oam_output->HFlip = (attr[1]>>12)&1;
oam_output->VFlip = (attr[1]>>13)&1;
oam_output->Size = (attr[1]>>14)&3;
oam_output->TileIndex = (attr[2]>>0)&0x3FF;
oam_output->Priority = (attr[2]>>10)&3;
oam_output->PaletteIndex = (attr[2]>>12)&0xF;
oam_output->attr3 = attr[3];
}
//gets the affine parameter associated with the specified oam index.
u16 SlurpOAMAffineParam(void* oam_buffer, int oam_index)
{
u16* u16_oam_buffer = (u16*)oam_buffer;
int u16_offset = oam_index<<2;
return LE_TO_LOCAL_16(u16_oam_buffer[u16_offset + 3]);
}
//this is fantastically inaccurate.
//we do the early return even though it reduces the resulting accuracy
//because we need the speed, and because it is inaccurate anyway
@ -830,8 +869,9 @@ static void mosaicSpriteLinePixel(GPU * gpu, int x, u16 l, u8 * dst, u8 * dst_al
int x_int;
int y = l;
_OAM_ * spriteInfo = (_OAM_ *)(gpu->oam + gpu->sprNum[x]);
bool enabled = spriteInfo->Mosaic;
_OAM_ spriteInfo;
SlurpOAM(&spriteInfo,gpu->oam,gpu->sprNum[x]);
bool enabled = spriteInfo.Mosaic!=0;
if(!enabled)
return;
@ -1289,8 +1329,6 @@ template<bool MOSAIC> void lineExtRot(GPU * gpu)
// SPRITE RENDERING -HELPER FUNCTIONS-
/*****************************************************************************/
#define nbShow 128
/* if i understand it correct, and it fixes some sprite problems in chameleon shot */
/* we have a 15 bit color, and should use the pal entry bits as alpha ?*/
/* http://nocash.emubase.de/gbatek.htm#dsvideoobjs */
@ -1481,28 +1519,14 @@ void GPU::_spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
int cost = 0;
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
_OAM_ * spriteInfo = (_OAM_ *)(gpu->oam);
u8 block = gpu->sprBoundary;
u8 i;
//what the hell? why is all this here? the #ifdefs in the bitfields definition should take care of this.
//this needs to be fixed anyway since i changed the sprite render order
//better yet, just dont do it this way at all. _OAM_ is so small, why not just copy it and then twiddle it?
//#ifdef WORDS_BIGENDIAN
// *(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15;
// *(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14;
//#endif
for(i = 0; i<nbShow; ++i, ++spriteInfo
//#ifdef WORDS_BIGENDIAN
// ,*(((u16*)(spriteInfo+1))+1) = (*(((u16*)(spriteInfo+1))+1) << 1) | *(((u16*)(spriteInfo+1))+1) >> 15
// ,*(((u16*)(spriteInfo+1))+2) = (*(((u16*)(spriteInfo+1))+2) << 2) | *(((u16*)(spriteInfo+1))+2) >> 14
// ,*(((u16*)spriteInfo)+1) = (*(((u16*)spriteInfo)+1) >> 1) | *(((u16*)spriteInfo)+1) << 15
// ,*(((u16*)spriteInfo)+2) = (*(((u16*)spriteInfo)+2) >> 2) | *(((u16*)spriteInfo)+2) << 14
//#endif
)
for(int i = 0; i<128; i++)
{
_OAM_ oam;
_OAM_* spriteInfo = &oam;
SlurpOAM(spriteInfo, gpu->oam, i);
//for each sprite:
if(cost>=2130)
{
@ -1573,17 +1597,11 @@ void GPU::_spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
blockparameter = (spriteInfo->RotScalIndex + (spriteInfo->HFlip<< 3) + (spriteInfo->VFlip << 4))*4;
// Get rotation/scale parameters
#ifdef WORDS_BIGENDIAN
dx = ((s16)(gpu->oam + blockparameter+0)->attr31 << 8) | ((s16)(gpu->oam + blockparameter+0)->attr30);
dmx = ((s16)(gpu->oam + blockparameter+1)->attr31 << 8) | ((s16)(gpu->oam + blockparameter+1)->attr30);
dy = ((s16)(gpu->oam + blockparameter+2)->attr31 << 8) | ((s16)(gpu->oam + blockparameter+2)->attr30);
dmy = ((s16)(gpu->oam + blockparameter+3)->attr31 << 8) | ((s16)(gpu->oam + blockparameter+3)->attr30);
#else
dx = (s16)(gpu->oam + blockparameter+0)->attr3;
dmx = (s16)(gpu->oam + blockparameter+1)->attr3;
dy = (s16)(gpu->oam + blockparameter+2)->attr3;
dmy = (s16)(gpu->oam + blockparameter+3)->attr3;
#endif
dx = SlurpOAMAffineParam(gpu->oam,blockparameter+0);
dmx = SlurpOAMAffineParam(gpu->oam,blockparameter+1);
dy = SlurpOAMAffineParam(gpu->oam,blockparameter+2);
dmy = SlurpOAMAffineParam(gpu->oam,blockparameter+3);
// Calculate fixed poitn 8.8 start offsets
realX = ((sprSize.x) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx + y * dmx;

View File

@ -2,7 +2,7 @@
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 Theo Berkau
Copyright (C) 2007 shash
Copyright (C) 2009-2010 DeSmuME team
Copyright (C) 2009-2012 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -510,77 +510,30 @@ enum GPU_OBJ_MODE
GPU_OBJ_MODE_Bitmap = 3
};
/*
this structure is for Sprite description,
it holds flags & transformations for 1 sprite
(max 128 OBJs / screen)
ref: http://www.bottledlight.com/ds/index.php/Video/Sprites
*/
struct _OAM_
{
#ifdef WORDS_BIGENDIAN
// attr0
/* 0*/ unsigned Y:8;
/*14*/ unsigned Shape:2; // (00: Square, 01: Wide, 10: Tall, 11: Illegal)
/*13*/ unsigned Depth:1; // (0: 16, 1: 256)
/*12*/ unsigned Mosaic:1; // (1: Enabled)
/*10*/ unsigned Mode:2; // (00: Normal, 01: Transparent, 10: Object window, 11: Bitmap)
/* 8*/ unsigned RotScale:2; // (00: Normal, 01: Rot/scale, 10: Disabled, 11: Double-size rot/scale)
// attr1
/* 0*/ signed X:9;
/*14*/ unsigned Size:2;
/*13*/ unsigned VFlip:1;
/*12*/ unsigned HFlip:1;
/* 9*/ unsigned RotScalIndex:3; // Rot/scale matrix index
// attr2
/* 0*/ unsigned TileIndex:10;
/*12*/ unsigned PaletteIndex:4;
/*10*/ unsigned Priority:2;
// attr3
unsigned attr3:16;
#else
// attr0
/* 0*/ unsigned Y:8;
/* 8*/ unsigned RotScale:2; // (00: Normal, 01: Rot/scale, 10: Disabled, 11: Double-size rot/scale)
/*10*/ unsigned Mode:2; // (00: Normal, 01: Transparent, 10: Object window, 11: Bitmap)
/*12*/ unsigned Mosaic:1; // (1: Enabled)
/*13*/ unsigned Depth:1; // (0: 16, 1: 256)
/*14*/ unsigned Shape:2; // (00: Square, 01: Wide, 10: Tall, 11: Illegal)
// attr1
/* 0*/ signed X:9;
/* 9*/ unsigned RotScalIndex:3; // Rot/scale matrix index
/*12*/ unsigned HFlip:1;
/*13*/ unsigned VFlip:1;
/*14*/ unsigned Size:2;
// attr2
/* 0*/ unsigned TileIndex:10;
/*10*/ unsigned Priority:2;
/*12*/ unsigned PaletteIndex:4;
// attr3
unsigned attr3:16;
#endif
//attr0
u8 Y;
u8 RotScale;
u8 Mode;
u8 Mosaic;
u8 Depth;
u8 Shape;
//att1
s16 X;
u8 RotScalIndex;
u8 HFlip, VFlip;
u8 Size;
//attr2
u16 TileIndex;
u8 Priority;
u8 PaletteIndex;
//attr3
u16 attr3;
};
typedef struct
{
#ifdef WORDS_BIGENDIAN
u8 attr00;
u8 attr01;
u8 attr10;
u8 attr11;
u8 attr20;
u8 attr21;
u8 attr30;
u8 attr31;
#else
u16 attr0;
u16 attr1;
u16 attr2;
u16 attr3;
#endif
} OAM;
void SlurpOAM(_OAM_* oam_output, void* oam_buffer, int oam_index);
u16 SlurpOAMAffineParam(void* oam_buffer, int oam_index);
typedef struct
{
@ -589,15 +542,9 @@ typedef struct
} size;
/*
this structure holds information
for rendering.
*/
#define NB_PRIORITIES 4
#define NB_BG 4
//this structure holds information for rendering.
typedef struct
{
u8 PixelsX[256];
@ -690,7 +637,7 @@ struct GPU
BOOL bg0HasHighestPrio;
OAM * oam;
void * oam;
u32 sprMem;
u8 sprBoundary;
u8 sprBMPBoundary;

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2011 DeSmuME team
Copyright (C) 2006-2012 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@ typedef struct
bool autoup;
s16 num;
OAM *oam;
void*oam;
GPU *gpu;
u8 scale;
bool border;
@ -109,7 +109,18 @@ LRESULT OamView_OnPaint(HWND hwnd, oamview_struct *win, WPARAM wParam, LPARAM lP
{
HDC hdc;
PAINTSTRUCT ps;
OAM * oam = &win->oam[win->num];
//_OAM_ _oam;
//_OAM_* oam = &_oam;
//SlurpOAM(oam,win->oam,win->num);
struct MyOam
{
u16 attr0,attr1,attr2,attr3;
} myOam;
MyOam* oam = &myOam;
memcpy(oam,(u8*)win->oam + 8*win->num,8);
char text[80];
u16 bitmap[256*192];
u8 bitmap_alpha[256*192];
@ -265,7 +276,7 @@ BOOL CALLBACK ViewOAMProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
{
OAMView = new oamview_struct;
memset(OAMView, 0, sizeof(oamview_struct));
OAMView->oam = (OAM *)(MMU.ARM9_OAM);
OAMView->oam = MMU.ARM9_OAM;
OAMView->gpu = MainScreen.gpu;
OAMView->scale = 2;
OAMView->border = true;
@ -375,12 +386,12 @@ BOOL CALLBACK ViewOAMProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
switch(sel)
{
case 0 :
OAMView->oam = (OAM *)MMU.ARM9_OAM;
OAMView->oam = MMU.ARM9_OAM;
OAMView->num = 0;
OAMView->gpu = MainScreen.gpu;
break;
case 1 :
OAMView->oam = (OAM *)(MMU.ARM9_OAM+0x400);
OAMView->oam = (MMU.ARM9_OAM+0x400);
OAMView->num = 0;
OAMView->gpu = SubScreen.gpu;
break;