public void Load(uint address, uint mode, uint paletteCount) { // Format: // 00 16-bit BGR 5650 // 01 16-bit ABGR 5551 // 10 16-bit ABGR 4444 // 11 32-bit ABGR 8888 _format = mode & 0x3; _shift = ( int )((mode >> 2) & 0x1F); _mask = (mode >> 8) & 0xFF; _start = ((mode >> 16) & 0x1F) * 16; // ?? this.Pointer = address; if (address == 0x0) { return; } byte *tablePointer = _driver.MemorySystem.Translate(address); fixed(byte *p = &_table[0]) { switch (_format) { case 0: this.Checksum = ColorOperations.DecodeBGR5650(tablePointer, p, paletteCount * 16); break; case 1: this.Checksum = ColorOperations.DecodeABGR5551(tablePointer, p, paletteCount * 16); break; case 2: this.Checksum = ColorOperations.DecodeABGR4444(tablePointer, p, paletteCount * 16); break; case 3: this.Checksum = ColorOperations.DecodeABGR8888(tablePointer, p, paletteCount * 8); break; } // Checksum so that we can tell if it changed //uint* cp = ( uint* )tablePointer; //uint checksum = 0; //for( int n = 0; n < ( entryCount * entryWidth ); n++ ) // checksum += *( cp++ ); //if( this.Checksum != checksum ) //{ // Checksums don't match! Invalidate all CLUT textures! /*LLEntry<TextureEntry*>* e = context->TextureCache->GetEnumerator(); * while( e != NULL ) * { * LLEntry<TextureEntry*>* next = e->Next; * if( ( e->Value->PixelStorage & 0x4 ) == 0x4 ) * { * // Check to see if it was from this clut * if( e->Value->ClutPointer == context->ClutPointer ) * { * // Kill it! * GLuint freeIds[] = { e->Value->TextureID }; * glDeleteTextures( 1, freeIds ); * context->TextureCache->Remove( ( uint )e->Value->Address ); * } * } * e = next; * }*/ //context->TextureCache->Clear(); //} //this.Checksum = checksum; } }
public static MGLTexture LoadTexture(MGLDriver driver, MGLContext ctx, MGLTextureInfo info, uint checksum) { uint width = info.Width; uint lineWidth = info.LineWidth; uint height = info.Height; MGLTexture texture = new MGLTexture(); texture.PixelStorage = info.PixelStorage; texture.Address = info.Address; texture.LineWidth = lineWidth; texture.Width = width; texture.Height = height; texture.Checksum = checksum; texture.ClutPointer = ctx.Clut.Pointer; texture.ClutChecksum = ctx.Clut.Checksum; int textureId; Gl.glGenTextures(1, out textureId); Gl.glBindTexture(Gl.GL_TEXTURE_2D, textureId); texture.TextureID = textureId; byte * address = driver.MemorySystem.Translate(info.Address); TextureFormat format = TextureFormats[( int )info.PixelStorage]; uint size = lineWidth * height * format.Size; fixed(byte *unswizzleBuffer = &_unswizzleBuffer[0]) fixed(byte *decodeBuffer = &_decodeBuffer[0]) { bool needRowLength = false; byte *buffer = address; if (ctx.TexturesSwizzled == true) { buffer = Unswizzle(format, buffer, unswizzleBuffer, lineWidth, height); } switch (texture.PixelStorage) { case TexturePixelStorage.BGR5650: texture.Checksum = ColorOperations.DecodeBGR5650(buffer, decodeBuffer, lineWidth * height); buffer = decodeBuffer; break; case TexturePixelStorage.ABGR5551: texture.Checksum = ColorOperations.DecodeABGR5551(buffer, decodeBuffer, lineWidth * height); buffer = decodeBuffer; break; case TexturePixelStorage.ABGR4444: texture.Checksum = ColorOperations.DecodeABGR4444(buffer, decodeBuffer, lineWidth * height); buffer = decodeBuffer; break; case TexturePixelStorage.ABGR8888: // Pass through needRowLength = true; break; case TexturePixelStorage.Indexed4: ctx.Clut.Decode4(buffer, decodeBuffer, width, height, lineWidth); buffer = decodeBuffer; break; case TexturePixelStorage.Indexed8: ctx.Clut.Decode8(buffer, decodeBuffer, width, height, lineWidth); buffer = decodeBuffer; break; case TexturePixelStorage.Indexed16: ctx.Clut.Decode16(buffer, decodeBuffer, width, height, lineWidth); buffer = decodeBuffer; break; case TexturePixelStorage.Indexed32: ctx.Clut.Decode32(buffer, decodeBuffer, width, height, lineWidth); buffer = decodeBuffer; break; case TexturePixelStorage.DXT1: case TexturePixelStorage.DXT3: case TexturePixelStorage.DXT5: // Not yet implemented Debug.Assert(false); break; } // TODO: eliminate these //Gl.glPixelStorei( Gl.GL_UNPACK_ALIGNMENT, 4 ); //if( needRowLength == true ) // Gl.glPixelStorei( Gl.GL_UNPACK_ROW_LENGTH, ( int )lineWidth ); //else // Gl.glPixelStorei( Gl.GL_UNPACK_ROW_LENGTH, ( int )width ); Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, ( int )width, ( int )height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, ( IntPtr )buffer); // Set cookie //texture.CookieOriginal = *( ( uint* )address ); //texture.Cookie = ( uint )textureId; //*( ( uint* )address ) = ( uint )textureId; // Calculate checksum if needed if (texture.Checksum == 0) { texture.Checksum = MGLTexture.CalculateChecksum(address, width, height, texture.PixelStorage); } } return(texture); }