clean up texture format conversion code, but rework it at same time to be more powerful and safer from making mistakes in the caching, although this is hard to test. also made it safe from textures and palettes which straddle texture and palette slots. i may have broken something, but now the code is much closer to where it needs to be.
This commit is contained in:
parent
08f0a76fe2
commit
7ea5ecfb17
|
@ -25,6 +25,7 @@
|
||||||
//(re: new super mario brothers renders the stormclouds at the beginning)
|
//(re: new super mario brothers renders the stormclouds at the beginning)
|
||||||
|
|
||||||
#include "OGLRender.h"
|
#include "OGLRender.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
//#define DEBUG_DUMP_TEXTURE
|
//#define DEBUG_DUMP_TEXTURE
|
||||||
|
|
||||||
|
@ -69,11 +70,146 @@ static void ENDGL() {
|
||||||
|
|
||||||
#include "shaders.h"
|
#include "shaders.h"
|
||||||
|
|
||||||
|
//This class represents a number of regions of memory which should be viewed as contiguous
|
||||||
|
class MemSpan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const int MAXSIZE = 8;
|
||||||
|
|
||||||
|
MemSpan()
|
||||||
|
: numItems(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int numItems;
|
||||||
|
|
||||||
|
struct Item {
|
||||||
|
u32 start;
|
||||||
|
u32 len;
|
||||||
|
u8* ptr;
|
||||||
|
u32 ofs; //offset within the memspan
|
||||||
|
} items[MAXSIZE];
|
||||||
|
|
||||||
|
int size;
|
||||||
|
|
||||||
|
//this MemSpan shall be considered the first argument to a standard memcmp
|
||||||
|
//the length shall be as specified in this MemSpan, unless you specify otherwise
|
||||||
|
int memcmp(void* buf2, int size=-1)
|
||||||
|
{
|
||||||
|
if(size==-1) size = this->size;
|
||||||
|
for(int i=0;i<numItems;i++)
|
||||||
|
{
|
||||||
|
Item &item = items[i];
|
||||||
|
int todo = std::min((int)item.len,size);
|
||||||
|
size -= todo;
|
||||||
|
int temp = ::memcmp(item.ptr,((u8*)buf2)+item.ofs,todo);
|
||||||
|
if(temp) return temp;
|
||||||
|
if(size == 0) break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//dumps the memspan to the specified buffer
|
||||||
|
//you may set size to limit the size to be copied
|
||||||
|
int dump(void* buf, int size=-1)
|
||||||
|
{
|
||||||
|
if(size==-1) size = this->size;
|
||||||
|
u8* bufptr = (u8*)buf;
|
||||||
|
int done = 0;
|
||||||
|
for(int i=0;i<numItems;i++)
|
||||||
|
{
|
||||||
|
Item item = items[i];
|
||||||
|
int todo = std::min((int)item.len,size);
|
||||||
|
size -= todo;
|
||||||
|
done += todo;
|
||||||
|
memcpy(bufptr,item.ptr,item.len);
|
||||||
|
bufptr += item.len;
|
||||||
|
if(size==0) return done;
|
||||||
|
}
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//creates a MemSpan in texture memory
|
||||||
|
MemSpan MemSpan_TexMem(u32 ofs, u32 len)
|
||||||
|
{
|
||||||
|
MemSpan ret;
|
||||||
|
ret.size = len;
|
||||||
|
u32 currofs = 0;
|
||||||
|
while(len) {
|
||||||
|
MemSpan::Item &curr = ret.items[ret.numItems++];
|
||||||
|
curr.start = ofs&0x1FFFF;
|
||||||
|
u32 slot = (ofs>>17)&3; //slots will wrap around
|
||||||
|
curr.len = std::min(len,0x20000-curr.start);
|
||||||
|
curr.ofs = currofs;
|
||||||
|
len -= curr.len;
|
||||||
|
ofs += curr.len;
|
||||||
|
if(len != 0) {
|
||||||
|
int zzz=9;
|
||||||
|
//here is an actual test case of bank spanning
|
||||||
|
}
|
||||||
|
currofs += curr.len;
|
||||||
|
u8* ptr = ARM9Mem.textureSlotAddr[slot];
|
||||||
|
//this is just a guess. what happens if there is a gap in the mapping? lets put zeros
|
||||||
|
if(ptr == NULL) {
|
||||||
|
PROGINFO("Texture gap in memory mapping. Trying to accomodate.\n");
|
||||||
|
static u8* emptyTextureSlot = 0;
|
||||||
|
if(emptyTextureSlot == NULL) {
|
||||||
|
emptyTextureSlot = new u8[128*1024];
|
||||||
|
memset(emptyTextureSlot,0,128*1024);
|
||||||
|
}
|
||||||
|
ptr = emptyTextureSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr.ptr = ptr + curr.start;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//creates a MemSpan in texture palette memory
|
||||||
|
MemSpan MemSpan_TexPalette(u32 ofs, u32 len)
|
||||||
|
{
|
||||||
|
MemSpan ret;
|
||||||
|
ret.size = len;
|
||||||
|
u32 currofs = 0;
|
||||||
|
while(len) {
|
||||||
|
MemSpan::Item &curr = ret.items[ret.numItems++];
|
||||||
|
curr.start = ofs&0x3FFF;
|
||||||
|
u32 slot = (ofs>>14)&7; //this masks to 8 slots, but there are really only 6
|
||||||
|
if(slot>5) {
|
||||||
|
PROGINFO("Texture palette overruns texture memory. Wrapping at palette slot 0.\n");
|
||||||
|
slot -= 5;
|
||||||
|
}
|
||||||
|
curr.len = std::min(len,0x4000-curr.start);
|
||||||
|
curr.ofs = currofs;
|
||||||
|
len -= curr.len;
|
||||||
|
ofs += curr.len;
|
||||||
|
if(len != 0) {
|
||||||
|
int zzz=9;
|
||||||
|
//here is an actual test case of bank spanning
|
||||||
|
}
|
||||||
|
currofs += curr.len;
|
||||||
|
u8* ptr = ARM9Mem.texPalSlot[slot];
|
||||||
|
//this is just a guess. what happens if there is a gap in the mapping? lets put zeros
|
||||||
|
if(ptr == NULL) {
|
||||||
|
PROGINFO("Texture palette gap in memory mapping. Trying to accomodate.\n");
|
||||||
|
static u8* emptyTexturePalette = 0;
|
||||||
|
if(emptyTexturePalette == NULL) {
|
||||||
|
emptyTexturePalette = new u8[16*1024];
|
||||||
|
memset(emptyTexturePalette,0,16*1024);
|
||||||
|
}
|
||||||
|
ptr = emptyTexturePalette;
|
||||||
|
}
|
||||||
|
curr.ptr = ptr + curr.start;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef CTASSERT
|
#ifndef CTASSERT
|
||||||
#define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1]
|
#define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ALIGN(16) unsigned char GPU_screen3D [256*256*4];
|
static ALIGN(16) u8 GPU_screen3D [256*192*4];
|
||||||
//static ALIGN(16) unsigned char GPU_screenStencil[256*256];
|
//static ALIGN(16) unsigned char GPU_screenStencil[256*256];
|
||||||
|
|
||||||
static const unsigned short map3d_cull[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
static const unsigned short map3d_cull[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
|
||||||
|
@ -81,7 +217,7 @@ static const int texEnv[4] = { GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE }
|
||||||
static const int depthFunc[2] = { GL_LESS, GL_EQUAL };
|
static const int depthFunc[2] = { GL_LESS, GL_EQUAL };
|
||||||
static bool needRefreshFramebuffer = false;
|
static bool needRefreshFramebuffer = false;
|
||||||
static unsigned char texMAP[1024*2048*4];
|
static unsigned char texMAP[1024*2048*4];
|
||||||
static unsigned int textureMode=0;
|
static unsigned int textureMode=TEXMODE_NONE;
|
||||||
|
|
||||||
float clearAlpha;
|
float clearAlpha;
|
||||||
|
|
||||||
|
@ -225,15 +361,15 @@ struct ALIGN(8) TextureCache
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
GLenum id;
|
GLenum id;
|
||||||
unsigned int frm;
|
u32 frm;
|
||||||
unsigned int mode;
|
u32 mode;
|
||||||
unsigned int pal;
|
u32 pal;
|
||||||
unsigned int sizeX;
|
u32 sizeX;
|
||||||
unsigned int sizeY;
|
u32 sizeY;
|
||||||
int coord;
|
|
||||||
float invSizeX;
|
float invSizeX;
|
||||||
float invSizeY;
|
float invSizeY;
|
||||||
unsigned char texture[128*1024]; // 128Kb texture slot
|
int textureSize, indexSize;
|
||||||
|
u8 texture[128*1024]; // 128Kb texture slot
|
||||||
u8 palette[256*2];
|
u8 palette[256*2];
|
||||||
u16 palSize;
|
u16 palSize;
|
||||||
|
|
||||||
|
@ -508,16 +644,6 @@ static void OGLClose()
|
||||||
ENDGL();
|
ENDGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CHECKSLOT txt_slot_current_size--;\
|
|
||||||
if (txt_slot_current_size<=0)\
|
|
||||||
{\
|
|
||||||
txt_slot_current++;\
|
|
||||||
if (txt_slot_current>3) txt_slot_current = 0;\
|
|
||||||
adr=(unsigned char *)ARM9Mem.textureSlotAddr[txt_slot_current];\
|
|
||||||
txt_slot_size=txt_slot_current_size=0x020000;\
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo - make all color conversions go through a properly spread table!!
|
//todo - make all color conversions go through a properly spread table!!
|
||||||
|
|
||||||
#if defined (DEBUG_DUMP_TEXTURE) && defined (WIN32)
|
#if defined (DEBUG_DUMP_TEXTURE) && defined (WIN32)
|
||||||
|
@ -544,28 +670,24 @@ static int lastTexture = -1;
|
||||||
static bool hasTexture = false;
|
static bool hasTexture = false;
|
||||||
static void setTexture(unsigned int format, unsigned int texpal)
|
static void setTexture(unsigned int format, unsigned int texpal)
|
||||||
{
|
{
|
||||||
//BIG TODO -
|
//for each texformat, number of palette entries
|
||||||
//none of this is capable of spanning bank boundaries. this is an obscure bug waiting to happen.
|
const int palSizes[] = {0, 32, 4, 16, 256, 0, 8, 0};
|
||||||
//each texel, palette, and 4x4 lookup need to be memory mapped.
|
|
||||||
//since we're caching textures, this cost is not too severe.
|
//for each texformat, multiplier from numtexels to numbytes (fixed point 30.2)
|
||||||
|
const int texSizes[] = {0, 4, 1, 2, 4, 1, 4, 8};
|
||||||
|
|
||||||
|
//used to hold a copy of the palette specified for this texture
|
||||||
|
u16 pal[256];
|
||||||
|
|
||||||
const int palSize[]={0, 8, 32, 512, 64, 0, 16, 0};
|
|
||||||
unsigned int x=0, y=0, i;
|
|
||||||
unsigned int palZeroTransparent;
|
|
||||||
|
|
||||||
u16 *pal = NULL;
|
|
||||||
unsigned char *dst = texMAP;
|
|
||||||
u32 *dwdst = (u32*)texMAP;
|
u32 *dwdst = (u32*)texMAP;
|
||||||
|
|
||||||
|
textureMode = (unsigned short)((format>>26)&0x07);
|
||||||
unsigned int sizeX=(8 << ((format>>20)&0x07));
|
unsigned int sizeX=(8 << ((format>>20)&0x07));
|
||||||
unsigned int sizeY=(8 << ((format>>23)&0x07));
|
unsigned int sizeY=(8 << ((format>>23)&0x07));
|
||||||
unsigned int imageSize = sizeX*sizeY;
|
unsigned int imageSize = sizeX*sizeY;
|
||||||
|
|
||||||
u64 txt_slot_current_size;
|
|
||||||
u64 txt_slot_size;
|
|
||||||
u64 txt_slot_current;
|
|
||||||
u8 *adr;
|
u8 *adr;
|
||||||
|
|
||||||
textureMode = (unsigned short)((format>>26)&0x07);
|
|
||||||
|
|
||||||
if (format==0)
|
if (format==0)
|
||||||
{
|
{
|
||||||
|
@ -586,62 +708,101 @@ static void setTexture(unsigned int format, unsigned int texpal)
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
txt_slot_current=(format>>14)&0x03;
|
|
||||||
adr=(unsigned char *)(ARM9Mem.textureSlotAddr[txt_slot_current]+((format&0x3FFF)<<3));
|
|
||||||
|
|
||||||
u32 paletteAddress;
|
u32 paletteAddress;
|
||||||
|
|
||||||
switch (textureMode)
|
switch (textureMode)
|
||||||
{
|
{
|
||||||
case 2: //i2
|
case TEXMODE_I2:
|
||||||
paletteAddress = texturePalette<<3;
|
paletteAddress = texturePalette<<3;
|
||||||
break;
|
break;
|
||||||
case 1: //a3i5
|
case TEXMODE_A3I5: //a3i5
|
||||||
case 3: //i4
|
case TEXMODE_I4: //i4
|
||||||
case 4: //i8
|
case TEXMODE_I8: //i8
|
||||||
case 6: //a5i3
|
case TEXMODE_A5I3: //a5i3
|
||||||
case 7: //16bpp
|
case TEXMODE_16BPP: //16bpp
|
||||||
case 5: //4x4
|
case TEXMODE_4X4: //4x4
|
||||||
default:
|
default:
|
||||||
paletteAddress = texturePalette<<4;
|
paletteAddress = texturePalette<<4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 paletteSlot = paletteAddress>>14;
|
//analyze the texture memory mapping and the specifications of this texture
|
||||||
u32 paletteOffset = paletteAddress&0x3FFF;
|
int palSize = palSizes[textureMode];
|
||||||
|
int texSize = (imageSize*texSizes[textureMode])>>2;
|
||||||
|
MemSpan ms = MemSpan_TexMem((format&0xFFFF)<<3,texSize);
|
||||||
|
MemSpan mspal = MemSpan_TexPalette(paletteAddress,palSize*2);
|
||||||
|
|
||||||
pal = (unsigned short *)(ARM9Mem.texPalSlot[paletteSlot] + (paletteOffset));
|
//determine the location for 4x4 index data
|
||||||
|
u32 indexBase;
|
||||||
|
if((format & 0xc000) == 0x8000) indexBase = 0x30000;
|
||||||
|
else indexBase = 0x20000;
|
||||||
|
|
||||||
|
u32 indexOffset = (format&0x3FFF)<<2;
|
||||||
|
|
||||||
|
int indexSize = 0;
|
||||||
|
MemSpan msIndex;
|
||||||
|
if(textureMode == TEXMODE_4X4)
|
||||||
|
{
|
||||||
|
indexSize = imageSize>>3;
|
||||||
|
MemSpan_TexMem(indexOffset+indexBase,indexSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//dump the palette to a temp buffer, so that we don't have to worry about memory mapping.
|
||||||
|
//this isnt such a problem with texture memory, because we read sequentially from it.
|
||||||
|
//however, we read randomly from palette memory, so the mapping is more costly.
|
||||||
|
mspal.dump(pal);
|
||||||
|
|
||||||
|
|
||||||
|
int i=texcache_start;
|
||||||
|
|
||||||
i=texcache_start;
|
|
||||||
|
|
||||||
//if(false)
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
//conditions where we give up and regenerate the texture:
|
||||||
if (texcache_stop==i) break;
|
if (texcache_stop==i) break;
|
||||||
if (texcache[i].frm==0) break;
|
if (texcache[i].frm==0) break;
|
||||||
if ( (texcache[i].frm == format) && (texcache[i].pal == texpal) )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ((texcache[i].palSize == 0) ||
|
//conditions where we reject matches:
|
||||||
!memcmp(texcache[i].palette, pal, texcache[i].palSize) )
|
//when the teximage or texpal params dont match
|
||||||
{
|
//(this is our key for identifying palettes in the cache)
|
||||||
//TODO - this doesnt correctly span bank boundaries. in fact, it seems quite dangerous.
|
if(texcache[i].frm != format) goto REJECT;
|
||||||
if (!texcache[i].suspectedInvalid || !memcmp(adr, texcache[i].texture, std::min((size_t)imageSize,sizeof(texcache[i].texture))) )
|
if(texcache[i].pal != texpal) goto REJECT;
|
||||||
{
|
|
||||||
texcache[i].suspectedInvalid = false;
|
//the texture matches params, but isnt suspected invalid. accept it.
|
||||||
texcache_count=i;
|
if(!texcache[i].suspectedInvalid) goto ACCEPT;
|
||||||
if(lastTexture == -1 || (int)i != lastTexture)
|
|
||||||
{
|
//if we couldnt cache this entire texture due to it being too large, then reject it
|
||||||
lastTexture = i;
|
if(texSize+indexSize > sizeof(texcache[i].texture)) goto REJECT;
|
||||||
glBindTexture(GL_TEXTURE_2D,texcache[i].id);
|
|
||||||
glMatrixMode (GL_TEXTURE);
|
//when the palettes dont match:
|
||||||
glLoadIdentity ();
|
//note that we are considering 4x4 textures to have a palette size of 0.
|
||||||
glScaled (texcache[i].invSizeX, texcache[i].invSizeY, 1.0f);
|
//they really have a potentially HUGE palette, too big for us to handle like a normal palette,
|
||||||
}
|
//so they go through a different system
|
||||||
return;
|
if(mspal.size != 0 && memcmp(texcache[i].palette,pal,mspal.size)) goto REJECT;
|
||||||
}
|
|
||||||
}
|
//when the texture data doesn't match
|
||||||
|
if(ms.memcmp(texcache[i].texture,sizeof(texcache[i].texture))) goto REJECT;
|
||||||
|
|
||||||
|
//if the texture is 4x4 then the index data must match
|
||||||
|
if(textureMode == TEXMODE_4X4) {
|
||||||
|
if(msIndex.memcmp(texcache[i].texture + texcache[i].textureSize,texcache[i].indexSize)) goto REJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ACCEPT:
|
||||||
|
texcache[i].suspectedInvalid = false;
|
||||||
|
texcache_count=i;
|
||||||
|
if(lastTexture == -1 || (int)i != lastTexture)
|
||||||
|
{
|
||||||
|
lastTexture = i;
|
||||||
|
glBindTexture(GL_TEXTURE_2D,texcache[i].id);
|
||||||
|
glMatrixMode (GL_TEXTURE);
|
||||||
|
glLoadIdentity ();
|
||||||
|
glScaled (texcache[i].invSizeX, texcache[i].invSizeY, 1.0f);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
REJECT:
|
||||||
i++;
|
i++;
|
||||||
if (i>MAX_TEXTURE)
|
if (i>MAX_TEXTURE)
|
||||||
{
|
{
|
||||||
|
@ -661,23 +822,29 @@ static void setTexture(unsigned int format, unsigned int texpal)
|
||||||
glBindTexture(GL_TEXTURE_2D, texcache[i].id);
|
glBindTexture(GL_TEXTURE_2D, texcache[i].id);
|
||||||
|
|
||||||
texcache[i].suspectedInvalid = false;
|
texcache[i].suspectedInvalid = false;
|
||||||
|
texcache[i].frm=format;
|
||||||
texcache[i].mode=textureMode;
|
texcache[i].mode=textureMode;
|
||||||
texcache[i].pal=texpal;
|
texcache[i].pal=texpal;
|
||||||
texcache[i].sizeX=sizeX;
|
texcache[i].sizeX=sizeX;
|
||||||
texcache[i].sizeY=sizeY;
|
texcache[i].sizeY=sizeY;
|
||||||
texcache[i].coord=(format>>30);
|
|
||||||
texcache[i].invSizeX=1.0f/((float)(sizeX));
|
texcache[i].invSizeX=1.0f/((float)(sizeX));
|
||||||
texcache[i].invSizeY=1.0f/((float)(sizeY));
|
texcache[i].invSizeY=1.0f/((float)(sizeY));
|
||||||
memcpy(texcache[i].texture,adr,std::min((size_t)imageSize,sizeof(texcache[i].texture)));
|
texcache[i].textureSize = ms.dump(texcache[i].texture,sizeof(texcache[i].texture));
|
||||||
texcache[i].palSize = palSize[textureMode];
|
|
||||||
|
//dump palette data for cache keying
|
||||||
|
texcache[i].palSize = mspal.size;
|
||||||
if ( texcache[i].palSize != 0 )
|
if ( texcache[i].palSize != 0 )
|
||||||
{
|
{
|
||||||
//TODO - the 4x4 lookup table should probably be checked also.
|
memcpy(texcache[i].palette, pal, texcache[i].palSize*2);
|
||||||
//but maybe we could concatenate that to the texture
|
}
|
||||||
memcpy(texcache[i].palette, pal, texcache[i].palSize);
|
//dump 4x4 index data for cache keying
|
||||||
|
texcache[i].indexSize = 0;
|
||||||
|
if(textureMode == TEXMODE_4X4)
|
||||||
|
{
|
||||||
|
texcache[i].indexSize = std::min(msIndex.size,(int)sizeof(texcache[i].texture) - texcache[i].textureSize);
|
||||||
|
msIndex.dump(texcache[i].texture,texcache[i].indexSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
texcache[i].frm=format;
|
|
||||||
|
|
||||||
glMatrixMode (GL_TEXTURE);
|
glMatrixMode (GL_TEXTURE);
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
|
@ -685,145 +852,162 @@ static void setTexture(unsigned int format, unsigned int texpal)
|
||||||
|
|
||||||
|
|
||||||
//INFO("Texture %03i - format=%08X; pal=%04X (mode %X, width %04i, height %04i)\n",i, texcache[i].frm, texcache[i].pal, texcache[i].mode, sizeX, sizeY);
|
//INFO("Texture %03i - format=%08X; pal=%04X (mode %X, width %04i, height %04i)\n",i, texcache[i].frm, texcache[i].pal, texcache[i].mode, sizeX, sizeY);
|
||||||
|
|
||||||
//============================================================================ Texture render
|
//============================================================================ Texture conversion
|
||||||
palZeroTransparent = (1-((format>>29)&1))*255; // shash: CONVERT THIS TO A TABLE :)
|
u32 palZeroTransparent = (1-((format>>29)&1))*255; // shash: CONVERT THIS TO A TABLE :)
|
||||||
txt_slot_size=(txt_slot_current_size=0x020000-((format & 0x3FFF)<<3));
|
|
||||||
|
|
||||||
switch (texcache[i].mode)
|
switch (texcache[i].mode)
|
||||||
{
|
{
|
||||||
case 1: //a3i5
|
case TEXMODE_A3I5:
|
||||||
{
|
{
|
||||||
for(x = 0; x < imageSize; x++, dst += 4)
|
for(int i=0;i<ms.numItems;i++) {
|
||||||
{
|
adr = ms.items[i].ptr;
|
||||||
u16 c = pal[*adr&31];
|
for(int x = 0; x < ms.items[i].len; x++)
|
||||||
u8 alpha = *adr>>5;
|
|
||||||
*dwdst++ = RGB15TO32(c,material_3bit_to_8bit[alpha]);
|
|
||||||
adr++;
|
|
||||||
CHECKSLOT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: //i2
|
|
||||||
{
|
|
||||||
for(x = 0; x < imageSize>>2; ++x)
|
|
||||||
{
|
|
||||||
unsigned short c = pal[(*adr)&0x3];
|
|
||||||
dst[0] = ((c & 0x1F)<<3);
|
|
||||||
dst[1] = ((c & 0x3E0)>>2);
|
|
||||||
dst[2] = ((c & 0x7C00)>>7);
|
|
||||||
dst[3] = ((*adr&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255;
|
|
||||||
dst += 4;
|
|
||||||
|
|
||||||
c = pal[((*adr)>>2)&0x3];
|
|
||||||
dst[0] = ((c & 0x1F)<<3);
|
|
||||||
dst[1] = ((c & 0x3E0)>>2);
|
|
||||||
dst[2] = ((c & 0x7C00)>>7);
|
|
||||||
dst[3] = (((*adr>>2)&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255;
|
|
||||||
dst += 4;
|
|
||||||
|
|
||||||
c = pal[((*adr)>>4)&0x3];
|
|
||||||
dst[0] = ((c & 0x1F)<<3);
|
|
||||||
dst[1] = ((c & 0x3E0)>>2);
|
|
||||||
dst[2] = ((c & 0x7C00)>>7);
|
|
||||||
dst[3] = (((*adr>>4)&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255;
|
|
||||||
dst += 4;
|
|
||||||
|
|
||||||
c = pal[(*adr)>>6];
|
|
||||||
dst[0] = ((c & 0x1F)<<3);
|
|
||||||
dst[1] = ((c & 0x3E0)>>2);
|
|
||||||
dst[2] = ((c & 0x7C00)>>7);
|
|
||||||
dst[3] = (((*adr>>6)&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255;
|
|
||||||
dst += 4;
|
|
||||||
|
|
||||||
adr++;
|
|
||||||
CHECKSLOT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: //i4
|
|
||||||
{
|
|
||||||
for(x = 0; x < (imageSize>>1); x++)
|
|
||||||
{
|
{
|
||||||
unsigned short c = pal[*adr&0xF];
|
u16 c = pal[*adr&31];
|
||||||
dst[0] = ((c & 0x1F)<<3);
|
u8 alpha = *adr>>5;
|
||||||
dst[1] = ((c & 0x3E0)>>2);
|
*dwdst++ = RGB15TO32(c,material_3bit_to_8bit[alpha]);
|
||||||
dst[2] = ((c & 0x7C00)>>7);
|
adr++;
|
||||||
dst[3] = (((*adr)&0xF) == 0) ? palZeroTransparent : 255;//(c>>15)*255;
|
}
|
||||||
dst += 4;
|
}
|
||||||
|
|
||||||
c = pal[((*adr)>>4)];
|
break;
|
||||||
dst[0] = ((c & 0x1F)<<3);
|
}
|
||||||
dst[1] = ((c & 0x3E0)>>2);
|
case TEXMODE_I2:
|
||||||
dst[2] = ((c & 0x7C00)>>7);
|
{
|
||||||
dst[3] = (((*adr>>4)&0xF) == 0) ? palZeroTransparent : 255;//(c>>15)*255;
|
for(int i=0;i<ms.numItems;i++) {
|
||||||
dst += 4;
|
adr = ms.items[i].ptr;
|
||||||
|
for(int x = 0; x < ms.items[i].len; x++)
|
||||||
|
{
|
||||||
|
u8 bits;
|
||||||
|
u16 c;
|
||||||
|
|
||||||
|
bits = (*adr)&0x3;
|
||||||
|
c = pal[bits];
|
||||||
|
*dwdst++ = RGB15TO32(c,(bits == 0) ? palZeroTransparent : 255);
|
||||||
|
|
||||||
|
bits = ((*adr)>>2)&0x3;
|
||||||
|
c = pal[bits];
|
||||||
|
*dwdst++ = RGB15TO32(c,(bits == 0) ? palZeroTransparent : 255);
|
||||||
|
|
||||||
|
bits = ((*adr)>>4)&0x3;
|
||||||
|
c = pal[bits];
|
||||||
|
*dwdst++ = RGB15TO32(c,(bits == 0) ? palZeroTransparent : 255);
|
||||||
|
|
||||||
|
bits = ((*adr)>>6)&0x3;
|
||||||
|
c = pal[bits];
|
||||||
|
*dwdst++ = RGB15TO32(c,(bits == 0) ? palZeroTransparent : 255);
|
||||||
|
|
||||||
adr++;
|
adr++;
|
||||||
|
|
||||||
CHECKSLOT;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case 4: //i8
|
break;
|
||||||
{
|
}
|
||||||
for(x = 0; x < imageSize; ++x)
|
case TEXMODE_I4:
|
||||||
|
{
|
||||||
|
for(int i=0;i<ms.numItems;i++) {
|
||||||
|
adr = ms.items[i].ptr;
|
||||||
|
for(int x = 0; x < ms.items[i].len; x++)
|
||||||
|
{
|
||||||
|
u8 bits;
|
||||||
|
u16 c;
|
||||||
|
|
||||||
|
bits = (*adr)&0xF;
|
||||||
|
c = pal[bits];
|
||||||
|
*dwdst++ = RGB15TO32(c,(bits == 0) ? palZeroTransparent : 255);
|
||||||
|
|
||||||
|
bits = ((*adr)>>4);
|
||||||
|
c = pal[bits];
|
||||||
|
*dwdst++ = RGB15TO32(c,(bits == 0) ? palZeroTransparent : 255);
|
||||||
|
|
||||||
|
adr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TEXMODE_I8:
|
||||||
|
{
|
||||||
|
for(int i=0;i<ms.numItems;i++) {
|
||||||
|
adr = ms.items[i].ptr;
|
||||||
|
for(int x = 0; x < ms.items[i].len; ++x)
|
||||||
{
|
{
|
||||||
u16 c = pal[*adr];
|
u16 c = pal[*adr];
|
||||||
*dwdst++ = RGB15TO32(c,(*adr == 0) ? palZeroTransparent : 255);
|
*dwdst++ = RGB15TO32(c,(*adr == 0) ? palZeroTransparent : 255);
|
||||||
adr++;
|
adr++;
|
||||||
CHECKSLOT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 5: //4x4
|
break;
|
||||||
|
case TEXMODE_4X4:
|
||||||
{
|
{
|
||||||
unsigned short * slot1;
|
if(ms.numItems != 1) PROGINFO("Your 4x4 texture has overrun its texture slot.\n");
|
||||||
unsigned int * map = (unsigned int *)adr;
|
//this check isnt necessary since the addressing is tied to the texture data which will also run out:
|
||||||
unsigned int d = 0;
|
//if(msIndex.numItems != 1) PROGINFO("Your 4x4 texture index has overrun its slot.\n");
|
||||||
|
|
||||||
|
#define PAL4X4(offset) ( *(u16*)( ARM9Mem.texPalSlot[((paletteAddress + (offset)*2)>>14)] + ((paletteAddress + (offset)*2)&0x3FFF) ) )
|
||||||
|
|
||||||
|
u16* slot1;
|
||||||
|
u32* map = (u32*)ms.items[0].ptr;
|
||||||
|
u32 limit = ms.items[0].len<<2;
|
||||||
|
u32 d = 0;
|
||||||
if ( (texcache[i].frm & 0xc000) == 0x8000)
|
if ( (texcache[i].frm & 0xc000) == 0x8000)
|
||||||
// texel are in slot 2
|
// texel are in slot 2
|
||||||
slot1=(unsigned short*)&ARM9Mem.textureSlotAddr[1][((texcache[i].frm&0x3FFF)<<2)+0x010000];
|
slot1=(u16*)&ARM9Mem.textureSlotAddr[1][((texcache[i].frm&0x3FFF)<<2)+0x010000];
|
||||||
else
|
else
|
||||||
slot1=(unsigned short*)&ARM9Mem.textureSlotAddr[1][(texcache[i].frm&0x3FFF)<<2];
|
slot1=(u16*)&ARM9Mem.textureSlotAddr[1][(texcache[i].frm&0x3FFF)<<2];
|
||||||
|
|
||||||
bool dead = false;
|
|
||||||
u16 yTmpSize = (texcache[i].sizeY>>2);
|
u16 yTmpSize = (texcache[i].sizeY>>2);
|
||||||
u16 xTmpSize = (texcache[i].sizeX>>2);
|
u16 xTmpSize = (texcache[i].sizeX>>2);
|
||||||
|
|
||||||
for (y = 0; y < yTmpSize; y ++)
|
//this is flagged whenever a 4x4 overruns its slot.
|
||||||
|
//i am guessing we just generate black in that case
|
||||||
|
bool dead = false;
|
||||||
|
|
||||||
|
for (int y = 0; y < yTmpSize; y ++)
|
||||||
{
|
{
|
||||||
u32 tmpPos[4]={(y<<2)*texcache[i].sizeX,((y<<2)+1)*texcache[i].sizeX,
|
u32 tmpPos[4]={(y<<2)*texcache[i].sizeX,((y<<2)+1)*texcache[i].sizeX,
|
||||||
((y<<2)+2)*texcache[i].sizeX,((y<<2)+3)*texcache[i].sizeX};
|
((y<<2)+2)*texcache[i].sizeX,((y<<2)+3)*texcache[i].sizeX};
|
||||||
for (x = 0; x < xTmpSize; x ++, d++)
|
for (int x = 0; x < xTmpSize; x ++, d++)
|
||||||
{
|
{
|
||||||
u32 currBlock = map[d], sy;
|
if(d >= limit)
|
||||||
|
dead = true;
|
||||||
|
|
||||||
|
if(dead) {
|
||||||
|
for (int sy = 0; sy < 4; sy++)
|
||||||
|
{
|
||||||
|
u32 currentPos = (x<<2) + tmpPos[sy];
|
||||||
|
dwdst[currentPos] = dwdst[currentPos+1] = dwdst[currentPos+2] = dwdst[currentPos+3] = 0;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 currBlock = map[d];
|
||||||
u16 pal1 = slot1[d];
|
u16 pal1 = slot1[d];
|
||||||
u16 pal1offset = (pal1 & 0x3FFF)<<1;
|
u16 pal1offset = (pal1 & 0x3FFF)<<1;
|
||||||
u8 mode = pal1>>14;
|
u8 mode = pal1>>14;
|
||||||
u32 tmp_col[4];
|
u32 tmp_col[4];
|
||||||
|
|
||||||
tmp_col[0]=RGB16TO32(pal[pal1offset],255);
|
tmp_col[0]=RGB15TO32(PAL4X4(pal1offset),255);
|
||||||
tmp_col[1]=RGB16TO32(pal[pal1offset+1],255);
|
tmp_col[1]=RGB15TO32(PAL4X4(pal1offset+1),255);
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
tmp_col[2]=RGB16TO32(pal[pal1offset+2],255);
|
tmp_col[2]=RGB15TO32(PAL4X4(pal1offset+2),255);
|
||||||
tmp_col[3]=RGB16TO32(0x7FFF,0);
|
tmp_col[3]=RGB15TO32(0x7FFF,0);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
tmp_col[2]=(((tmp_col[0]&0xFF)+(tmp_col[1]&0xff))>>1)|
|
tmp_col[2]=(((tmp_col[0]&0xFF)+(tmp_col[1]&0xff))>>1)|
|
||||||
(((tmp_col[0]&(0xFF<<8))+(tmp_col[1]&(0xFF<<8)))>>1)|
|
(((tmp_col[0]&(0xFF<<8))+(tmp_col[1]&(0xFF<<8)))>>1)|
|
||||||
(((tmp_col[0]&(0xFF<<16))+(tmp_col[1]&(0xFF<<16)))>>1)|
|
(((tmp_col[0]&(0xFF<<16))+(tmp_col[1]&(0xFF<<16)))>>1)|
|
||||||
(0xff<<24);
|
(0xff<<24);
|
||||||
tmp_col[3]=RGB16TO32(0x7FFF,0);
|
tmp_col[3]=RGB15TO32(0x7FFF,0);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
tmp_col[2]=RGB16TO32(pal[pal1offset+2],255);
|
tmp_col[2]=RGB15TO32(PAL4X4(pal1offset+2),255);
|
||||||
tmp_col[3]=RGB16TO32(pal[pal1offset+3],255);
|
tmp_col[3]=RGB15TO32(PAL4X4(pal1offset+3),255);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
u32 red1, red2;
|
u32 red1, red2;
|
||||||
u32 green1, green2;
|
u32 green1, green2;
|
||||||
|
@ -838,77 +1022,61 @@ static void setTexture(unsigned int format, unsigned int texpal)
|
||||||
blue2=(tmp_col[1]>>16)&0xff;
|
blue2=(tmp_col[1]>>16)&0xff;
|
||||||
|
|
||||||
tmp1=((red1*5+red2*3)>>6)|
|
tmp1=((red1*5+red2*3)>>6)|
|
||||||
(((green1*5+green2*3)>>6)<<5)|
|
(((green1*5+green2*3)>>6)<<5)|
|
||||||
(((blue1*5+blue2*3)>>6)<<10);
|
(((blue1*5+blue2*3)>>6)<<10);
|
||||||
tmp2=((red2*5+red1*3)>>6)|
|
tmp2=((red2*5+red1*3)>>6)|
|
||||||
(((green2*5+green1*3)>>6)<<5)|
|
(((green2*5+green1*3)>>6)<<5)|
|
||||||
(((blue2*5+blue1*3)>>6)<<10);
|
(((blue2*5+blue1*3)>>6)<<10);
|
||||||
|
|
||||||
tmp_col[2]=RGB16TO32(tmp1,255);
|
tmp_col[2]=RGB15TO32(tmp1,255);
|
||||||
tmp_col[3]=RGB16TO32(tmp2,255);
|
tmp_col[3]=RGB15TO32(tmp2,255);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (sy = 0; sy < 4; sy++)
|
|
||||||
{
|
|
||||||
// Texture offset
|
|
||||||
u32 currentPos = (x<<2) + tmpPos[sy];
|
|
||||||
u8 currRow = (u8)((currBlock>>(sy<<3))&0xFF);
|
|
||||||
|
|
||||||
dwdst[currentPos] = tmp_col[currRow&3];
|
|
||||||
dwdst[currentPos+1] = tmp_col[(currRow>>2)&3];
|
|
||||||
dwdst[currentPos+2] = tmp_col[(currRow>>4)&3];
|
|
||||||
dwdst[currentPos+3] = tmp_col[(currRow>>6)&3];
|
|
||||||
|
|
||||||
if(dead) {
|
|
||||||
memset(dwdst, 0, sizeof(dwdst[0]) * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
txt_slot_current_size-=4;;
|
|
||||||
if (txt_slot_current_size<=0)
|
|
||||||
{
|
|
||||||
//dead = true;
|
|
||||||
txt_slot_current++;
|
|
||||||
map=(unsigned int*)ARM9Mem.textureSlotAddr[txt_slot_current];
|
|
||||||
map-=txt_slot_size>>2; //this is weird, but necessary since we use map[d] above
|
|
||||||
txt_slot_size=txt_slot_current_size=0x020000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set all 16 texels
|
||||||
|
for (int sy = 0; sy < 4; sy++)
|
||||||
|
{
|
||||||
|
// Texture offset
|
||||||
|
u32 currentPos = (x<<2) + tmpPos[sy];
|
||||||
|
u8 currRow = (u8)((currBlock>>(sy<<3))&0xFF);
|
||||||
|
|
||||||
|
dwdst[currentPos] = tmp_col[currRow&3];
|
||||||
|
dwdst[currentPos+1] = tmp_col[(currRow>>2)&3];
|
||||||
|
dwdst[currentPos+2] = tmp_col[(currRow>>4)&3];
|
||||||
|
dwdst[currentPos+3] = tmp_col[(currRow>>6)&3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6: //a5i3
|
case TEXMODE_A5I3:
|
||||||
{
|
{
|
||||||
for(x = 0; x < imageSize; x++)
|
for(int i=0;i<ms.numItems;i++) {
|
||||||
{
|
adr = ms.items[i].ptr;
|
||||||
u16 c = pal[*adr&0x07];
|
for(int x = 0; x < ms.items[i].len; ++x)
|
||||||
u8 alpha = (*adr>>3);
|
{
|
||||||
*dwdst++ = RGB15TO32(c,material_5bit_to_8bit[alpha]);
|
u16 c = pal[*adr&0x07];
|
||||||
adr++;
|
u8 alpha = (*adr>>3);
|
||||||
CHECKSLOT;
|
*dwdst++ = RGB15TO32(c,material_5bit_to_8bit[alpha]);
|
||||||
|
adr++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 7: //16bpp
|
case TEXMODE_16BPP:
|
||||||
{
|
{
|
||||||
unsigned short * map = ((unsigned short *)adr);
|
for(int i=0;i<ms.numItems;i++) {
|
||||||
|
u16* map = (u16*)ms.items[i].ptr;
|
||||||
for(x = 0; x < imageSize; ++x)
|
for(int x = 0; x < ms.items[i].len; ++x)
|
||||||
{
|
|
||||||
u16 c = map[x];
|
|
||||||
int alpha = ((c&0x8000)?255:0);
|
|
||||||
*dwdst++ = RGB15TO32(c&0x7FFF,alpha);
|
|
||||||
|
|
||||||
txt_slot_current_size-=2;;
|
|
||||||
if (txt_slot_current_size<=0)
|
|
||||||
{
|
{
|
||||||
txt_slot_current++;
|
u16 c = map[x];
|
||||||
map=(unsigned short *)ARM9Mem.textureSlotAddr[txt_slot_current];
|
int alpha = ((c&0x8000)?255:0);
|
||||||
map-=txt_slot_size>>1;
|
*dwdst++ = RGB15TO32(c&0x7FFF,alpha);
|
||||||
txt_slot_size=txt_slot_current_size=0x020000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -916,15 +1084,15 @@ static void setTexture(unsigned int format, unsigned int texpal)
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||||
texcache[i].sizeX, texcache[i].sizeY, 0,
|
texcache[i].sizeX, texcache[i].sizeY, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, texMAP);
|
GL_RGBA, GL_UNSIGNED_BYTE, texMAP);
|
||||||
|
|
||||||
DebugDumpTexture(i);
|
DebugDumpTexture(i);
|
||||||
|
|
||||||
//============================================================================================
|
//============================================================================================
|
||||||
|
|
||||||
texcache_count=i;
|
texcache_count=i;
|
||||||
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (BIT16(texcache[i].frm) ? (BIT18(texcache[i].frm)?GL_MIRRORED_REPEAT:GL_REPEAT) : GL_CLAMP));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (BIT16(texcache[i].frm) ? (BIT18(texcache[i].frm)?GL_MIRRORED_REPEAT:GL_REPEAT) : GL_CLAMP));
|
||||||
|
@ -1161,8 +1329,18 @@ static void OGLVramReconfigureSignal()
|
||||||
{
|
{
|
||||||
//well, this is a very blunt instrument.
|
//well, this is a very blunt instrument.
|
||||||
//lets just flag all the textures as invalid.
|
//lets just flag all the textures as invalid.
|
||||||
for(int i=0;i<MAX_TEXTURE+1;i++)
|
for(int i=0;i<MAX_TEXTURE+1;i++) {
|
||||||
texcache[i].suspectedInvalid = true;
|
texcache[i].suspectedInvalid = true;
|
||||||
|
|
||||||
|
//invalidate all 4x4 textures when texture palettes change mappings
|
||||||
|
//this is necessary because we arent tracking 4x4 texture palettes to look for changes.
|
||||||
|
//Although I concede this is a bit paranoid.. I think the odds of anyone changing 4x4 palette data
|
||||||
|
//without also changing the texture data is pretty much zero.
|
||||||
|
//
|
||||||
|
//TODO - move this to a separate signal: split into TexReconfigureSignal and TexPaletteReconfigureSignal
|
||||||
|
if(texcache[i].mode == TEXMODE_4X4)
|
||||||
|
texcache[i].frm = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GL_ReadFramebuffer()
|
static void GL_ReadFramebuffer()
|
||||||
|
|
|
@ -5768,9 +5768,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
|
|
||||||
//emu_halt();
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_M_IMM_OFF_POSTIND\n");
|
||||||
LOG("Untested opcode: OP_LDRBT_M_IMM_OFF_POSTIND\n");
|
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
adr = cpu->R[REG_POS(i,16)];
|
adr = cpu->R[REG_POS(i,16)];
|
||||||
|
@ -5794,9 +5792,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_REG_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_P_REG_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_P_REG_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
adr = cpu->R[REG_POS(i,16)];
|
adr = cpu->R[REG_POS(i,16)];
|
||||||
|
@ -5820,9 +5817,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_LSL_IMM_OFF_POSTIND()
|
||||||
if(cpu->CPSR.bits.mode==USR)
|
if(cpu->CPSR.bits.mode==USR)
|
||||||
return 2;
|
return 2;
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_P_LSL_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_P_LSL_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
LSL_IMM;
|
LSL_IMM;
|
||||||
|
@ -5848,9 +5844,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_LSL_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_M_LSL_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_M_LSL_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
LSL_IMM;
|
LSL_IMM;
|
||||||
|
@ -5876,9 +5871,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_LSR_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_P_LSR_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_P_LSR_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
LSR_IMM;
|
LSR_IMM;
|
||||||
|
@ -5904,9 +5898,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_LSR_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_M_LSR_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_M_LSR_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
LSR_IMM;
|
LSR_IMM;
|
||||||
|
@ -5932,8 +5925,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_ASR_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_P_ASR_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_P_ASR_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
|
@ -5960,8 +5953,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_ASR_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_M_ASR_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_M_ASR_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
|
@ -5988,8 +5981,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_ROR_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_P_ROR_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_P_ROR_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
|
@ -6016,8 +6009,8 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_ROR_IMM_OFF_POSTIND()
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDRBT_M_ROR_IMM_OFF_POSTIND\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDRBT_M_ROR_IMM_OFF_POSTIND\n");
|
||||||
|
|
||||||
|
|
||||||
i = cpu->instruction;
|
i = cpu->instruction;
|
||||||
|
@ -6751,8 +6744,8 @@ TEMPLATE static u32 FASTCALL OP_LDMIB2()
|
||||||
u32 start = cpu->R[REG_POS(i,16)];
|
u32 start = cpu->R[REG_POS(i,16)];
|
||||||
u32 * registres;
|
u32 * registres;
|
||||||
TWaitState* waitState;
|
TWaitState* waitState;
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDMIB2\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDMIB2\n");
|
||||||
|
|
||||||
if(BIT15(i)==0)
|
if(BIT15(i)==0)
|
||||||
{
|
{
|
||||||
|
@ -6810,8 +6803,8 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2()
|
||||||
TWaitState* waitState;
|
TWaitState* waitState;
|
||||||
|
|
||||||
u32 start = cpu->R[REG_POS(i,16)];
|
u32 start = cpu->R[REG_POS(i,16)];
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_LDMDA2\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_LDMDA2\n");
|
||||||
|
|
||||||
if(BIT15(i)==0)
|
if(BIT15(i)==0)
|
||||||
{
|
{
|
||||||
|
@ -7329,8 +7322,7 @@ TEMPLATE static u32 FASTCALL OP_STMIA2()
|
||||||
start = cpu->R[REG_POS(i,16)];
|
start = cpu->R[REG_POS(i,16)];
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
|
|
||||||
//emu_halt();
|
UNTESTEDOPCODELOG("Untested opcode: OP_STMIA2\n");
|
||||||
LOG("Untested opcode: OP_STMIA2\n");
|
|
||||||
|
|
||||||
for(b=0; b<16; ++b)
|
for(b=0; b<16; ++b)
|
||||||
{
|
{
|
||||||
|
@ -7360,8 +7352,7 @@ TEMPLATE static u32 FASTCALL OP_STMIB2()
|
||||||
start = cpu->R[REG_POS(i,16)];
|
start = cpu->R[REG_POS(i,16)];
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
|
|
||||||
//emu_halt();
|
UNTESTEDOPCODELOG("Untested opcode: OP_STMIB2\n");
|
||||||
LOG("Untested opcode: OP_STMIB2\n");
|
|
||||||
|
|
||||||
for(b=0; b<16; ++b)
|
for(b=0; b<16; ++b)
|
||||||
{
|
{
|
||||||
|
@ -7391,8 +7382,7 @@ TEMPLATE static u32 FASTCALL OP_STMDA2()
|
||||||
start = cpu->R[REG_POS(i,16)];
|
start = cpu->R[REG_POS(i,16)];
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
|
|
||||||
//emu_halt();
|
UNTESTEDOPCODELOG("Untested opcode: OP_STMDA2\n");
|
||||||
LOG("Untested opcode: OP_STMDA2\n");
|
|
||||||
|
|
||||||
for(b=0; b<16; ++b)
|
for(b=0; b<16; ++b)
|
||||||
{
|
{
|
||||||
|
@ -7450,8 +7440,7 @@ TEMPLATE static u32 FASTCALL OP_STMIA2_W()
|
||||||
start = cpu->R[REG_POS(i,16)];
|
start = cpu->R[REG_POS(i,16)];
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
|
|
||||||
//emu_halt();
|
UNTESTEDOPCODELOG("Untested opcode: OP_STMIA2_W\n");
|
||||||
LOG("Untested opcode: OP_STMIA2_W\n");
|
|
||||||
|
|
||||||
for(b=0; b<16; ++b)
|
for(b=0; b<16; ++b)
|
||||||
{
|
{
|
||||||
|
@ -7510,8 +7499,8 @@ TEMPLATE static u32 FASTCALL OP_STMDA2_W()
|
||||||
c = 0;
|
c = 0;
|
||||||
start = cpu->R[REG_POS(i,16)];
|
start = cpu->R[REG_POS(i,16)];
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
//emu_halt();
|
|
||||||
LOG("Untested opcode: OP_STMDA2_W\n");
|
UNTESTEDOPCODELOG("Untested opcode: OP_STMDA2_W\n");
|
||||||
|
|
||||||
for(b=0; b<16; ++b)
|
for(b=0; b<16; ++b)
|
||||||
{
|
{
|
||||||
|
@ -7544,8 +7533,7 @@ TEMPLATE static u32 FASTCALL OP_STMDB2_W()
|
||||||
start = cpu->R[REG_POS(i,16)];
|
start = cpu->R[REG_POS(i,16)];
|
||||||
oldmode = armcpu_switchMode(cpu, SYS);
|
oldmode = armcpu_switchMode(cpu, SYS);
|
||||||
|
|
||||||
//emu_halt();
|
UNTESTEDOPCODELOG("Untested opcode: OP_STMDB2_W\n");
|
||||||
LOG("Untested opcode: OP_STMDB2_W\n");
|
|
||||||
|
|
||||||
for(b=0; b<16; ++b)
|
for(b=0; b<16; ++b)
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
static void log(unsigned int channel, const char * file, unsigned int line, void (*callback)(const Logger& logger, const char * message));
|
static void log(unsigned int channel, const char * file, unsigned int line, void (*callback)(const Logger& logger, const char * message));
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUG) || defined(GPUDEBUG) || defined(DIVDEBUG) || defined(SQRTDEBUG) || defined(DMADEBUG)
|
#if defined(DEBUG) || defined(GPUDEBUG) || defined(DIVDEBUG) || defined(SQRTDEBUG) || defined(DMADEBUG) || defined(WANTPROGINFO)
|
||||||
#define LOGC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
#define LOGC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define LOGC(...)
|
#define LOGC(...)
|
||||||
|
@ -93,6 +93,20 @@ public:
|
||||||
#define CFLASHLOG(...)
|
#define CFLASHLOG(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef UNTESTEDOPCODELOG
|
||||||
|
#define UNTESTEDOPCODELOG(...) LOGC(6, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define UNTESTEDOPCODELOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WANTPROGINFO
|
||||||
|
#define PROGINFO(...) LOGC(7, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PROGINFO(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define INFOC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
#define INFOC(channel, ...) Logger::log(channel, __FILE__, __LINE__, __VA_ARGS__)
|
||||||
#define INFO(...) INFOC(10, __VA_ARGS__)
|
#define INFO(...) INFOC(10, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,15 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#define TEXMODE_NONE 0
|
||||||
|
#define TEXMODE_A3I5 1
|
||||||
|
#define TEXMODE_I2 2
|
||||||
|
#define TEXMODE_I4 3
|
||||||
|
#define TEXMODE_I8 4
|
||||||
|
#define TEXMODE_4X4 5
|
||||||
|
#define TEXMODE_A5I3 6
|
||||||
|
#define TEXMODE_16BPP 7
|
||||||
|
|
||||||
void gfx3d_init();
|
void gfx3d_init();
|
||||||
void gfx3d_reset();
|
void gfx3d_reset();
|
||||||
|
|
||||||
|
@ -129,9 +138,6 @@ extern GFX3D gfx3d;
|
||||||
|
|
||||||
//---------------------
|
//---------------------
|
||||||
|
|
||||||
//produce a 32bpp color from a DS RGB16
|
|
||||||
#define RGB16TO32(col,alpha) (((alpha)<<24) | ((((col) & 0x7C00)>>7)<<16) | ((((col) & 0x3E0)>>2)<<8) | (((col) & 0x1F)<<3))
|
|
||||||
|
|
||||||
//produce a 32bpp color from a ds RGB15 plus an 8bit alpha, using a table
|
//produce a 32bpp color from a ds RGB15 plus an 8bit alpha, using a table
|
||||||
#define RGB15TO32(col,alpha8) ( ((alpha8)<<24) | color_15bit_to_24bit[col&0x7FFF] )
|
#define RGB15TO32(col,alpha8) ( ((alpha8)<<24) | color_15bit_to_24bit[col&0x7FFF] )
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="shift_jis"?>
|
<?xml version="1.0" encoding="shift_jis"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="8,00"
|
Version="8.00"
|
||||||
Name="DeSmuME_VS2005"
|
Name="DeSmuME_VS2005"
|
||||||
ProjectGUID="{9F5F72A1-D3A5-4918-B460-E076B16D10A9}"
|
ProjectGUID="{9F5F72A1-D3A5-4918-B460-E076B16D10A9}"
|
||||||
RootNamespace="DeSmuME"
|
RootNamespace="DeSmuME"
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
EnableFiberSafeOptimizations="false"
|
EnableFiberSafeOptimizations="false"
|
||||||
WholeProgramOptimization="false"
|
WholeProgramOptimization="false"
|
||||||
AdditionalIncludeDirectories=".;..;.\zlib123;.\zziplib"
|
AdditionalIncludeDirectories=".;..;.\zlib123;.\zziplib"
|
||||||
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;BETA_VERSION;SPU_INTERPOLATE;HAVE_LIBZ;NOMINMAX"
|
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;BETA_VERSION;SPU_INTERPOLATE;HAVE_LIBZ;NOMINMAX;DEBUG;WANTPROGINFO"
|
||||||
ExceptionHandling="1"
|
ExceptionHandling="1"
|
||||||
BufferSecurityCheck="false"
|
BufferSecurityCheck="false"
|
||||||
EnableEnhancedInstructionSet="0"
|
EnableEnhancedInstructionSet="0"
|
||||||
|
|
Loading…
Reference in New Issue