diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index fe9666f0e..67cc616c7 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -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 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> 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; diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 11638dfe3..5f6ff725e 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -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; diff --git a/desmume/src/windows/oamView.cpp b/desmume/src/windows/oamView.cpp index b10c20589..7661e9006 100644 --- a/desmume/src/windows/oamView.cpp +++ b/desmume/src/windows/oamView.cpp @@ -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;