private void PrepareWrite(GpuStateStruct *GpuState) { //Console.WriteLine("PrepareWrite"); try { var GlPixelFormat = GlPixelFormatList[(int)GpuState->DrawBufferState.Format]; int Width = (int)GpuState->DrawBufferState.Width; int Height = 272; int ScanWidth = PixelFormatDecoder.GetPixelsSize(GlPixelFormat.GuPixelFormat, Width); int PixelSize = PixelFormatDecoder.GetPixelsSize(GlPixelFormat.GuPixelFormat, 1); //GpuState->DrawBufferState.Format var Address = (void *)Memory.PspAddressToPointerSafe(GpuState->DrawBufferState.Address); //Console.WriteLine("{0}", GlPixelFormat.GuPixelFormat); //Console.WriteLine("{0:X}", GpuState->DrawBufferState.Address); GL.PixelStore(PixelStoreParameter.PackAlignment, PixelSize); GL.ReadPixels(0, 0, Width, Height, PixelFormat.Rgba, GlPixelFormat.OpenglPixelType, TempBuffer); fixed(void *_TempBufferPtr = &TempBuffer[0]) { var Input = (byte *)_TempBufferPtr; var Output = (byte *)Address; for (int Row = 0; Row < Height; Row++) { var ScanIn = (byte *)&Input[ScanWidth * Row]; var ScanOut = (byte *)&Output[ScanWidth * (Height - Row - 1)]; //Console.WriteLine("{0}:{1},{2},{3}", Row, PixelSize, Width, ScanWidth); PointerUtils.Memcpy(ScanOut, ScanIn, ScanWidth); } } } catch (Exception Exception) { Console.WriteLine(Exception); } }
private void GetTexVram(Action <TexturePair> Action) { if (TexVram == null) { TexVram = GLTexture.Create().SetFormat(TextureFormat.RGBA).SetSize(1, 1); } //Console.WriteLine(TexVram); TexVram.Bind(); if (BufferGraphics == null) { BufferGraphics = Graphics.FromImage(Buffer); //BufferGraphics.Clear(Color.Red); BufferGraphics.Clear(Color.Black); } //if (PspDisplayForm.Singleton.WindowState == FormWindowState.Minimized) //{ // return; //} // //if (!PspDisplayForm.Singleton.EnableRefreshing) //{ // return; //} if (IGuiWindowInfo.EnableRefreshing) { try { int Width = 512; int Height = 272; var FrameAddress = PspDisplay.CurrentInfo.FrameAddress; byte *FrameBuffer = null; byte *DepthBuffer = null; try { FrameBuffer = (byte *)Memory.PspAddressToPointerSafe( FrameAddress, PixelFormatDecoder.GetPixelsSize(PspDisplay.CurrentInfo.PixelFormat, Width * Height) ); } catch (Exception Exception) { Console.Error.WriteLine(Exception); } //Console.Error.WriteLine("FrameBuffer == 0x{0:X}!!", (long)FrameBuffer); if (FrameBuffer == null) { //Console.Error.WriteLine("FrameBuffer == null!!"); } //Console.WriteLine("{0:X}", Address); var Hash = PixelFormatDecoder.Hash( PspDisplay.CurrentInfo.PixelFormat, (void *)FrameBuffer, Width, Height ); if (Hash != LastHash) { LastHash = Hash; Buffer.LockBitsUnlock(System.Drawing.Imaging.PixelFormat.Format32bppArgb, (BitmapData) => { var Count = Width * Height; fixed(OutputPixel * BitmapDataDecodePtr = BitmapDataDecode) { var BitmapDataPtr = (BGRA *)BitmapData.Scan0.ToPointer(); //var LastRow = (FrameBuffer + 512 * 260 * 4 + 4 * 10); //Console.WriteLine("{0},{1},{2},{3}", LastRow[0], LastRow[1], LastRow[2], LastRow[3]); if (FrameBuffer == null) { if (OldFrameBuffer != null) { Console.Error.WriteLine("FrameBuffer == null"); } } else if (BitmapDataPtr == null) { Console.Error.WriteLine("BitmapDataPtr == null"); } else { PixelFormatDecoder.Decode( PspDisplay.CurrentInfo.PixelFormat, (void *)FrameBuffer, BitmapDataDecodePtr, Width, Height ); } // Converts the decoded data to Window's format. for (int n = 0; n < Count; n++) { BitmapDataPtr[n].R = BitmapDataDecodePtr[n].B; BitmapDataPtr[n].G = BitmapDataDecodePtr[n].G; BitmapDataPtr[n].B = BitmapDataDecodePtr[n].R; BitmapDataPtr[n].A = 0xFF; } OldFrameBuffer = FrameBuffer; GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, 512, 272, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, BitmapDataPtr); TextureVerticalFlip = true; } }); } //else { //Console.WriteLine("Display not updated!"); } } catch (Exception Exception) { Console.Error.WriteLine(Exception); } } Action(new TexturePair() { Color = TexVram, Depth = GLTexture.Wrap(0) }); return; }
public void AvcDecode(SceMpegAu *MpegAccessUnit, int FrameWidth, GuPixelFormats GuPixelFormat, PspPointer OutputBuffer) { if (MpegAccessUnit != null) { *MpegAccessUnit = GetAvcAu(StreamId.Avc); } while (MpegPsDemuxer.HasMorePackets) { if (!DecodePsPacket()) { return; } } if (VideoStream.Length <= 0) { return; } // Buffer 1MB //if (VideoStream.Length <= 1 * 1024 * 1024) return; try { //if (H264FrameDecoder.HasMorePackets) { //Console.WriteLine("VideoStream.Length: {0}", VideoStream.Length); var Frame = H264FrameDecoder.DecodeFrame(); ConsoleUtils.SaveRestoreConsoleColor(ConsoleColor.DarkGreen, () => { Console.WriteLine("DecodedFrame: {0}", FrameIndex); }); var Bitmap = FrameUtils.imageFromFrameWithoutEdges(Frame, FrameWidth, 272); var TempBuffer = new byte[PixelFormatDecoder.GetPixelsSize(GuPixelFormat, Bitmap.Width * Bitmap.Height)]; fixed(byte *TempBufferPtr = TempBuffer) { var TempBufferPtr2 = TempBufferPtr; Bitmap.LockBitsUnlock(PixelFormat.Format32bppArgb, (BitmapData) => { var InputBuffer = (OutputPixel *)BitmapData.Scan0.ToPointer(); int Count = Bitmap.Width * Bitmap.Height; for (int n = 0; n < Count; n++) { var Color = InputBuffer[n]; InputBuffer[n].R = Color.B; InputBuffer[n].G = Color.G; InputBuffer[n].B = Color.R; InputBuffer[n].A = 0xFF; } PixelFormatDecoder.Encode(GuPixelFormat, InputBuffer, TempBufferPtr2, Bitmap.Width * Bitmap.Height); PixelFormatDecoder.Encode(PspDisplay.CurrentInfo.PixelFormat, InputBuffer, (byte *)Memory.PspAddressToPointerSafe(PspDisplay.CurrentInfo.FrameAddress), 512, Bitmap.Width, Bitmap.Height); PspDisplay.CurrentInfo.PlayingVideo = true; }); PspDisplay.CurrentInfo.PlayingVideo = true; Memory.WriteBytes(OutputBuffer.Address, TempBufferPtr, TempBuffer.Length); GpuImpl.InvalidateCache(OutputBuffer.Address, TempBuffer.Length); } if (SaveBitmapFrame) { Bitmap.Save(@"c:\temp\frame" + (FrameIndex) + ".png"); } FrameIndex++; } //PixelFormat return; } catch (EndOfStreamException) { ConsoleUtils.SaveRestoreConsoleColor(ConsoleColor.Red, () => { Console.WriteLine("H264FrameDecoder.DecodeFrame: EndOfStreamException"); }); } }
public Texture Get(TextureStateStruct *TextureState, ClutStateStruct *ClutState) { Texture Texture; //GC.Collect(); bool Swizzled = TextureState->Swizzled; uint TextureAddress = TextureState->Mipmap0.Address; uint ClutAddress = ClutState->Address; var ClutFormat = ClutState->PixelFormat; var ClutStart = ClutState->Start; var ClutDataStart = PixelFormatDecoder.GetPixelsSize(ClutFormat, ClutStart); ulong Hash1 = TextureAddress | (ulong)((ClutAddress + ClutDataStart) << 32); bool Recheck = false; if (Cache.TryGetValue(Hash1, out Texture)) { if (Texture.RecheckTimestamp != RecheckTimestamp) { Recheck = true; } } else { Recheck = true; } if (Recheck) { //Console.Write("."); //Console.WriteLine("{0:X}", ClutAddress); var TexturePointer = (byte *)PspMemory.PspAddressToPointerSafe(TextureAddress); var ClutPointer = (byte *)PspMemory.PspAddressToPointerSafe(ClutAddress); var TextureFormat = TextureState->PixelFormat; //var Width = TextureState->Mipmap0.TextureWidth; int BufferWidth = TextureState->Mipmap0.BufferWidth; var Height = TextureState->Mipmap0.TextureHeight; var TextureDataSize = PixelFormatDecoder.GetPixelsSize(TextureFormat, BufferWidth * Height); if (ClutState->NumberOfColors > 256) { ClutState->NumberOfColors = 256; } var ClutDataSize = PixelFormatDecoder.GetPixelsSize(ClutFormat, ClutState->NumberOfColors); var ClutCount = ClutState->NumberOfColors; var ClutShift = ClutState->Shift; var ClutMask = ClutState->Mask; //Console.WriteLine(TextureFormat); if (TextureDataSize > 2048 * 2048 * 4) { Console.Error.WriteLine("UPDATE_TEXTURE(TEX={0},CLUT={1}:{2}:{3}:{4}:0x{5:X},SIZE={6}x{7},{8},Swizzled={9})", TextureFormat, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask, BufferWidth, Height, BufferWidth, Swizzled); Console.Error.WriteLine("Invalid TEXTURE!"); return(new Texture()); } TextureCacheKey TextureCacheKey = new TextureCacheKey() { TextureAddress = TextureAddress, TextureFormat = TextureFormat, TextureHash = FastHash((uint *)TexturePointer, TextureDataSize), ClutHash = FastHash((uint *)&(ClutPointer[ClutDataStart]), ClutDataSize), ClutAddress = ClutAddress, ClutFormat = ClutFormat, ClutStart = ClutStart, ClutShift = ClutShift, ClutMask = ClutMask, Swizzled = Swizzled, }; if (Texture == null || (!Texture.TextureCacheKey.Equals(TextureCacheKey))) { #if DEBUG_TEXTURE_CACHE string TextureName = "texture_" + TextureCacheKey.TextureHash + "_" + TextureCacheKey.ClutHash + "_" + TextureFormat + "_" + ClutFormat + "_" + BufferWidth + "x" + Height; Console.Error.WriteLine("UPDATE_TEXTURE(TEX={0},CLUT={1}:{2}:{3}:{4}:0x{5:X},SIZE={6}x{7},{8},Swizzled={9})", TextureFormat, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask, BufferWidth, Height, BufferWidth, Swizzled); #endif Texture = new Texture(); Texture.TextureCacheKey = TextureCacheKey; { fixed(PixelFormatDecoder.OutputPixel *TexturePixelsPointer = DecodedTextureBuffer) { if (Swizzled) { fixed(byte *SwizzlingBufferPointer = SwizzlingBuffer) { Marshal.Copy(new IntPtr(TexturePointer), SwizzlingBuffer, 0, TextureDataSize); PixelFormatDecoder.UnswizzleInline(TextureFormat, (void *)SwizzlingBufferPointer, BufferWidth, Height); PixelFormatDecoder.Decode( TextureFormat, (void *)SwizzlingBufferPointer, TexturePixelsPointer, BufferWidth, Height, ClutPointer, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask ); } } else { PixelFormatDecoder.Decode( TextureFormat, (void *)TexturePointer, TexturePixelsPointer, BufferWidth, Height, ClutPointer, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask ); } #if DEBUG_TEXTURE_CACHE var Bitmap = new Bitmap(BufferWidth, Height); BitmapUtils.TransferChannelsDataInterleaved( Bitmap.GetFullRectangle(), Bitmap, (byte *)TexturePixelsPointer, BitmapUtils.Direction.FromDataToBitmap, BitmapChannel.Red, BitmapChannel.Green, BitmapChannel.Blue, BitmapChannel.Alpha ); Bitmap.Save(TextureName + ".png"); #endif Texture.SetData(TexturePixelsPointer, BufferWidth, Height); } } if (Cache.ContainsKey(Hash1)) { Cache[Hash1].Dispose(); } Cache[Hash1] = Texture; } } Texture.RecheckTimestamp = RecheckTimestamp; return(Texture); }
public TTexture Get(GpuStateStruct GpuState) { var TextureMappingState = GpuState.TextureMappingState; var ClutState = TextureMappingState.ClutState; var TextureState = TextureMappingState.TextureState; TTexture Texture; //GC.Collect(); bool Swizzled = TextureState.Swizzled; uint TextureAddress = TextureState.Mipmap0.Address; uint ClutAddress = ClutState.Address; var ClutFormat = ClutState.PixelFormat; var ClutStart = ClutState.Start; var ClutDataStart = PixelFormatDecoder.GetPixelsSize(ClutFormat, ClutStart); ulong Hash1 = TextureAddress | (ulong)((ClutAddress + ClutDataStart) << 32); bool Recheck = false; if (Cache.TryGetValue(Hash1, out Texture)) { if (Texture.RecheckTimestamp != RecheckTimestamp) { Recheck = true; } } else { Recheck = true; } if (Recheck) { //Console.Write("."); //Console.WriteLine("{0:X}", ClutAddress); var TextureFormat = TextureState.PixelFormat; //var Width = TextureState->Mipmap0.TextureWidth; int BufferWidth = TextureState.Mipmap0.BufferWidth; // FAKE! //BufferWidth = TextureState->Mipmap0.TextureWidth; var Height = TextureState.Mipmap0.TextureHeight; var TextureDataSize = PixelFormatDecoder.GetPixelsSize(TextureFormat, BufferWidth * Height); if (ClutState.NumberOfColors > 256) { ClutState.NumberOfColors = 256; } var ClutDataSize = PixelFormatDecoder.GetPixelsSize(ClutFormat, ClutState.NumberOfColors); var ClutCount = ClutState.NumberOfColors; var ClutShift = ClutState.Shift; var ClutMask = ClutState.Mask; //Console.WriteLine(TextureFormat); // INVALID TEXTURE if (!PspMemory.IsRangeValid(TextureAddress, TextureDataSize) || TextureDataSize > 2048 * 2048 * 4) { Console.Error.WriteLineColored(ConsoleColor.DarkRed, "UPDATE_TEXTURE(TEX={0},CLUT={1}:{2}:{3}:{4}:0x{5:X},SIZE={6}x{7},{8},Swizzled={9})", TextureFormat, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask, BufferWidth, Height, BufferWidth, Swizzled); Console.Error.WriteLineColored(ConsoleColor.DarkRed, "Invalid TEXTURE! TextureAddress=0x{0:X}, TextureDataSize={1}", TextureAddress, TextureDataSize); if (InvalidTexture == null) { InvalidTexture = new TTexture(); InvalidTexture.Init(GpuImpl); int InvalidTextureWidth = 2, InvalidTextureHeight = 2; int InvalidTextureSize = InvalidTextureWidth * InvalidTextureHeight; var Data = new OutputPixel[InvalidTextureSize]; fixed(OutputPixel *DataPtr = Data) { var Color1 = OutputPixel.FromRgba(0xFF, 0x00, 0x00, 0xFF); var Color2 = OutputPixel.FromRgba(0x00, 0x00, 0xFF, 0xFF); for (int n = 0; n < InvalidTextureSize; n++) { DataPtr[n] = (n & 1) != 0 ? Color1 : Color2; } InvalidTexture.SetData(Data, InvalidTextureWidth, InvalidTextureHeight); } } return(InvalidTexture); } //Console.WriteLine("TextureAddress=0x{0:X}, TextureDataSize=0x{1:X}", TextureAddress, TextureDataSize); byte *TexturePointer = null; byte *ClutPointer = null; try { TexturePointer = (byte *)PspMemory.PspAddressToPointerSafe(TextureAddress); ClutPointer = (byte *)PspMemory.PspAddressToPointerSafe(ClutAddress); } catch (PspMemory.InvalidAddressException InvalidAddressException) { throw InvalidAddressException; } TextureCacheKey TextureCacheKey = new TextureCacheKey() { TextureAddress = TextureAddress, TextureFormat = TextureFormat, TextureHash = FastHash(TexturePointer, TextureDataSize), ClutHash = FastHash(&ClutPointer[ClutDataStart], ClutDataSize), ClutAddress = ClutAddress, ClutFormat = ClutFormat, ClutStart = ClutStart, ClutShift = ClutShift, ClutMask = ClutMask, Swizzled = Swizzled, ColorTestEnabled = GpuState.ColorTestState.Enabled, ColorTestRef = GpuState.ColorTestState.Ref, ColorTestMask = GpuState.ColorTestState.Mask, ColorTestFunction = GpuState.ColorTestState.Function, }; if (Texture == null || !Texture.TextureCacheKey.Equals(TextureCacheKey)) { string TextureName = "texture_" + TextureCacheKey.TextureHash + "_" + TextureCacheKey.ClutHash + "_" + TextureFormat + "_" + ClutFormat + "_" + BufferWidth + "x" + Height + "_" + Swizzled; #if DEBUG_TEXTURE_CACHE Console.Error.WriteLine("UPDATE_TEXTURE(TEX={0},CLUT={1}:{2}:{3}:{4}:0x{5:X},SIZE={6}x{7},{8},Swizzled={9})", TextureFormat, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask, BufferWidth, Height, BufferWidth, Swizzled); #endif Texture = new TTexture(); Texture.Init(GpuImpl); Texture.TextureCacheKey = TextureCacheKey; //Texture.Hash = Hash1; { //int TextureWidth = Math.Max(BufferWidth, Height); //int TextureHeight = Math.Max(BufferWidth, Height); int TextureWidth = BufferWidth; int TextureHeight = Height; int TextureWidthHeight = TextureWidth * TextureHeight; fixed(OutputPixel *TexturePixelsPointer = DecodedTextureBuffer) { if (Swizzled) { fixed(byte *SwizzlingBufferPointer = SwizzlingBuffer) { PointerUtils.Memcpy(SwizzlingBuffer, TexturePointer, TextureDataSize); PixelFormatDecoder.UnswizzleInline(TextureFormat, (void *)SwizzlingBufferPointer, BufferWidth, Height); PixelFormatDecoder.Decode( TextureFormat, (void *)SwizzlingBufferPointer, TexturePixelsPointer, BufferWidth, Height, ClutPointer, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask, strideWidth: PixelFormatDecoder.GetPixelsSize(TextureFormat, TextureWidth) ); } } else { PixelFormatDecoder.Decode( TextureFormat, (void *)TexturePointer, TexturePixelsPointer, BufferWidth, Height, ClutPointer, ClutFormat, ClutCount, ClutStart, ClutShift, ClutMask, strideWidth: PixelFormatDecoder.GetPixelsSize(TextureFormat, TextureWidth) ); } if (TextureCacheKey.ColorTestEnabled) { byte EqualValue, NotEqualValue; switch (TextureCacheKey.ColorTestFunction) { case ColorTestFunctionEnum.GuAlways: EqualValue = 0xFF; NotEqualValue = 0xFF; break; case ColorTestFunctionEnum.GuNever: EqualValue = 0x00; NotEqualValue = 0x00; break; case ColorTestFunctionEnum.GuEqual: EqualValue = 0xFF; NotEqualValue = 0x00; break; case ColorTestFunctionEnum.GuNotequal: EqualValue = 0x00; NotEqualValue = 0xFF; break; default: throw new NotImplementedException(); } ConsoleUtils.SaveRestoreConsoleState(() => { Console.BackgroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Yellow; Console.Error.WriteLine("{0} : {1}, {2} : ref:{3} : mask:{4}", TextureCacheKey.ColorTestFunction, EqualValue, NotEqualValue, TextureCacheKey.ColorTestRef, TextureCacheKey.ColorTestMask); }); for (int n = 0; n < TextureWidthHeight; n++) { if ((TexturePixelsPointer[n] & TextureCacheKey.ColorTestMask).Equals( TextureCacheKey.ColorTestRef & TextureCacheKey.ColorTestMask)) { TexturePixelsPointer[n].A = EqualValue; } else { TexturePixelsPointer[n].A = NotEqualValue; } if (TexturePixelsPointer[n].A == 0) { //Console.Write("yup!"); } } } var TextureInfo = new TextureHookInfo() { TextureCacheKey = TextureCacheKey, Data = DecodedTextureBuffer, Width = TextureWidth, Height = TextureHeight }; MessageBus.Dispatch(TextureInfo); var Result = Texture.SetData(TextureInfo.Data, TextureInfo.Width, TextureInfo.Height); } } if (Cache.ContainsKey(Hash1)) { Cache[Hash1].Dispose(); } Cache[Hash1] = Texture; } } Texture.RecheckTimestamp = RecheckTimestamp; return(Texture); }